* SpecialPageFactory::setGroup was removed (deprecated in 1.21).
* SpecialPageFactory::getGroup was removed (deprecated in 1.21).
* DatabaseBase::ignoreErrors() is now protected.
+* BREAKING CHANGE: mediawiki.legacy.ajax has been removed, following
+ a lengthy deprecation period.
== Compatibility ==
'CurlHttpRequest' => __DIR__ . '/includes/HttpFunctions.php',
'DBAccessBase' => __DIR__ . '/includes/dao/DBAccessBase.php',
'DBAccessError' => __DIR__ . '/includes/db/LBFactory.php',
+ 'DBAccessObjectUtils' => __DIR__ . '/includes/dao/DBAccessObjectUtils.php',
'DBConnRef' => __DIR__ . '/includes/db/DBConnRef.php',
'DBConnectionError' => __DIR__ . '/includes/db/DatabaseError.php',
'DBError' => __DIR__ . '/includes/db/DatabaseError.php',
'SQLiteField' => __DIR__ . '/includes/db/DatabaseSqlite.php',
'SVGMetadataExtractor' => __DIR__ . '/includes/media/SVGMetadataExtractor.php',
'SVGReader' => __DIR__ . '/includes/media/SVGMetadataExtractor.php',
+ 'SamplingStatsdClient' => __DIR__ . '/includes/libs/SamplingStatsdClient.php',
'Sanitizer' => __DIR__ . '/includes/Sanitizer.php',
'SavepointPostgres' => __DIR__ . '/includes/db/DatabasePostgres.php',
'ScopedCallback' => __DIR__ . '/includes/libs/ScopedCallback.php',
"bottom",
"top"
]
+ },
+ "templates": {
+ "type": "object",
+ "description": "Templates to be loaded for client-side usage"
}
}
}
$statsdHost = $statsdServer[0];
$statsdPort = isset( $statsdServer[1] ) ? $statsdServer[1] : 8125;
$statsdSender = new SocketSender( $statsdHost, $statsdPort );
- $statsdClient = new StatsdClient( $statsdSender, true, false );
+ $statsdClient = new SamplingStatsdClient( $statsdSender, true, false );
$statsdClient->send( $context->getStats()->getBuffer() );
} catch ( Exception $ex ) {
MWExceptionHandler::logException( $ex );
}
/**
- * Generate a table of contents from a section tree
- * Currently unused.
+ * Generate a table of contents from a section tree.
*
* @param array $tree Return value of ParserOutput::getSections()
* @param string|Language|bool $lang Language for the toc title, defaults to user language
}
$ret .= $this->buildCssLinks() . "\n";
-
$ret .= $this->getHeadScripts() . "\n";
foreach ( $this->mHeadItems as $item ) {
}
/**
- * @todo Document
+ * Construct neccecary html and loader preset states to load modules on a page.
+ *
+ * Use getHtmlFromLoaderLinks() to convert this array to HTML.
+ *
* @param array|string $modules One or more module names
* @param string $only ResourceLoaderModule TYPE_ class constant
- * @param array $extraQuery Array with extra query parameters to add to each
- * request. array( param => value ).
- * @param bool $loadCall If true, output an (asynchronous) mw.loader.load()
- * call rather than a "<script src='...'>" tag.
- * @return string The html "<script>", "<link>" and "<style>" tags
- */
- public function makeResourceLoaderLink( $modules, $only, array $extraQuery = array(),
- $loadCall = false
- ) {
+ * @param array $extraQuery [optional] Array with extra query parameters for the request
+ * @return array A list of HTML strings and array of client loader preset states
+ */
+ public function makeResourceLoaderLink( $modules, $only, array $extraQuery = array() ) {
$modules = (array)$modules;
$links = array(
if ( ResourceLoader::inDebugMode() ) {
// Recursively call us for every item
foreach ( $modules as $name ) {
- $link = $this->makeResourceLoaderLink( $name, $only );
+ $link = $this->makeResourceLoaderLink( $name, $only, $extraQuery );
$links['html'] = array_merge( $links['html'], $link['html'] );
$links['states'] += $link['states'];
}
// Automatically select style/script elements
if ( $only === ResourceLoaderModule::TYPE_STYLES ) {
$link = Html::linkedStyle( $url );
- } elseif ( $loadCall ) {
- $link = ResourceLoader::makeInlineScript(
- Xml::encodeJsCall( 'mw.loader.load', array( $url, 'text/javascript', true ) )
- );
} else {
- $link = Html::linkedScript( $url );
- if ( !$context->getRaw() && !$isRaw ) {
- // Wrap only=script / only=combined requests in a conditional as
- // browsers not supported by the startup module would unconditionally
- // execute this module. Otherwise users will get "ReferenceError: mw is
- // undefined" or "jQuery is undefined" from e.g. a "site" module.
+ if ( $context->getRaw() || $isRaw ) {
+ // Startup module can't load itself, needs to use <script> instead of mw.loader.load
+ $link = Html::element( 'script', array(
+ // In SpecialJavaScriptTest, QUnit must load synchronous
+ 'async' => !isset( $extraQuery['sync'] ),
+ 'src' => $url
+ ) );
+ } else {
$link = ResourceLoader::makeInlineScript(
- Xml::encodeJsCall( 'document.write', array( $link ) )
+ Xml::encodeJsCall( 'mw.loader.load', array( $url ) )
);
}
-
- // For modules requested directly in the html via <link> or <script>,
- // tell mw.loader they are being loading to prevent duplicate requests.
- foreach ( $grpModules as $key => $module ) {
- // Don't output state=loading for the startup module..
- if ( $key !== 'startup' ) {
- $links['states'][$key] = 'loading';
- }
- }
}
if ( $group == 'noscript' ) {
* @return string HTML fragment
*/
function getHeadScripts() {
- // Startup - this will immediately load jquery and mediawiki modules
$links = array();
+
+ // Client profile classes for <html>. Allows for easy hiding/showing of UI components.
+ // Must be done synchronously on every page to avoid flashes of wrong content.
+ // Note: This class distinguishes MediaWiki-supported JavaScript from the rest.
+ // The "rest" includes browsers that support JavaScript but not supported by our runtime.
+ // For the performance benefit of the majority, this is added unconditionally here and is
+ // then fixed up by the startup module for unsupported browsers.
+ $links[] = Html::inlineScript(
+ 'document.documentElement.className = document.documentElement.className'
+ . '.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );'
+ );
+
+ // Startup - this provides the client with the module manifest and loads jquery and mediawiki base modules
$links[] = $this->makeResourceLoaderLink( 'startup', ResourceLoaderModule::TYPE_SCRIPTS );
// Load config before anything else
);
if ( $this->getConfig()->get( 'ResourceLoaderExperimentalAsyncLoading' ) ) {
- $links[] = $this->getScriptsForBottomQueue( true );
+ $links[] = $this->getScriptsForBottomQueue();
}
return self::getHtmlFromLoaderLinks( $links );
* 'bottom', legacy scripts ($this->mScripts), user preferences, site JS
* and user JS.
*
- * @param bool $inHead If true, this HTML goes into the "<head>",
- * if false it goes into the "<body>".
+ * @param bool $unused Previously used to let this method change its output based
+ * on whether it was called by getHeadScripts() or getBottomScripts().
* @return string
*/
- function getScriptsForBottomQueue( $inHead ) {
+ function getScriptsForBottomQueue( $unused = null ) {
// Scripts "only" requests marked for bottom inclusion
// If we're in the <head>, use load() calls rather than <script src="..."> tags
$links = array();
$links[] = $this->makeResourceLoaderLink( $this->getModuleScripts( true, 'bottom' ),
- ResourceLoaderModule::TYPE_SCRIPTS, /* $extraQuery = */ array(),
- /* $loadCall = */ $inHead
+ ResourceLoaderModule::TYPE_SCRIPTS
);
$links[] = $this->makeResourceLoaderLink( $this->getModuleStyles( true, 'bottom' ),
- ResourceLoaderModule::TYPE_STYLES, /* $extraQuery = */ array(),
- /* $loadCall = */ $inHead
+ ResourceLoaderModule::TYPE_STYLES
);
// Modules requests - let the client calculate dependencies and batch requests as it likes
$modules = $this->getModules( true, 'bottom' );
if ( $modules ) {
$links[] = ResourceLoader::makeInlineScript(
- Xml::encodeJsCall( 'mw.loader.load', array( $modules, null, true ) )
+ Xml::encodeJsCall( 'mw.loader.load', array( $modules ) )
);
}
// We're on a preview of a JS subpage. Exclude this page from the user module (T28283)
// and include the draft contents as a raw script instead.
$links[] = $this->makeResourceLoaderLink( 'user', ResourceLoaderModule::TYPE_COMBINED,
- array( 'excludepage' => $this->getTitle()->getPrefixedDBkey() ), $inHead
+ array( 'excludepage' => $this->getTitle()->getPrefixedDBkey() )
);
// Load the previewed JS
$links[] = ResourceLoader::makeInlineScript(
// the excluded subpage.
} else {
// Include the user module normally, i.e., raw to avoid it being wrapped in a closure.
- $links[] = $this->makeResourceLoaderLink( 'user', ResourceLoaderModule::TYPE_COMBINED,
- /* $extraQuery = */ array(), /* $loadCall = */ $inHead
- );
+ $links[] = $this->makeResourceLoaderLink( 'user', ResourceLoaderModule::TYPE_COMBINED );
}
// Group JS is only enabled if site JS is enabled.
- $links[] = $this->makeResourceLoaderLink( 'user.groups', ResourceLoaderModule::TYPE_COMBINED,
- /* $extraQuery = */ array(), /* $loadCall = */ $inHead
- );
+ $links[] = $this->makeResourceLoaderLink( 'user.groups', ResourceLoaderModule::TYPE_COMBINED );
return self::getHtmlFromLoaderLinks( $links );
}
// In case the skin wants to add bottom CSS
$this->getSkin()->setupSkinUserCss( $this );
- // Optimise jQuery ready event cross-browser.
- // This also enforces $.isReady to be true at </body> which fixes the
- // mw.loader bug in Firefox with using document.write between </body>
- // and the DOMContentReady event (bug 47457).
- $html = Html::inlineScript( 'if(window.jQuery)jQuery.ready();' );
-
- if ( !$this->getConfig()->get( 'ResourceLoaderExperimentalAsyncLoading' ) ) {
- $html .= $this->getScriptsForBottomQueue( false );
+ if ( $this->getConfig()->get( 'ResourceLoaderExperimentalAsyncLoading' ) ) {
+ // Already handled by getHeadScripts()
+ return '';
}
-
- return $html;
+ return $this->getScriptsForBottomQueue();
}
/**
# Double-quoted
return $set[3];
} elseif ( !isset( $set[2] ) ) {
- # In XHTML, attributes must have a value.
- # For 'reduced' form, return explicitly the attribute name here.
- return $set[1];
+ # In XHTML, attributes must have a value so return an empty string.
+ # See "Empty attribute syntax",
+ # http://www.w3.org/TR/html5/syntax.html#syntax-attribute-name
+ return "";
} else {
throw new MWException( "Tag conditions not met. This should never happen and is a bug." );
}
* If the code is invalid or has expired, returns NULL.
*
* @param string $code Confirmation code
+ * @param int $flags User::READ_* bitfield
* @return User|null
*/
- public static function newFromConfirmationCode( $code ) {
- $dbr = wfGetDB( DB_SLAVE );
- $id = $dbr->selectField( 'user', 'user_id', array(
- 'user_email_token' => md5( $code ),
- 'user_email_token_expires > ' . $dbr->addQuotes( $dbr->timestamp() ),
- ) );
- if ( $id !== false ) {
- return User::newFromId( $id );
- } else {
- return null;
- }
+ public static function newFromConfirmationCode( $code, $flags = 0 ) {
+ $db = ( $flags & self::READ_LATEST ) == self::READ_LATEST
+ ? wfGetDB( DB_MASTER )
+ : wfGetDB( DB_SLAVE );
+
+ $id = $db->selectField(
+ 'user',
+ 'user_id',
+ array(
+ 'user_email_token' => md5( $code ),
+ 'user_email_token_expires > ' . $db->addQuotes( $db->timestamp() ),
+ )
+ );
+
+ return $id ? User::newFromId( $id ) : null;
}
/**
"apihelp-query+search-example-generator": "Отримати інформацію про сторінки, на яких знайдено <kbd>meaning</kbd>.",
"apihelp-query+siteinfo-description": "Видати загальну інформацію про сайт.",
"apihelp-query+siteinfo-param-prop": "Яку інформацію отримати:\n;general:Загальна системна інформація.\n;namespaces:Список зареєстрованих просторів назв та їхні канонічні назви.\n;namespacealiases:Список зареєстрованих синонімів просторів назв.\n;specialpagealiases:Список аліасів спеціальної сторінки.\n;magicwords:Список магічних слів та їх аліасів.\n;statistics:Видає статистику сайту.\n;interwikimap:Видає карту інтервікі (за бажанням, фільтровану, за бажанням локалізовану з використанням <var>$1inlanguagecode</var>).\n;dbrepllag:Видає сервер бази даних з найбільшою затримкою відповіді.\n;usergroups:Видає групи користувачів і пов'язані дозволи.\n;libraries:Видає бібліотеки, встановлені у вікі.\n;extensions:Видає розширення, встановлені у вікі.\n;fileextensions:Видає список розширень файлів, які дозволено завантажувати.\n;rightsinfo:Видає інформацію щодо прав (ліцензії) вікі, якщо наявна.\n;restrictions:Видає інформацію про наявні типи обмежень (захисту).\n;languages:Видає список мов, які підтримує MediaWiki (за бажанням локалізовані через <var>$1inlanguagecode</var>).\n;skins:Видє список усіх доступних тем оформлення (опціонально локалізовані з використанням <var>$1inlanguagecode</var>, в іншому разі — мовою вмісту).\n;extensiontags:Видає список теґів розширення парсеру.\n;functionhooks:Видає список of parser function hooks.\n;showhooks:Returns a list of all subscribed hooks (contents of <var>[[mw:Manual:$wgHooks|$wgHooks]]</var>).\n;variables:Returns a list of variable IDs.\n;protocols:Returns a list of protocols that are allowed in external links.\n;defaultoptions:Returns the default values for user preferences.",
+ "apihelp-query+siteinfo-param-filteriw": "Видати лише локальні або лише нелокальні елементи карти інтервікі.",
+ "apihelp-query+siteinfo-param-showalldb": "Перелічити усі сервери баз даних, а не лише той, який робить найбільшу затримку.",
+ "apihelp-query+siteinfo-param-numberingroup": "Перераховує кількість користувачів у групах користувачів.",
+ "apihelp-query+siteinfo-param-inlanguagecode": "Код мови для локалізованих назв мов (найкращий варіант) і назв тем оформлення.",
+ "apihelp-query+siteinfo-example-simple": "Вибрати інформацію про сайт.",
+ "apihelp-query+siteinfo-example-interwiki": "Отримати список локальних інтервікі-префіксів.",
+ "apihelp-query+siteinfo-example-replag": "Перевірити поточне відставання реплікації.",
+ "apihelp-query+stashimageinfo-description": "Видає інформацію про приховані файли.",
+ "apihelp-query+stashimageinfo-param-filekey": "Ключ, який ідентифікує попереднє завантаження, що було тимчасово приховане.",
+ "apihelp-query+stashimageinfo-param-sessionkey": "Аліас для $1filekey, для зворотної сумісності.",
+ "apihelp-query+stashimageinfo-example-simple": "Видає інформацію про прихований файл.",
+ "apihelp-query+stashimageinfo-example-params": "Видає мініатюри для двох прихованих файлів.",
+ "apihelp-query+tags-description": "Перелічити мітки змін.",
+ "apihelp-query+tags-param-limit": "Максимальна кількість міток у списку.",
+ "apihelp-query+tags-param-prop": "Які властивості отримати:\n;name:Додає назву мітки.\n;displayname:Додає системне повідомлення для мітки.\n;description:Додає опис мітки.\n;hitcount:Додає кількість версій та записів журналу, які мають цю мітку.\n;defined:Показує, чи мітка визначена.\n;source:Отримує джерела мітки, що може включати <samp>extension</samp> для визначених розширеннями міток і <samp>manual</samp> для міток, які користувачі можуть застосовувати вручну.\n;active:Чи мітка ще застосовується.",
+ "apihelp-query+tags-example-simple": "Перелічити доступні мітки.",
+ "apihelp-query+templates-description": "Видає усі сторінки, які включені на вказаних сторінках.",
+ "apihelp-query+templates-param-namespace": "Показати шаблони лише у цьому просторі назв.",
+ "apihelp-query+templates-param-limit": "Скільки шаблонів виводити.",
+ "apihelp-query+templates-param-templates": "Перерахувати лише ці шаблони. Корисно для перевірки, чи певна сторінка використовує певний шаблон.",
+ "apihelp-query+templates-param-dir": "Напрямок, у якому перелічити.",
+ "apihelp-query+templates-example-simple": "Отримати шаблони, використані на сторінці <kbd>Main Page</kbd>.",
+ "apihelp-query+templates-example-generator": "Отримати інформацію про сторінки шаблонів, використаних на сторінці <kbd>Main Page</kbd>.",
+ "apihelp-query+templates-example-namespaces": "Отримати сторінки у просторах назв {{ns:user}} і {{ns:template}}, які включені на сторінці <kbd>Main Page</kbd>.",
+ "apihelp-query+tokens-description": "Отримує токени для дій, що змінюють дані.",
+ "apihelp-query+tokens-param-type": "Типи токена для запиту.",
+ "apihelp-query+tokens-example-simple": "Отримати csrf-токен (за замовчуванням).",
+ "apihelp-query+tokens-example-types": "Отримати токен спостереження і токен патрулювання.",
+ "apihelp-query+transcludedin-description": "Знайти усі сторінки, що включають подані сторінки.",
+ "apihelp-query+transcludedin-param-prop": "Які властивості отримати:\n;pageid:ID кожної сторінки.\n;title:Назва кожної сторінки.\n;redirect:Помітка, якщо сторінка є перенаправленням.",
+ "apihelp-query+transcludedin-param-namespace": "Включати сторінки лише в цих просторах назв.",
+ "apihelp-query+transcludedin-param-limit": "Скільки результатів виводити.",
+ "apihelp-query+transcludedin-param-show": "Показати лише елементи, що відповідають цим критеріям:\n;redirect:Показати лише перенаправлення.\n;!redirect:Показати лише не перенаправлення.",
+ "apihelp-query+transcludedin-example-simple": "Отримати список сторінок, що включають <kbd>Main Page</kbd>.",
+ "apihelp-query+transcludedin-example-generator": "Отримати інформацію про сторінки, які включають <kbd>Main Page</kbd>.",
+ "apihelp-query+usercontribs-description": "Отримати всі редагування користувача.",
+ "apihelp-query+usercontribs-param-limit": "Максимальна кількість елементів внеску для виведення.",
+ "apihelp-query+usercontribs-param-start": "З якої часової мітки виводити.",
+ "apihelp-query+usercontribs-param-end": "До якої часової мітки виводити.",
+ "apihelp-query+usercontribs-param-user": "Користувачі, для яких отримати внесок.",
+ "apihelp-query+usercontribs-param-userprefix": "Отримати внесок усіх користувачів, чиї імена починаються цим значенням. Перевизначає $1user.",
+ "apihelp-query+usercontribs-param-namespace": "Перерахувати записи внеску лише в цих просторах назв.",
+ "apihelp-query+usercontribs-param-prop": "Включити додаткові відомомсті:\n;ids:Додає ID сторінки й ID версії.\n;title:Додає назву й ID простору назв сторінки.\n;timestamp:Додає часову мітку редагування.\n;comment:Додає коментар редагування.\n;parsedcomment:Додає проаналізований коментар редагування.\n;size:Додає новий розмір редагування.\n;sizediff:Додає зміну розміру порівняно з попереднім редагуванням.\n;flags:Додає прапорці редагування.\n;patrolled:Відзначає патрульовані редагування.\n;tags:Перелічує мітки редагування.",
+ "apihelp-query+usercontribs-param-show": "Показати лише елементи, що відповідають цим критеріям, наприклад, лише не незначні редагування: <kbd>$2show=!minor</kbd>.\n\nЯкщо вказано <kbd>$2show=patrolled</kbd> або <kbd>$2show=!patrolled</kbd>, версії, старіші ніж <var>[[mw:Manual:$wgRCMaxAge|$wgRCMaxAge]]</var> ($1 {{PLURAL:$1|секунда|секунди|секунд}}) не будуть показуватися.",
+ "apihelp-query+usercontribs-param-tag": "Перерахувати лише версії, помічені цим теґом.",
+ "apihelp-query+usercontribs-param-toponly": "Виводити лише зміни, які є останньою версією.",
+ "apihelp-query+usercontribs-example-user": "Показати внесок користувача <kbd>Example</kbd>.",
+ "apihelp-query+usercontribs-example-ipprefix": "Показати внесок з усіх IP-адрес з префіксом <kbd>192.0.2.</kbd>.",
+ "apihelp-query+userinfo-description": "Отримати інформацію про поточного користувача.",
+ "apihelp-query+users-description": "Отримати інформацію про список користувачів.",
+ "apihelp-query+users-param-prop": "Яку інформацію включити:\n;blockinfo:Мітки про те чи є користувач заблокованим, ким, і з якою причиною.\n;groups:Перелічує всі групи, до яких належить кожен з користувачів.\n;implicitgroups:Перелічує всі групи, членом яких користувач є автоматично.\n;rights:Перелічує всі права, які має кожен з користувачів.\n;editcount:Додає лічильник редагувань користувача.\n;registration:Додає часову мітку реєстрації користувача.\n;emailable:Помічає чи хоче користувач отримувати електронну пошту через [[Special:Emailuser]].\n;gender:Помічає стать користувача. Повертає \"male\", \"female\", або \"unknown\".",
+ "apihelp-revisiondelete-description": "Вилучити або відновити версії.",
+ "apihelp-revisiondelete-param-type": "Тип здійснюваного вилучення версії.",
+ "apihelp-revisiondelete-param-target": "Назва сторінки, версію якої вилучити, якщо вимагається для цього типу.",
+ "apihelp-revisiondelete-param-ids": "Ідентифікатори версій, які слід вилучити.",
+ "apihelp-revisiondelete-param-hide": "Що приховати у кожній з версій.",
+ "apihelp-revisiondelete-param-show": "Що показати у кожній з версії.",
+ "apihelp-revisiondelete-param-suppress": "Чи приховати дані від адміністраторів так само як від усіх інших.",
+ "apihelp-revisiondelete-param-reason": "Причина вилучення або відновлення.",
+ "apihelp-revisiondelete-example-revision": "Приховати вміст версії <kbd>12345</kbd> сторінки <kbd>Main Page</kbd>.",
+ "apihelp-revisiondelete-example-log": "Приховати всі дані у записі журналу <kbd>67890</kbd> з причиною <kbd>BLP violation</kbd>.",
+ "apihelp-rollback-description": "Скасувати останнє редагування цієї сторінки.\n\nЯкщо користувач, який редагував сторінку, зробив декілька редагувань підряд, їх усі буде відкочено.",
+ "apihelp-rollback-param-title": "Назва сторінки, у якій здійснити відкіт. Не може використовуватись разом з <var>$1pageid</var>.",
+ "apihelp-rollback-param-pageid": "Ідентифікатор сторінки у якій здійснити відкіт. Не може використовуватись разом з <var>$1title</var>.",
+ "apihelp-rollback-param-user": "Ім'я користувача чиї редагування слід відкотити.",
+ "apihelp-rollback-param-summary": "Нестандартний опис редагування. Якщо порожній, буде використано опис редагування за замовчуванням.",
+ "apihelp-rollback-param-markbot": "Позначити відкинуті редагування та відкіт як редагування бота.",
+ "apihelp-rollback-param-watchlist": "Безумовно додати або вилучити сторінку із списку спостереження поточного користувача, використати налаштування, або не змінювати статус (не)спостереження.",
+ "apihelp-rollback-example-simple": "Відкинути останні редагування сторінки <kbd>Main Page</kbd> здійснені користувачем <kbd>Example</kbd>.",
+ "apihelp-rollback-example-summary": "Відкинути останні редагування сторінки <kbd>Main Page</kbd> здійснені IP-користувачем <kbd>192.0.2.5</kbd> з причиною <kbd>Reverting vandalism</kbd>, та позначити ці редагування та відкіт як редагування бота.",
+ "apihelp-setnotificationtimestamp-description": "Оновити часову мітку сповіщень для сторінок, що спостерігаються.\n\nЦе зачепить підсвічування змінених сторінок у списку спостереження та історії, а також надсилання електронного листа якщо опція налаштувань «{{int:tog-enotifwatchlistpages}}» увімкнена.",
+ "apihelp-setnotificationtimestamp-param-entirewatchlist": "Опрацювати всі сторінки, що спостерігаються.",
+ "apihelp-setnotificationtimestamp-param-timestamp": "Часова мітка, яку вказати у якості часової мітки сповіщень.",
+ "apihelp-setnotificationtimestamp-param-torevid": "Версія до якої вказати часову мітку сповіщень (лише одна сторінка).",
+ "apihelp-setnotificationtimestamp-param-newerthanrevid": "Версія, до новішої від якої вказати часову мітку сповіщень (лише одна сторінка).",
+ "apihelp-setnotificationtimestamp-example-all": "Стерти статус сповіщень для всього списку спостереження.",
+ "apihelp-setnotificationtimestamp-example-page": "Стерти статус сповіщень для <kbd>Main page</kbd>.",
+ "apihelp-setnotificationtimestamp-example-pagetimestamp": "Встановити часову мітку сповіщень для <kbd>Main page</kbd> так, що всі редагування після 1 січня 2012 будуть виглядати як не переглянуті.",
+ "apihelp-setnotificationtimestamp-example-allpages": "Стерти статус сповіщень для сторінок у просторі назв <kbd>{{ns:user}}</kbd>.",
+ "apihelp-tag-description": "Додати або вилучити зміни міток з окремих версій або записів журналу.",
+ "apihelp-tag-param-rcid": "Один або більше ідентифікаторів останніх змін, до яких додати або вилучити мітки.",
+ "apihelp-tag-param-revid": "Один або більше ідентифікатор з якого додати або вилучити мітку.",
+ "apihelp-tag-param-logid": "Один або більше ідентифікатор запису журналу з якого вилучити або додати мітку.",
+ "apihelp-tag-param-add": "Мітки, які слід додати. Лише визначені вручну мітки може бути додано.",
+ "apihelp-tag-param-remove": "Мітки, які слід вилучити. Лише мітки, які було визначено вручну, або взагалі не визначено, можуть бути вилучені.",
+ "apihelp-tag-param-reason": "Причина зміни.",
+ "apihelp-tag-example-rev": "Додати мітку <kbd>vandalism</kbd> до версії з ідентифікатором 123 без вказання причини",
+ "apihelp-tag-example-log": "Вилучити мітку <kbd>spam</kbd> з запису журналу з ідентифікатором 123 з причиною <kbd>Wrongly applied</kbd>",
+ "apihelp-tokens-description": "Отримати жетони для дій пов'язаних зі зміною даних.\n\nЦей модуль застарів на користь [[Special:ApiHelp/query+tokens|action=query&meta=tokens]].",
+ "apihelp-tokens-param-type": "Які типи жетонів запитати.",
+ "apihelp-tokens-example-edit": "Отримати жетон редагування (за замовчуванням).",
+ "apihelp-tokens-example-emailmove": "Отримати жетон електронної пошти та жетон перейменування.",
+ "apihelp-unblock-description": "Розблокувати користувача.",
+ "apihelp-unblock-param-id": "Ідентифікатор блоку чи розблокування (отриманий через <kbd>list=blocks</kbd>). Не може бути використано разом з <var>$1user</var>.",
+ "apihelp-unblock-param-user": "Ім'я користувача, IP-адреса чи IP-діапазон до розблокування. Не може бути використано разом з <var>$1id</var>.",
+ "apihelp-unblock-param-reason": "Причина розблокування.",
+ "apihelp-unblock-example-id": "Зняти блокування з ідентифікатором #<kbd>105</kbd>.",
+ "apihelp-unblock-example-user": "Розблокувати користувача <kbd>Bob</kbd> з причиною <kbd>Sorry Bob</kbd>.",
+ "apihelp-undelete-description": "Відновити версії вилученої сторінки.\n\nСписок вилучених версій (включено з часовими мітками) може бути отримано через [[Special:ApiHelp/query+deletedrevs|list=deletedrevs]], а список ідентифікаторів вилучених файлів може бути отримано через [[Special:ApiHelp/query+filearchive|list=filearchive]].",
+ "apihelp-undelete-param-title": "Назва сторінки, яку слід відновити.",
+ "apihelp-undelete-param-reason": "Причина відновлення.",
+ "apihelp-undelete-param-timestamps": "Часові мітки версій, які слід відновити. Якщо і <var>$1timestamps</var>, і <var>$1fileids</var> порожні, буде відновлено всі версії.",
+ "apihelp-undelete-param-fileids": "Ідентифікатори версій файлів, які слід відновити. Якщо і <var>$1timestamps</var>, і <var>$1fileids</var> порожні, буде відновлено всі версії.",
+ "apihelp-undelete-param-watchlist": "Безумовно додати або вилучити сторінку із списку спостереження поточного користувача, використати налаштування, або не змінювати статус (не)спостереження.",
+ "apihelp-undelete-example-page": "Відновити сторінку <kbd>Main Page</kbd>.",
+ "apihelp-undelete-example-revisions": "Відновити дві версії сторінки <kbd>Main Page</kbd>.",
+ "apihelp-upload-description": "Завантажити файл, або отримати статус завантажень у процесі.\n\nДоступні декілька методів:\n* Завантажити вміст файлу напряму, використовуючи параметр <var>$1file</var>.\n* Завантажити файл шматками, використовуючи параметри <var>$1filesize</var>, <var>$1chunk</var>, та <var>$1offset</var>.\n* Змусити сервер Медіавікі отримати файл за URL, використовуючи параметр <var>$1url</var>.\n* Завершити раніше розпочате завантаження, яке не вдалось через попередження, використовуючи параметр <var>$1filekey</var>.\nЗауважте, що HTTP POST повинен бути здійснений як завантаження файлу (наприклад, використовуючи <code>multipart/form-data</code>)",
+ "apihelp-upload-param-filename": "Цільова назва файлу.",
+ "apihelp-upload-param-comment": "Коментар завантаження. Також використовується як початковий текст сторінок для нових файлів, якщо <var>$1text</var> не вказано.",
+ "apihelp-upload-param-text": "Початковий текст сторінок для нових файлів.",
+ "apihelp-upload-param-watch": "Спостерігати за сторінкою.",
+ "apihelp-upload-param-watchlist": "Безумовно додати або вилучити сторінку із списку спостереження поточного користувача, використати налаштування, або не змінювати статус (не)спостереження.",
+ "apihelp-upload-param-ignorewarnings": "Ігнорувати всі попередження.",
+ "apihelp-upload-param-file": "Вміст файлу.",
+ "apihelp-upload-param-url": "URL з якого отримати файл.",
+ "apihelp-upload-param-filekey": "Ключ, що ідентифікує попереднє завантаження яке було відкладено тимчасово",
+ "apihelp-upload-param-stash": "Якщо вказано, сервер тимчасово відкладе файл замість додати його до репозиторію.",
+ "apihelp-upload-param-filesize": "Розмір файлу цілого завантаження.",
+ "apihelp-upload-param-offset": "Зміщення шматка в байтах.",
+ "apihelp-upload-param-chunk": "Шматок вмісту.",
+ "apihelp-upload-param-async": "Зробити операції з потенційно великими файлами асинхронними коли можливо.",
+ "apihelp-upload-param-asyncdownload": "Зробити отримання за URL асинхронним.",
+ "apihelp-upload-param-statuskey": "Отримати статус завантаження для цього ключа файлу (завантаження за URL)",
+ "apihelp-upload-param-checkstatus": "Отримувати статус завантаження лише для даного ключа файлу.",
+ "apihelp-upload-example-url": "Завантаження з URL.",
+ "apihelp-upload-example-filekey": "Завершити завантаження, що не вдалось через попередження.",
"apihelp-userrights-description": "Змінити членство користувача у групах.",
"apihelp-userrights-param-user": "Ім'я користувача.",
"apihelp-userrights-param-userid": "Ідентифікатор користувача.",
"api-pageset-param-pageids": "Список ідентифікаторів сторінок над якими працювати.",
"api-pageset-param-revids": "Список ідентифікаторів версій над якими працювати.",
"api-pageset-param-generator": "Отримати список сторінок над якими працювати шляхом виконання вказаного модуля запиту.\n\n<strong>Примітка:</strong> Назви параметрів генератора повинні мати префікс «g», див. приклади.",
+ "api-pageset-param-redirects-generator": "Автоматично вирішувати перенаправлення у <var>$1titles</var>, <var>$1pageids</var>, і <var>$1revids</var>, та у сторінках, повернених <var>$1generator</var>.",
+ "api-pageset-param-redirects-nogenerator": "Автоматично вирішувати перенаправлення у <var>$1titles</var>, <var>$1pageids</var>, та <var>$1revids</var>.",
+ "api-pageset-param-converttitles": "Конвертувати назви в інші варіанти за необхідності. Працює лише для вікі, мова вмісту яких підтримує конвертування варіантів. Мовами, що підтримують конвертування варіантів є $1.",
+ "api-help-title": "Довідка API Медіавікі",
+ "api-help-lead": "Це автоматично генерована сторінка документації API Медіавікі.\n\nДокументація та приклади: https://www.mediawiki.org/wiki/API",
+ "api-help-main-header": "Головний модуль",
+ "api-help-flag-deprecated": "Цей модуль є застарілим.",
+ "api-help-license": "Ліцензія: [[$1|$2]]",
+ "api-help-license-noname": "Ліцензія: [[$1|див. посилання]]",
+ "api-help-license-unknown": "Ліцензія: <span class=\"apihelp-unknown\">невідома</span>",
+ "api-help-param-deprecated": "Застарілий.",
"api-help-datatypes-header": "Типи даних"
}
"apihelp-query+watchlistraw-param-totitle": "要列举的最终标题(带名字空间前缀)。",
"apihelp-query+watchlistraw-example-simple": "列出当前用户的监视列表中的页面。",
"apihelp-revisiondelete-description": "删除和恢复修订版本。",
+ "apihelp-revisiondelete-param-ids": "用于将被删除的修订的标识符。",
"apihelp-revisiondelete-param-hide": "每次修订要隐藏的东西。",
"apihelp-revisiondelete-param-show": "每次修订要恢复显示的东西。",
"apihelp-revisiondelete-param-reason": "删除或恢复的原因。",
--- /dev/null
+<?php
+/**
+ * This file contains database access object related constants.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Database
+ */
+
+/**
+ * Helper class for DAO classes
+ *
+ * @since 1.26
+ */
+class DBAccessObjectUtils {
+ /**
+ * @param integer $bitfield
+ * @param integer $flags IDBAccessObject::READ_* constant
+ * @return bool Bitfield has flag $flag set
+ */
+ public static function hasFlags( $bitfield, $flags ) {
+ return ( $bitfield & $flags ) == $flags;
+ }
+
+ /**
+ * Get an appropriate DB index and options for a query
+ *
+ * @param integer $bitfield
+ * @return array (DB_MASTER/DB_SLAVE, SELECT options array)
+ */
+ public static function getDBOptions( $bitfield ) {
+ $index = self::hasFlags( $bitfield, IDBAccessObject::READ_LATEST )
+ ? DB_MASTER
+ : DB_SLAVE;
+
+ $options = array();
+ if ( self::hasFlags( $bitfield, IDBAccessObject::READ_EXCLUSIVE ) ) {
+ $options[] = 'FOR UPDATE';
+ } elseif ( self::hasFlags( $bitfield, IDBAccessObject::READ_LOCKING ) ) {
+ $options[] = 'LOCK IN SHARE MODE';
+ }
+
+ return array( $index, $options );
+ }
+}
\ No newline at end of file
* @return EnqueueJob
*/
public static function newFromJobsByWiki( array $jobsByWiki ) {
+ $deduplicate = true;
+
$jobMapsByWiki = array();
foreach ( $jobsByWiki as $wiki => $jobs ) {
$jobMapsByWiki[$wiki] = array();
} else {
throw new InvalidArgumentException( "Jobs must be of type JobSpecification." );
}
+ $deduplicate = $deduplicate && $job->ignoreDuplicates();
}
}
- return new self( Title::newMainPage(), array( 'jobsByWiki' => $jobMapsByWiki ) );
+ $eJob = new self( Title::newMainPage(), array( 'jobsByWiki' => $jobMapsByWiki ) );
+ // If *all* jobs to be pushed are to be de-duplicated (a common case), then
+ // de-duplicate this whole job itself to avoid build up in high traffic cases
+ $eJob->removeDuplicates = $deduplicate;
+
+ return $eJob;
}
public function run() {
* @file
*/
+use Liuggio\StatsdClient\Entity\StatsdData;
use Liuggio\StatsdClient\Entity\StatsdDataInterface;
use Liuggio\StatsdClient\Factory\StatsdDataFactory;
return $entity;
}
+ /**
+ * @return StatsdData[]
+ */
public function getBuffer() {
return $this->buffer;
}
--- /dev/null
+<?php
+/**
+ * Copyright 2015
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+use Liuggio\StatsdClient\StatsdClient;
+use Liuggio\StatsdClient\Entity\StatsdData;
+use Liuggio\StatsdClient\Entity\StatsdDataInterface;
+
+/**
+ * A statsd client that applies the sampling rate to the data items before sending them.
+ *
+ * @since 1.26
+ */
+class SamplingStatsdClient extends StatsdClient {
+ /**
+ * Sets sampling rate for all items in $data.
+ * The sample rate specified in a StatsdData entity overrides the sample rate specified here.
+ *
+ * {@inheritDoc}
+ */
+ public function appendSampleRate( $data, $sampleRate = 1 ) {
+ if ( $sampleRate < 1 ) {
+ array_walk( $data, function( $item ) use ( $sampleRate ) {
+ /** @var $item StatsdData */
+ if ( $item->getSampleRate() === 1 ) {
+ $item->setSampleRate( $sampleRate );
+ }
+ });
+ }
+
+ return $data;
+ }
+
+ /**
+ * Sample the metrics according to their sample rate and send the remaining ones.
+ *
+ * {@inheritDoc}
+ */
+ public function send( $data, $sampleRate = 1 ) {
+ if ( !is_array( $data ) ) {
+ $data = array( $data );
+ }
+ if ( !$data ) {
+ return;
+ }
+ foreach ( $data as $item ) {
+ if ( !( $item instanceof StatsdDataInterface ) ) {
+ throw new InvalidArgumentException(
+ 'SamplingStatsdClient does not accept stringified messages' );
+ }
+ }
+
+ // add sampling
+ if ( $sampleRate < 1 ) {
+ $data = $this->appendSampleRate( $data, $sampleRate );
+ }
+ $data = $this->sampleData( $data );
+
+ $messages = array_map( 'strval', $data );
+
+ // reduce number of packets
+ if ( $this->getReducePacket() ) {
+ $data = $this->reduceCount( $data );
+ }
+ //failures in any of this should be silently ignored if ..
+ $written = 0;
+ try {
+ $fp = $this->getSender()->open();
+ if ( !$fp ) {
+ return;
+ }
+ foreach ( $messages as $message ) {
+ $written += $this->getSender()->write( $fp, $message );
+ }
+ $this->getSender()->close( $fp );
+ } catch ( Exception $e ) {
+ $this->throwException( $e );
+ }
+
+ return $written;
+ }
+
+ /**
+ * Throw away some of the data according to the sample rate.
+ * @param StatsdDataInterface[] $data
+ * @return array
+ * @throws LogicException
+ */
+ protected function sampleData( $data ) {
+ $newData = array();
+ $mt_rand_max = mt_getrandmax();
+ foreach ( $data as $item ) {
+ $samplingRate = $item->getSampleRate();
+ if ( $samplingRate <= 0.0 || $samplingRate > 1.0 ) {
+ throw new LogicException( 'Sampling rate shall be within ]0, 1]' );
+ }
+ if (
+ $samplingRate === 1 ||
+ ( mt_rand() / $mt_rand_max <= $samplingRate )
+ ) {
+ $newData[] = $item;
+ }
+ }
+ return $newData;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function throwException( Exception $exception ) {
+ if ( !$this->getFailSilently() ) {
+ throw $exception;
+ }
+ }
+}
return;
}
- if ( $from === self::READ_LOCKING ) {
- $data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle, array( 'FOR UPDATE' ) );
- } elseif ( $from === self::READ_LATEST ) {
- $data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle );
- } elseif ( $from === self::READ_NORMAL ) {
- $data = $this->pageDataFromTitle( wfGetDB( DB_SLAVE ), $this->mTitle );
+ if ( is_int( $from ) ) {
+ list( $index, $opts ) = DBAccessObjectUtils::getDBOptions( $from );
+ $data = $this->pageDataFromTitle( wfGetDB( $index ), $this->mTitle, $opts );
+
if ( !$data
+ && $index == DB_SLAVE
&& wfGetLB()->getServerCount() > 1
&& wfGetLB()->hasOrMadeRecentMasterChanges()
) {
$from = self::READ_LATEST;
- $data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle );
+ list( $index, $opts ) = DBAccessObjectUtils::getDBOptions( $from );
+ $data = $this->pageDataFromTitle( wfGetDB( $index ), $this->mTitle, $opts );
}
} else {
// No idea from where the caller got this data, assume slave database.
}, array(
'$VARS.wgLegacyJavaScriptGlobals' => $this->getConfig()->get( 'LegacyJavaScriptGlobals' ),
'$VARS.configuration' => $this->getConfigSettings( $context ),
- '$VARS.baseModulesScript' => Html::linkedScript( self::getStartupModulesUrl( $context ) ),
+ '$VARS.baseModulesUri' => self::getStartupModulesUrl( $context ),
) );
$pairs['$CODE.registrations()'] = str_replace( "\n", "\n\t", trim( $this->getModuleRegistrations( $context ) ) );
// Add various resources if required
if ( $wgUseAjax ) {
- $modules['legacy'][] = 'mediawiki.legacy.ajax';
-
if ( $wgEnableAPI ) {
if ( $wgEnableWriteAPI && $wgAjaxWatch && $user->isLoggedIn()
&& $user->isAllowed( 'writeapi' )
* @param string $code Confirmation code
*/
function attemptConfirm( $code ) {
- $user = User::newFromConfirmationCode( $code );
+ $user = User::newFromConfirmationCode( $code, User::READ_LATEST );
if ( !is_object( $user ) ) {
$this->getOutput()->addWikiMsg( 'confirmemail_invalid' );
* @param string $code Confirmation code
*/
function attemptInvalidate( $code ) {
- $user = User::newFromConfirmationCode( $code );
+ $user = User::newFromConfirmationCode( $code, User::READ_LATEST );
if ( !is_object( $user ) ) {
$this->getOutput()->addWikiMsg( 'confirmemail_invalid' );
$query['only'] = 'scripts';
$startupContext = new ResourceLoaderContext( $rl, new FauxRequest( $query ) );
+ $query['raw'] = true;
+
$modules = $rl->getTestModuleNames( 'qunit' );
+ // Disable autostart because we load modules asynchronously. By default, QUnit would start
+ // at domready when there are no tests loaded and also fire 'QUnit.done' which then instructs
+ // Karma to end the run before the tests even started.
+ $qunitConfig = 'QUnit.config.autostart = false;'
+ . 'if (window.__karma__) {'
+ // karma-qunit's use of autostart=false and QUnit.start conflicts with ours.
+ // Hack around this by replacing 'karma.loaded' with a no-op and call it ourselves later.
+ // See <https://github.com/karma-runner/karma-qunit/issues/27>.
+ . 'window.__karma__.loaded = function () {};'
+ . '}';
+
// The below is essentially a pure-javascript version of OutputPage::getHeadScripts.
$startup = $rl->makeModuleResponse( $startupContext, array(
'startup' => $rl->getModule( 'startup' ),
'user.options' => $rl->getModule( 'user.options' ),
'user.tokens' => $rl->getModule( 'user.tokens' ),
) );
- $code .= Xml::encodeJsCall( 'mw.loader.load', array( $modules ) );
+ // Catch exceptions (such as "dependency missing" or "unknown module") so that we
+ // always start QUnit. Re-throw so that they are caught and reported as global exceptions
+ // by QUnit and Karma.
+ $code .= '(function () {'
+ . 'var start = window.__karma__ ? window.__karma__.start : QUnit.start;'
+ . 'try {'
+ . 'mw.loader.using( ' . Xml::encodeJsVar( $modules ) . ' ).always( start );'
+ . '} catch ( e ) { start(); throw e; }'
+ . '}());';
header( 'Content-Type: text/javascript; charset=utf-8' );
header( 'Cache-Control: private, no-cache, must-revalidate' );
header( 'Pragma: no-cache' );
+ echo $qunitConfig;
echo $startup;
- echo "\n";
- // Note: The following has to be wrapped in a script tag because the startup module also
- // writes a script tag (the one loading mediawiki.js). Script tags are synchronous, block
- // each other, and run in order. But they don't nest. The code appended after the startup
- // module runs before the added script tag is parsed and executed.
- echo Xml::encodeJsCall( 'document.write', array( Html::inlineScript( $code ) ) );
+ // The following has to be deferred via RLQ because the startup module is asynchronous.
+ echo ResourceLoader::makeLoaderConditionalScript( $code );
}
private function plainQUnit() {
$out = $this->getOutput();
$out->disable();
- $url = $this->getPageTitle( 'qunit/export' )->getFullURL( array(
- 'debug' => ResourceLoader::inDebugMode() ? 'true' : 'false',
- ) );
-
$styles = $out->makeResourceLoaderLink( 'jquery.qunit',
ResourceLoaderModule::TYPE_STYLES
);
- // Use 'raw' since this is a plain HTML page without ResourceLoader
+
+ // Use 'raw' because QUnit loads before ResourceLoader initialises (omit mw.loader.state call)
+ // Use 'test' to ensure OutputPage doesn't use the "async" attribute because QUnit must
+ // load before qunit/export.
$scripts = $out->makeResourceLoaderLink( 'jquery.qunit',
ResourceLoaderModule::TYPE_SCRIPTS,
- array( 'raw' => 'true' )
+ array( 'raw' => true, 'sync' => true )
);
$head = implode( "\n", array_merge( $styles['html'], $scripts['html'] ) );
$summary
<div id="qunit"></div>
HTML;
+
+ $url = $this->getPageTitle( 'qunit/export' )->getFullURL( array(
+ 'debug' => ResourceLoader::inDebugMode() ? 'true' : 'false',
+ ) );
$html .= "\n" . Html::linkedScript( $url );
header( 'Content-Type: text/html; charset=utf-8' );
static $msgcache = null;
if ( $msgcache === null ) {
static $msgs = array( 'isredirect', 'istemplate', 'semicolon-separator',
- 'whatlinkshere-links', 'isimage', 'edit' );
+ 'whatlinkshere-links', 'isimage', 'editlink' );
$msgcache = array();
foreach ( $msgs as $msg ) {
$msgcache[$msg] = $this->msg( $msg )->escaped();
}
# Space for utilities links, with a what-links-here link provided
- $wlhLink = $this->wlhLink( $nt, $msgcache['whatlinkshere-links'], $msgcache['edit'] );
+ $wlhLink = $this->wlhLink( $nt, $msgcache['whatlinkshere-links'], $msgcache['editlink'] );
$wlh = Xml::wrapClass(
$this->msg( 'parentheses' )->rawParams( $wlhLink )->escaped(),
'mw-whatlinkshere-tools'
"아라",
"Koroğlu",
"Baloch Afghanistan",
- "Macofe"
+ "Macofe",
+ "Sadiqr"
]
},
"tog-underline": "باغلانتیلارین آلتینی خطله:",
"no-null-revision": "\"$1\" صحیفهسی اوچون یئنی بوش بیر نوسخه یارادیلا بیلمهدی",
"badtitle": "پیس باشلیق",
"badtitletext": "آختاریلان صحیفه آدی سهودیر و يا بوْشدور، يا دا دۆزگون اوْلمايان دیللرآراسی، ياخود ویکیلرآراسی کئچید ایستیفاده ائدیلیب. \nباشلیقلاردا ایستیفاده ائدیلمهسی قاداغان اوْلونان بیر و يا داها چوْخ سیمووْل ایستیفاده ائدیلمیش اوْلا بیلر.",
+ "title-invalid-empty": "آختاردیٛغیٛنیٛز صفحهنین آدیٛ بوْشدۇر و یا آدلارفضاسیٛندا یالنیٛز آدیٛ وار.",
+ "title-invalid-utf8": "ایستنیلن صفحهنین آدیندا بیر یانلیش UTF-8 کاراکتِری وار.",
+ "title-invalid-characters": "ایستنیلن صفحهنین آدیندا، یانلیش کاراکتِرلر وار: «$1»",
"perfcached": "بو بیلگی، کَش اولوبدور و اولا بیلر گونجل اولماسین. چوخو {{PLURAL:$1|بیر نتیجه|$1 نتیجه}} کَشدهدیر.",
"perfcachedts": "بو بیلگی کَش اولوبدور، سون دفعه $1 واختیندا گونجلیبدیر. چوخو {{PLURAL:$4|بیر نتیجه|$4 نتیجه}} کَشدهدیر.",
"querypage-no-updates": "بو یارپاقدا گونجللهمک ایندی باغلانیبدیر.\nبورداکی بیلگیلر یئنیلشمیهجکلر.",
"actionthrottled": "سیزین چالیشمانیزین قاباغی آلیندی",
"actionthrottledtext": "آنتی-ایسپام حرکتلری گؤره، بیر حرکتی قیسا بیر زامان آرالیغیندا چوخئتمهنیز انگللندی، و سیز حدی آشمیسینیز. لطفاً بیر نئچه دقیقه سونرا یئنیدن یوخلایین.",
"protectedpagetext": "بو صحیفه دیَیشدیرمک و باشقا ایشلر اوچون باغلیدیر.",
- "viewsourcetext": "سیز بو صحیفهنین مزمونونو گؤره و کؤچوره بیلرسینیز:",
- "viewyourtext": "'''اؤز دَییشیکلیکلرینیز''' ین کودونو گؤروب و بو صحیفهیه کوپی ائده بیلرسینیز:",
+ "viewsourcetext": "سیز بو صفحهنین قایناغینی گؤروب و کؤچوره بیلرسینیز.",
+ "viewyourtext": "سیز بو صفحهده <strong>اؤز دَییشیکلیکلرینیزین</strong> قایناغینی گؤروب و کوپی ائده بیلرسینیز.",
"protectedinterface": "بو صحیفهده پروقرام تأمیناتی اوچون سیستئم بیلگیلری وار و سوی-ایستیفادهنین قارشیسینی آلماق اوچون محافظه اولونمالیدیر.",
"editinginterface": "<strong>دیقت:</strong> سیز بیر یازیلیم آرا-اوزونه یازی تعمین ائدن صحیفهنی دَییشدیرمکدهسینیز.\nبو صحیفهنی دَییشدیرمک، بو ویکینی ایستیفاده ائدن باشقا ایستیفادهچیلرین گؤرونوشونو دَییشهجکدیر.",
"translateinterface": "ترجومه و یا اونون دَییشدیرمک هامی ویکی لر اوچون [//translatewiki.net/ translatewiki.net]،مدیا ویکی نین یئرلری ائتمک پروژه سیندن ایستفاده ائدین",
"boteditletter": "ب",
"number_of_watching_users_pageview": "[{{PLURAL:$1|بیر|$1}} ایزلهین ایستیفادهچی]",
"rc_categories": "بؤلمهلره محدودلاشدیر («|» ایله آییر)",
- "rc_categories_any": "هر",
+ "rc_categories_any": "سئچیلمیشلرین هر بیریسی",
"rc-change-size-new": "دَییشیکلیکدن سونرا {{PLURAL:|بیر|$1}} بایت",
"newsectionsummary": "/* $1 */ یئنی بؤلمه",
"rc-enhanced-expand": "تفصیللری گؤستر",
"randomincategory-nopages": "[[:Category:$1|$1]] بؤلمهسینده، هئچ صحیفه یوخدور.",
"randomincategory-category": "بؤلمه:",
"randomincategory-legend": "بؤلمهده راستگله صفحه",
+ "randomincategory-submit": "گئت",
"randomredirect": "راستگله یوللاندیرما",
"randomredirect-nopages": "«$1» آدفضاسیندا هئچ بیر یوللاندیرما یوخدور.",
"statistics": "آمارلار",
"tooltip-pt-logout": "چیخیش",
"tooltip-pt-createaccount": "سیزدن دعوت اولونور ایشلدن حسابی آچیب و گیریش ائدهسیز؛ آنجاق حساب یاراتماق ایستگه باغلیدیر",
"tooltip-ca-talk": "ایچیندهکیلره گؤره دانیشیق",
- "tooltip-ca-edit": "سÛ\8cز بÙ\88 صÙ\81ØÙ\87â\80\8cÙ\86Û\8c دÙ\8eÛ\8cÛ\8cشدÛ\8cرÙ\87 بÛ\8cÙ\84رسÛ\8cÙ\86Û\8cز. Ù\84Ø·Ù\81اÙ\8b Ù\82ئÛ\8cد ائتÙ\85Ù\87â\80\8cدÙ\86 Ù\82اباÙ\82 اؤÙ\86â\80\8cگؤسترÛ\8cØ´ دÙ\88Ú¯Ù\85Ù\87â\80\8cسÛ\8cÙ\86Û\8c اÛ\8cØ´Ù\84دÛ\8cÙ\86",
+ "tooltip-ca-edit": "بÛ\87 صÙ\81ØÙ\87â\80\8câ\80\8cÙ\86Û\8c دÙ\8eÛ\8cÛ\8cشدÛ\8cر",
"tooltip-ca-addsection": "یئنی بؤلوم یارات",
"tooltip-ca-viewsource": "بو صحیفه قورونوبدور.\nاونون قایناغینا باخا بیلرسیز",
"tooltip-ca-history": "بو صفحهنین گئچمیش سۆروملری",
"watchlistedit-raw-done": "ایزلهدیکلرینیز گونجللندی.",
"watchlistedit-raw-added": "{{PLURAL:$1|بیر|$1}} باشلیق آرلیریلدی:",
"watchlistedit-raw-removed": "{{PLURAL:$1|بیر|$1}} باشلیق چیخاریلدی:",
+ "watchlistedit-clear-legend": "ایزلدیکلریمین لیستین سیل",
"watchlistedit-clear-titles": "باشلیقلار:",
+ "watchlisttools-clear": "ایزلدیکلریمین لیستین سیل",
"watchlisttools-view": "ایلگیلی دَییشیکلیکلره باخین",
"watchlisttools-edit": "ایزلهدیکلره باخ و اونلاری دَییشدیر",
"watchlisttools-raw": "چیی ایزلهدیکلری دَییشدیر",
"version-libraries": "نصب اولونموش کیتابخانا",
"version-libraries-library": "کیتابائوی",
"version-libraries-version": "نوسخه",
+ "version-libraries-authors": "یازارلار",
"redirect": "فایل، ایستیفادهچی، صفحه یا نوسخه آیدی-سی ایله یوللاندیرما",
"redirect-legend": "بیر فایل یا صحیفهیه یوللاندیرما",
"redirect-summary": "بو اؤزل صحیفه، بیر فایلا (فایل آدی ایله)، صفحهیه (نوسخه یا صفحه آیدی-سی ایله) یا ایستیفادهچی صفحهسینه (ایستیفادهچی نومره آیدی-سی ایله) یوللاندیریر. ایشلتمک: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]]، [[{{#Special:Redirect}}/revision/328429]]، یا [[{{#Special:Redirect}}/user/101]].",
"tags-active-no": "یوْخ",
"tags-edit": "دَییشدیر",
"tags-delete": "سیل",
+ "tags-activate": "ائتکینلشدیر",
"tags-hitcount": "$1 {{PLURAL:$1|دییشیکلیک|دییشیکلیک}}",
"tags-create-submit": "یارات",
"tags-edit-title": "اِتیکِتلری دَییشدیر",
"htmlform-cloner-create": "چوْخراق آرتیر",
"htmlform-cloner-delete": "سیل",
"htmlform-cloner-required": "ان آزی بیر دیَر گرکلیدیر.",
+ "htmlform-title-badnamespace": "[[:$1]]، «{{ns:$2}}» آدفضاسیندا دئییل.",
+ "htmlform-title-not-creatable": "«$1» بیر یارانا بیلن صفحه آدی دئییل",
+ "htmlform-title-not-exists": "[[:$1]] یوخدور.",
+ "htmlform-user-not-exists": "<strong>$1</strong> یوخدور.",
+ "htmlform-user-not-valid": "<strong>$1</strong> بیر دوزگون ایشلدن آدی دئییل.",
"sqlite-has-fts": "$1 بوتون یازی آختارما دستگیله",
"sqlite-no-fts": "$1 بوتون یازی آختارماماقلا",
"logentry-delete-delete": "$1، $3 صحیفهسینی {{GENDER:$2|سیلدی}}",
"pagelang-name": "صفحه",
"pagelang-language": "دیل",
"pagelang-select-lang": "دیل سئچمهسی",
+ "right-pagelang": "صفحه دیلینی دَییشدیر",
+ "action-pagelang": "صفحه دیلینی دَییشدیر",
+ "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (ائتکین)",
+ "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''ائتکیسیز''')",
+ "mediastatistics": "مئدیا آمارلاری",
+ "mediastatistics-nbytes": "{{PLURAL:$1|$1}} بایت ($2؛ ٪$3)",
+ "mediastatistics-table-mimetype": "MIME تیپی",
"mediastatistics-table-count": "فایللارین سایی",
"mediastatistics-header-unknown": "بیلینمهین",
"mediastatistics-header-bitmap": "بیتمپ گؤرونتولر",
"mediastatistics-header-audio": "سس",
"mediastatistics-header-video": "ویدیولار",
"mediastatistics-header-office": "دفتر",
+ "mediastatistics-header-text": "یازیلی",
"headline-anchor-title": "بو بؤلومه باغلانتی",
"special-characters-group-latin": "لاتین",
"special-characters-group-latinextended": "لاتین گئنیشلندیریلمیش",
"special-characters-group-khmer": "خمر",
"special-characters-title-endash": "آرالیق خطی دی",
"special-characters-title-emdash": "آرالیق خطی چکیلیب",
- "special-characters-title-minus": "منفی علامتی"
+ "special-characters-title-minus": "منفی علامتی",
+ "mw-widgets-dateinput-no-date": "تاریخ سئچیلمهییب",
+ "mw-widgets-titleinput-description-new-page": "صفحه هلهلیک یوخدور",
+ "mw-widgets-titleinput-description-redirect": "$1-ه یوللاندیر"
}
"actionthrottled": "কাজের গতি ধীরকরণ",
"actionthrottledtext": "স্প্যাম-রোধী সমাধান হিসেবে এই কাজটি খুব কম সময়ে অনেক বেশিবার সম্পাদনা করার সীমা বেঁধে দেওয়া হয়েছে। আপনি সেই সীমা অতিক্রম করেছেন। অনুগ্রহ করে কয়েক মিনিট পরে আবার চেষ্টা করুন।",
"protectedpagetext": "সম্পাদনা অথবা স্থানান্তর এড়াতে এ পাতাটির ব্যবহার নিয়ন্ত্রণ করা হয়েছে।",
- "viewsourcetext": "এ পাতাটি আপনি দেখতে এবং উৎসের অনুলিপি নিতে পারবেন:",
- "viewyourtext": "আপনি এই পাতায় <strong>আপনার সম্পাদনা</strong>দেখতে এবং অনুলিপি করতে পারেন:",
+ "viewsourcetext": "এ পাতাটি আপনি দেখতে এবং উৎসের অনুলিপি নিতে পারবেন।",
+ "viewyourtext": "আপনি এই পাতায় <strong>আপনার সম্পাদনা</strong>দেখতে এবং অনুলিপি করতে পারেন।",
"protectedinterface": "এই পাতার বিষয়বস্তু এই উইকি সফটওয়্যারের একটি ইন্টারফেস বার্তা প্রদান করে, তাই এটিকে সুরক্ষিত করে রাখা হয়েছে।\nসকল উইকির অনুবাদে কোনো ধরনের সংযোজন বা পরিবর্তন করতে, অনুগ্রহ করে মিডিয়াউইকি স্থানীয়করন প্রকল্প [//translatewiki.net/ translatewiki.net] ব্যবহার করুন।",
"editinginterface": "<strong>সতর্কীকরণ:</strong> আপনি এমন একটি পাতা সম্পাদনা করছেন যা সফটওয়্যারের জন্য ইন্টারফেস টেক্সট প্রদান করে।\nএই পাতাতে সংঘটিত পরিবর্তন এই উইকির ব্যবহারকারীদের ইন্টারফেসে প্রভাব ফেলবে, যা অন্য ব্যবহারকারীরা দেখতে পাবেন।",
"translateinterface": "সকল উইকির জন্য অনুবাদ যোগ বা পরিবর্তন করতে, দয়া করে [//translatewiki.net/ translatewiki.net], মিডিয়াউইকি স্থানীয়করণ প্রকল্প ব্যবহার করুন।",
"newpageletter": "ন",
"boteditletter": "ব",
"number_of_watching_users_pageview": "[$1 {{PLURAL:$1|জন ব্যবহারকারী|জন ব্যবহারকারী}} এই পাতার উপর নজর রাখছেন]",
- "rc_categories": "à¦\8fà¦\87 বিষয়শà§\8dরà§\87ণà§\80à¦\97à§\81লিতà§\87 সà§\80মাবদà§\8dধ à¦\95রা হà§\8bà¦\95 (\"|\" দিয়à§\87 à¦\86লাদা à¦\95রà§\87 লিà¦\96à§\81ন)",
- "rc_categories_any": "যà§\87à¦\95à§\8bনà§\8b",
+ "rc_categories": "বিষয়শà§\8dরà§\87ণà§\80à¦\97à§\81লিতà§\87 সà§\80মা (\"|\" দিয়à§\87 à¦\86লাদা à¦\95রà§\81ন):",
+ "rc_categories_any": "à¦\9aয়নà§\87র à¦\9cনà§\8dয যà§\87à¦\95à§\8bনà§\8b à¦\95িà¦\9bà§\81",
"rc-change-size-new": "পরিবর্তনের পর $1 {{PLURAL:$1|বাইট}}",
"newsectionsummary": "/* $1 */ নতুন অনুচ্ছেদ",
"rc-enhanced-expand": "বিস্তারিত দেখাও",
"viewsourcelink": "pogledaj izvor",
"editsectionhint": "Uredi sekciju: $1",
"toc": "Sadržaj",
- "showtoc": "pokaži",
+ "showtoc": "prikaži",
"hidetoc": "sakrij",
"collapsible-collapse": "sklopi",
"collapsible-expand": "Proširi",
"rev-deleted-diff-view": "Jedna od revizija u ovoj razlici je '''obrisana'''.\nVi možete vidjeti ovu razliku; detalji o tome se mogu vidjeti u [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} zapisniku brisanja].",
"rev-suppressed-diff-view": "Jedna od revizija u ovoj razlici je '''sakrivena'''.\nVi možete vidjeti ovu razliku; detalji se mogu vidjeti u [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} zapisniku sakrivanja].",
"rev-delundel": "pokaži/sakrij",
- "rev-showdeleted": "Pokaži",
+ "rev-showdeleted": "prikaži",
"revisiondelete": "Obriši/vrati revizije",
"revdelete-nooldid-title": "Nije unesena tačna revizija",
"revdelete-nooldid-text": "Niste odredili odredišnu verziju da se izvrši ova funkcija, ili ta verzija ne postoji, ili pokušavate sakriti trenutnu verziju.",
"recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|spisak novih stranica]])",
"rcnotefrom": "Ispod {{PLURAL:$5|je izmjena|su izmjene}} od <strong>$3, $4</strong> (do <strong>$1</strong> prikazano).",
"rclistfrom": "Prikaži nove izmjene počev od $3 $2",
- "rcshowhideminor": "$1 male izmjene",
- "rcshowhideminor-show": "Pokaži",
+ "rcshowhideminor": "$1 manje izmjene",
+ "rcshowhideminor-show": "Prikaži",
"rcshowhideminor-hide": "Sakrij",
"rcshowhidebots": "$1 botove",
- "rcshowhidebots-show": "Pokaži",
+ "rcshowhidebots-show": "Prikaži",
"rcshowhidebots-hide": "Sakrij",
"rcshowhideliu": "$1 registrovane korisnike",
- "rcshowhideliu-show": "Pokaži",
+ "rcshowhideliu-show": "Prikaži",
"rcshowhideliu-hide": "Sakrij",
"rcshowhideanons": "$1 anonimne korisnike",
- "rcshowhideanons-show": "Pokaži",
+ "rcshowhideanons-show": "Prikaži",
"rcshowhideanons-hide": "Sakrij",
"rcshowhidepatr": "$1 patrolirane izmjene",
- "rcshowhidepatr-show": "Pokaži",
+ "rcshowhidepatr-show": "Prikaži",
"rcshowhidepatr-hide": "Sakrij",
"rcshowhidemine": "$1 moje izmjene",
- "rcshowhidemine-show": "Pokaži",
+ "rcshowhidemine-show": "Prikaži",
"rcshowhidemine-hide": "Sakrij",
"rclinks": "Prikaži najskorijih $1 izmjena u posljednjih $2 dana<br />$3",
"diff": "razl",
"withoutinterwiki": "Članci bez interwiki linkova",
"withoutinterwiki-summary": "Slijedeće stranice nemaju linkove prema verzijama na drugim jezicima.",
"withoutinterwiki-legend": "Prefiks",
- "withoutinterwiki-submit": "Pokaži",
+ "withoutinterwiki-submit": "Prikaži",
"fewestrevisions": "Stranice sa najmanje izmjena",
"nbytes": "$1 {{PLURAL:$1|bajt|bajtova}}",
"ncategories": "$1 {{PLURAL:$1|kategorija|kategorije}}",
"linksearch-line": "$1 vodi sa $2",
"linksearch-error": "Džokeri se mogu pojavljivati samo na početku adrese.",
"listusersfrom": "Prikaži korisnike koji počinju sa:",
- "listusers-submit": "Pokaži",
+ "listusers-submit": "Prikaži",
"listusers-noresult": "Nije pronađen korisnik.",
"listusers-blocked": "(blokiran)",
"activeusers": "Spisak aktivnih korisnika",
"Svetko",
"Wolliger Mensch",
"ОйЛ",
- "아라"
+ "아라",
+ "Илья Драконов"
]
},
"tog-oldsig": "нꙑнѣшьн҄ь аѵтографъ :",
"minoreditletter": "м҃л",
"newpageletter": "н҃в",
"boteditletter": "а҃ѵ",
+ "rc_categories_any": "Любы из выбраных",
"rc-change-size-new": "$1 {{PLURAL:$1|баитъ|баита|баитъ}} послѣди мѣнꙑ",
"rc-old-title": "напрьва страница створѥна ꙗко ⁖ $1 ⁖",
"recentchangeslinked": "съвѧꙁанꙑ страницѧ",
"protectedarticle": "⁖ [[$1]] ⁖ ꙁабранѥна ѥстъ",
"prot_1movedto2": "⁖ [[$1]] ⁖ нарєчєнъ ⁖ [[$2]] ⁖ ѥстъ",
"protectcomment": "какъ съмꙑслъ :",
+ "protect-cascadeon": "Эта страница защищена от редактирования {{PLURAL:$1|page, which has|pages, which have}}.",
"protect-level-sysop": "толико съмотритєлє",
"protect-othertime": "ино врѣмѧ :",
"protect-othertime-op": "ино врѣмѧ",
"prefixindex": "Сăмах пуçламăшĕсен кăтартмăшĕ",
"shortpages": "Кĕске статьясем",
"longpages": "Вăрăм страницăсем",
- "deadendpages": "Ниăçта та урăх ертмен страницăсем",
+ "deadendpages": "Нимĕнпе те çыхăнман страницăсем",
"protectedpages": "Хӳтĕленĕ страницăсем",
"protectedtitles": "Юраман ятсем",
"listusers": "Хутшăнакансен списокĕ",
"boteditletter": "B",
"number_of_watching_users_pageview": "[$1 {{PLURAL:$1|beobachtender|beobachtende}} Benutzer]",
"rc_categories": "Nur Seiten aus den Kategorien (getrennt mit „|“):",
- "rc_categories_any": "Alle",
+ "rc_categories_any": "Beliebige der ausgewählten",
"rc-change-size": "$1 {{PLURAL:$1|Byte|Bytes}}",
"rc-change-size-new": "$1 {{PLURAL:$1|Byte|Bytes}} nach der Änderung",
"newsectionsummary": "Neuer Abschnitt /* $1 */",
"mostrevisions": "Artículos con más ediciones",
"prefixindex": "Todas las páginas con prefijo",
"prefixindex-namespace": "Todas las páginas con el prefijo (espacio de nombres $1)",
- "prefixindex-strip": "Prefijo de la hilera en la lista",
+ "prefixindex-strip": "Quitar prefijos en la lista",
"shortpages": "Páginas cortas",
"longpages": "Páginas largas",
"deadendpages": "Páginas sin salida",
"special-characters-title-endash": "semirraya",
"special-characters-title-emdash": "raya",
"special-characters-title-minus": "signo de resta",
+ "mw-widgets-dateinput-no-date": "Ninguna fecha seleccionada",
"mw-widgets-titleinput-description-new-page": "la página aún no existe",
"mw-widgets-titleinput-description-redirect": "redirigir a $1"
}
"throttled-mailpassword": "یک ایمیل بازنشانی گذرواژه در $1 {{PLURAL:$1|ساعت|ساعت}} گذشته فرستاده شده است.\nبرای جلوگیری از سوءاستفاده، هر $1 {{PLURAL:$1|ساعت|ساعت}} تنها یک ایمیل بازنشانی گذرواژه فرستاده میشود.",
"mailerror": "خطا در ارسال ایمیل: $1",
"acct_creation_throttle_hit": "بازدیدکنندگان این ویکی که از نشانی آیپی شما استفاده میکنند در روز گذشته {{PLURAL:$1|یک حساب کاربری|$1 حساب کاربری}} ساختهاند، که بیشترین تعداد مجاز در آن بازهٔ زمانی است.\nبه همین خاطر، بازدیدکنندگانی که از این نشانی آیپی استفاده میکنند نمیتوانند در حال حاضر حساب جدیدی بسازند.",
- "emailauthenticated": "آدرس ایمیل شما در $2 ساعت $3 تأیید شده است.",
+ "emailauthenticated": "نشانی ایمیل شما در $2 ساعت $3 تأیید شده است.",
"emailnotauthenticated": "آدرس ایمیل شما هنوز تأیید نشده است.\nبرای هیچیک از ویژگیهای زیر، ایمیل ارسال نخواهد شد.",
"noemailprefs": "برای راهاندازی این قابلیتها یک آدرس ایمیل در ترجیحات خود مشخص کنید.",
- "emailconfirmlink": "آدرس ایمیل خود را تأیید کنید",
+ "emailconfirmlink": "نشانی ایمیل خود را تأیید کنید",
"invalidemailaddress": "آدرس ایمیل واردشدهٔ قابل قبول نیست، چرا که دارای ساختار نامعتبری است.\nلطفاً آدرسی با ساختار صحیح وارد کنید و یا بخش مربوط را خالی بگذارید.",
"cannotchangeemail": "آدرسهای ایمیل حساب کاربری در این ویکی قابل تغییر نیست.",
"emaildisabled": "این وب سایت قادر به ارسال ایمیل نیست.",
"hr_tip": "خط افقی (از آن کم استفاده کنید)",
"summary": "خلاصه:",
"subject": "موضوع/عنوان:",
- "minoredit": "این ویرایش جزئیاست",
+ "minoredit": "این ویرایشْ جزئی است",
"watchthis": "پیگیری این صفحه",
"savearticle": "صفحه ذخیره شود",
"preview": "پیشنمایش",
"exif-compression-3": "رمزگذاری نمابر سیسیآیتیتی گروه ۳",
"exif-compression-4": "رمزگذاری نمابر سیسیآیتیتی گروه ۴",
"exif-copyrighted-true": "دارای حق تکثیر",
- "exif-copyrighted-false": "وضعیت حقتکثیر تعیین نشدهاست",
+ "exif-copyrighted-false": "وضعیت حقتکثیر تعیین نشده است",
"exif-unknowndate": "تاریخ نامعلوم",
"exif-orientation-1": "عادی",
"exif-orientation-2": "افقی پشت و روشده",
"exif-urgency-other": "اولویت تعریف شده توسط کاربر ($1)",
"namespacesall": "همه",
"monthsall": "همهٔ ماهها",
- "confirmemail": "تأیید آدرس ایمیل",
+ "confirmemail": "تأیید نشانی ایمیل",
"confirmemail_noemail": "شما در صفحهٔ [[Special:Preferences|ترجیحات کاربری]] خود آدرس ایمیل معتبری وارد نکردهاید.",
"confirmemail_text": "این ویکی، شما را ملزم به تأیید آدرس ایمیل خود، پیش از استفاده از خدمات ایمیل در اینجا میکند. دکمهٔ زیرین را فعال کنید تا ایمیلی تأییدی به آدرس ایمیل شما فرستاده شود. این ایمیل دربردارندهٔ پیوندی خواهد بود که حاوی یک کد است. پیوند را در مرورگر خود بار کنید کنید تا آدرس ایمیل شما تأیید شود.",
"confirmemail_pending": "یک کد تأییدی پیشتر برای شما به صورت ایمیل فرستاده شده است. اگر همین اواخر حساب خود را باز کردهاید شاید بد نباشد که پیش از درخواست یک کد جدید چند دقیقه درنگ کنید تا شاید ایمیل قبلی برسد.",
"confirmemail_invalid": "کد تأیید نامعتبر است. ممکن است که منقضی شده باشد.",
"confirmemail_needlogin": "لطفاً برای تأیید آدرس ایمیلتان $1.",
"confirmemail_success": "آدرس ایمیل شما تأیید شدهاست.\n\nاکنون میتوانید [[Special:UserLogin|به سیستم وارد شوید]] و از ویکی لذت ببرید.",
- "confirmemail_loggedin": "آدرس ایمیل شما تأیید شد.",
- "confirmemail_subject": "تأیید آدرس ایمیل {{SITENAME}}",
+ "confirmemail_loggedin": "نشانی ایمیل شما تأیید شد.",
+ "confirmemail_subject": "تأیید نشانی ایمیل {{SITENAME}}",
"confirmemail_body": "یک نفر، احتمالاً خود شما، از نشانی آیپی $1 حساب کاربریای با نام «$2» و این آدرس ایمیل در {{SITENAME}} ایجاد کرده است.\n\nبرای تأیید این که این حساب واقعاً متعلق به شماست و نیز برای فعال سازی قابلیت ایمیل {{SITENAME}} پیوند زیر را در مرورگر اینترنت خود باز کنید:\n\n$3\n\nاگر شما این حساب کاربری را ثبت *نکردهاید*، لطفاً پیوند زیر را\nباز کنید تا تأیید آدرس ایمیل لغو شود:\n\n$5\n\nاین کدِ تأیید در تاریخ $4 منقضی خواهد شد.",
"confirmemail_body_changed": "یک نفر، احتمالاً خود شما، از نشانی آیپی $1 آدرس ایمیل حساب «$2» در {{SITENAME}} را تغییر داده است.\n\nبرای تأیید این که این حساب واقعاً به شما تعلق دارد و فعال کردن دوبارهٔ قابلیت ایمیل در {{SITENAME}}، پیوند زیر را در مرورگرتان باز کنید:\n\n$3\n\nاگر این حساب متعلق به شما نیست، پیوند زیر را باز کنید تا تغییر آدرس ایمیل لغو شود:\n\n$5\n\nاین تأییدیه در $4 منقضی میگردد.",
"confirmemail_body_set": "یک نفر، احتمالاً خود شما، از نشانی آیپی $1,\nآدرس ایمیل حساب «$2» در {{SITENAME}} را به این آدرس تغییر داده است.\n\nبرای تأیید این که این حساب واقعاً به شما تعلق دارد و فعال کردن دوبارهٔ قابلیت ایمیل در {{SITENAME}}، پیوند زیر را در مرورگرتان باز کنید:\n\n$3\n\nاگر این حساب متعلق به شما نیست، پیوند زیر را باز تا تغییر آدرس ایمیل، لغو شود:\n\n$5\n\nاین تأییدیه در $4 منقضی میگردد.",
- "confirmemail_invalidated": "تأیید آدرس ایمیل لغو شد",
- "invalidateemail": "لغو تأیید آدرس ایمیل",
+ "confirmemail_invalidated": "تأیید نشانی ایمیل لغو شد",
+ "invalidateemail": "لغو تأیید نشانی ایمیل",
"scarytranscludedisabled": "[تراگنجانش بینویکیانه فعال نیست]",
"scarytranscludefailed": "[فراخوانی الگو برای $1 میسر نشد]",
"scarytranscludefailed-httpstatus": "[فراخوانی الگو برای $1 میسر نشد: خطای اچتیتیپی $2]",
"newpageletter": "ח",
"boteditletter": "ב",
"number_of_watching_users_pageview": "[{{PLURAL:$1|משתמש אחד עוקב|$1 משתמשים עוקבים}} אחרי הדף]",
- "rc_categories": "×\94×\92×\91×\9c×\94 ×\9cק×\98×\92×\95ר×\99×\95ת (×\99ש ×\9c×\94פר×\99×\93 ×¢×\9d \"|\")",
- "rc_categories_any": "×\94×\9b×\95×\9c",
+ "rc_categories": "×\94×\92×\91×\9c×\94 ×\9cק×\98×\92×\95ר×\99×\95ת (×\9e×\95פר×\93×\95×\93 ×\91ת×\95 \"|\"):",
+ "rc_categories_any": "×\9b×\9c ×\90×\97ת ×\9e×\94× ×\91×\97ר×\95ת",
"rc-change-size-new": "{{PLURAL:$1|בית אחד|$1 בתים}} לאחר השינוי",
"newsectionsummary": "/* $1 */ פסקה חדשה",
"rc-enhanced-expand": "הצגת הפרטים",
"saturday-at": "$1 (szombat)",
"sunday-at": "$1 (vasárnap)",
"yesterday-at": "Tegnap $1",
- "bad_image_list": "A formátum a következő:\n\nCsak a listatételek (csillaggal * kezdődő tételek) vannak figyelembe véve. Egy sor első hivatkozásának egy rossz képre mutató hivatkozásnak kell lennie.\nUgyanazon sor további hivatkozásai kivételnek tekintettek, pl. a szócikkek, ahol a kép bennük fordulhat elő.",
+ "bad_image_list": "A formátum a következő:\n\nCsak a listatételek (csillaggal * kezdődő sorok) vannak figyelembe véve.\nEgy sor első hivatkozásának egy rossz képre mutató hivatkozásnak kell lennie.\nUgyanazon sor további hivatkozásai kivételnek tekintettek: szócikkek, amikben a kép előfordulhat.",
"metadata": "Metaadatok",
"metadata-help": "Ez a kép járulékos adatokat tartalmaz, amelyek feltehetően a kép létrehozásához használt digitális fényképezőgép vagy lapolvasó beállításairól adnak tájékoztatást. Ha a képet az eredetihez képest módosították, ezen adatok eltérhetnek a kép tényleges jellemzőitől.",
"metadata-expand": "További képadatok",
"tags-create-warnings-below": "Vole tu continuar a crear le etiquetta?",
"tags-delete-title": "Deler etiquetta",
"tags-delete-explanation-initial": "Tu es sur le puncto de deler le etiquetta \"$1\" del base de datos.",
+ "tags-delete-explanation-in-use": "Illo essera removite ab {{PLURAL:$2|$2 version o entrata de registro al qual|tote le $2 versiones e/o entratas de registro al quales}} illo es actualmente applicate.",
"tags-delete-reason": "Motivo:",
"comparepages": "Comparar paginas",
"compare-page1": "Pagina 1",
"boteditletter": "B",
"unpatrolledletter": "!",
"number_of_watching_users_pageview": "[{{PLURAL:$1|eine|$1|kein}} Oppasser]",
- "rc_categories": "Nor de Saachjroppe (met „|“ dozwesche):",
- "rc_categories_any": "All, wat mer han",
+ "rc_categories": "Bejränz op de Saachjroppe (schrihv „|“ dozwesche):",
+ "rc_categories_any": "Öhndseijne vun dä aanjejovve Saachjroppe",
"rc-change-size": "$1 {{PLURAL:$1|Byte|Bytes}}",
"rc-change-size-new": "$1 {{PLURAL:$1|Byte|Bytes|Bytes}} noh dem Ändere",
"newsectionsummary": "Neu Avschnet /* $1 */",
"trackingcategories-name": "Dä Nohreesch udder däm Täxschtöck singe Nahme",
"trackingcategories-desc": "Bedengonge för enjeschloße ze sin",
"noindex-category-desc": "Di Sigg sull vun de Wäbkrauler Robots un de Söhkmaschihne nit opjenumme wähde, weil dat Zauberwoot <code><nowiki>__NOINDEX__</nowiki></code> dren schteiht un se en enem Appachemang es, woh dat zohjelohße es.",
- "index-category-desc": "Di Sigg sull vun de Wäbkrauler Robots un de Söhkmaschihne opjenumme wähde, weil dat Zauberwoot <code><nowiki>__INDEX__</nowiki></code> dren schteiht un se en enem Appachemang es, woh dat zohjelohße es, un wat nommahlerwies nit vun de Robots dorschsöhk weed.",
+ "index-category-desc": "Di Sigg sull vun de Wäbkrauler Robots un de Söhkmaschihne opjenumme wähde, weil dat Zauberwoot <code><nowiki>__INDEX__</nowiki></code> dren schteiht un se en enem Appachemang es, woh dat zohjelohße es, un wat nommahlerwihs nit vun de Robots dorschsöhk weed.",
"post-expand-template-inclusion-category-desc": "Nohdämm a paa Schablohne enjesaz woode sen, hät di Sigg mieh Dahte wi <code xml:lang=\"en\" lang=\"en\">$wgMaxArticleSize</code> zohlöhß. Et sin nit alle Oprohve vun Schablohne opjelöhß.",
"post-expand-template-argument-category-desc": "Di Sigg hät mieh Dahte wi <code xml:lang=\"en\" lang=\"en\">$wgMaxArticleSize</code> zohlöhß, nohdämm dä Wäät för ene Parramehter — jät met drei jeschweifte Klammere drömeröm, wi <code>{{{Dengenskersche}}}</code> — enjesaz woode es.",
"expensive-parserfunction-category-desc": "Di Sigg hät zoh vill düüre Befähle met Pahserfonxjuhne, för e Beijschpell esu jät, wi <code xml:lang=\"en\" lang=\"en\">#ifexist</code>. Mih doh drövver schteihd em [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Handbohch].",
"tooltip-pt-mycontris": "Lîsteya beşdariyên min",
"tooltip-pt-logout": "Derkeve",
"tooltip-ca-talk": "Gotûbêj li ser rûpela naverokê",
- "tooltip-ca-edit": "Vê rûpelê biguherîne! Berê qeydkirinê bişkoka \"Pêşdîtin\"",
+ "tooltip-ca-edit": "Vê rûpelê biguherîne",
"tooltip-ca-addsection": "Beşekê zêde bike.",
"tooltip-ca-viewsource": "Ev rûpel tê parastin.\nTu dikarî tenê li çavkaniyê binêrî.",
"tooltip-ca-history": "Guhertoyên berê yên vê rûpelê",
"tooltip-n-mainpage": "Here Destpêkê",
"tooltip-n-mainpage-description": "Here Destpêkê",
"tooltip-n-portal": "Agahdarî li ser {{SITENAME}}, tu dikarî çi bikî, tu dikarî çi li ku bîbînî",
+ "tooltip-n-currentevents": "Der barê bûyerên dawî de agahîyên nûjen bibîne",
"tooltip-n-recentchanges": "Lîsteya guherandinên dawî di vê wîkiyê da",
"tooltip-n-randompage": "Rûpeleka ketober bar bike",
"tooltip-n-help": "Bersivên ji bo pirsên te.",
"newpageletter": "N",
"boteditletter": "B",
"number_of_watching_users_pageview": "[$1 Benotzer {{PLURAL:$1|iwwerwaacht|iwwerwaachen}}]",
- "rc_categories": "Nëmme Säiten aus de Kategorien (getrennt mat \"|\"):",
- "rc_categories_any": "All",
+ "rc_categories": "Limitéieren op d'Kategorie (getrennt mat \"|\"):",
+ "rc_categories_any": "Aus iergendenger vun den erausgesichten",
"rc-change-size": "$1 {{PLURAL:$1|Byte|Bytes}}",
"rc-change-size-new": "$1 {{PLURAL:$1|Byte|Bytes}} no der Ännerung",
"newsectionsummary": "Neien Abschnitt /* $1 */",
"actionthrottled": "Veiksmas apribotas",
"actionthrottledtext": "Kad būtų apsisaugota nuo reklamų, jums neleidžiama daug kartų atlikti šį veiksmą per trumpą laiko tarpą, bet jūs pasiekėte šį limitą. Prašome vėl pamėginti po kelių minučių.",
"protectedpagetext": "Šis puslapis yra užrakintas, saugant jį nuo redagavimo.",
- "viewsourcetext": "Jūs galite žiūrėti ir kopijuoti puslapio kodą:",
- "viewyourtext": "Jūs galite matyti ir kopijuoti '''savo redagavimų''' tekstą į šį puslapį:",
+ "viewsourcetext": "Jūs galite peržiūrėti ir kopijuoti puslapio kodą:",
+ "viewyourtext": "Jūs galite peržiūrėti ir kopijuoti <strong>savo pakeitimų</strong> kodą į šį puslapį:",
"protectedinterface": "Šiame puslapyje yra apsaugotas nuo piktnaudžiavimo programinės įrangos sąsajos tekstas. Norėdami pridėti ar pakeisti vertimus visose wiki, naudokite [//translatewiki.net/ translatewiki.net] MediaWiki vertimų projektą.",
"editinginterface": "'''Dėmesio:''' Jūs redaguojate puslapį, kuris yra naudojamas programinės įrangos sąsajos tekste. Pakeitimai šiame puslapyje taip pat pakeis naudotojo sąsajos išvaizdą ir kitiems naudotojams šiame wiki.",
"translateinterface": "Kad pridėtumėte vertimus visoms wiki, naudokitės [//translatewiki.net/ translatewiki.net] – projektu, skirtu MediaWiki vertimams į vietines kalbas.",
"newpageletter": "N",
"boteditletter": "R",
"number_of_watching_users_pageview": "[$1 {{PLURAL:$1|stebintis naudotojas|stebintys naudotojai|stebinčių naudotojų}}]",
- "rc_categories": "Rodyti tik šias kategorijas (atskirkite naudodami „|“)",
- "rc_categories_any": "Bet kokia",
+ "rc_categories": "Riboti kategorijoms (atskirkite su „|“)",
+ "rc_categories_any": "Bet kuris iš pasirinktųjų",
"rc-change-size-new": "$1 {{PLURAL:$1|baitas|baitai|baitų}} po pakeitimo",
"newsectionsummary": "/* $1 */ naujas skyrius",
"rc-enhanced-expand": "Rodyti detales",
"special-characters-title-endash": "en brūkšnys",
"special-characters-title-emdash": "em brūkšnys",
"special-characters-title-minus": "minuso ženklas",
+ "mw-widgets-dateinput-no-date": "Nepasirinkta data",
"mw-widgets-titleinput-description-new-page": "puslapis dar neegzistuoja",
"mw-widgets-titleinput-description-redirect": "nukreipti į $1"
}
"group-sysop": "koán-lí jîn-oân",
"group-bureaucrat": "Koaⁿ-liâu",
"group-bot-member": "{{GENDER:$1|Ke-khì-lâng}}",
- "group-sysop-member": "{{GENDER:$1|goán-lí jîn-oân}}",
+ "group-sysop-member": "{{GENDER:$1|koán-lí jîn-oân}}",
"group-bureaucrat-member": "{{GENDER:$1|Koaⁿ-liâu}}",
"grouppage-sysop": "{{ns:project}}:Hêng-chèng jîn-oân",
"grouppage-bureaucrat": "{{ns:project}}:Koaⁿ-liâu",
"search-category": "(categorie $1)",
"search-file-match": "(komt overeen met de inhoud van het bestand)",
"search-suggest": "Bedoelde u: $1",
+ "search-rewritten": "Resultaten voor $1 getoond. Zoek in plaats daarvan naar $2.",
"search-interwiki-caption": "Zusterprojecten",
"search-interwiki-default": "Resultaten van $1:",
"search-interwiki-more": "(meer)",
"watchlisttools-raw": "Editar a lista de páginas vigiadas em forma de texto",
"signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|discussão]])",
"duplicate-defaultsort": "<strong>Aviso:</strong> A chave de ordenação padrão \"$2\" sobrepõe-se à anterior \"$1\".",
- "duplicate-displaytitle": "<strong>Aviso:</strong> Exibir título \"$2\" substituindo o título anteriormente em exibição \"$1\".",
+ "duplicate-displaytitle": "<strong>Aviso:</strong> O título em exibição \"$2\" anula o título anteriormente em exibição \"$1\".",
"invalid-indicator-name": "<strong>Erro:</strong> O atributo <code>name</code>, da página de estados, não deve estar em branco.",
"version": "Versão",
"version-extensions": "Extensões instaladas",
"unpatrolledletter": "{{optional}}\n\nUsed in {{msg-mw|Recentchanges-label-legend}}, meaning \"unpatrolled\".",
"number_of_watching_users_RCview": "{{notranslate}}\nParameters:\n* $1 - number of users who are watching",
"number_of_watching_users_pageview": "Used if <code>$wgPageShowWatchingUsers</code> is true.\n* $1 - number of watching user(s)",
- "rc_categories": "Probably to do with 'recent changes' special page, either in a particular skin, or for a particular user group.\n\nI guess that this should appear before an input box where you can specify that recent changes should be shown for pages belonging to certain categories only. You name the categories in the input box, and separate them by a pipe character. If this is right, then you should be able to use 'restrict' instead of 'limit', or even 'show pages in the following categories only'.",
- "rc_categories_any": "Used in the CategoryFilter form on [[Special:RecentChanges]], if <code>$wgAllowCategorizedRecentChanges</code> is true.\n{{Identical|Any}}",
+ "rc_categories": "A label of an input box. Appears on Special:RecentChanges if filtering recent changes by category is enable (that is, $wgAllowCategorizedRecentChanges is set to true).",
+ "rc_categories_any": "Appears ''after'' the input box the label of which is {{msg-mw|rc_categories}}, which appears on [[Special:RecentChanges]], if <code>$wgAllowCategorizedRecentChanges</code> is true. \"Chosen\" refers to categories.",
"rc-change-size": "{{optional}}\nDoes not work under $wgMiserMode ([[mwr:48986|r48986]]).\n\nParameters:\n* $1 - size of diff",
"rc-change-size-new": "Tooltip when hovering a change list diff size. Parameters:\n* $1 - the resulting new size (in bytes)",
"newsectionsummary": "Default summary when adding a new section to a page. Parameters:\n* $1 - section title",
"sunday-at": "Phrase for indicating that something occurred at a particular time on the most recent Sunday.\n\nParameters:\n* $1 - the time (localized)\n{{Related|Day-at}}",
"today-at": "Phrase for indicating that something occurred at a particular time today.\n\nParameters:\n* $1 - the time (localized)\n{{Related|Day-at}}",
"yesterday-at": "Phrase for indicating that something occurred at a particular time yesterday.\n\nParameters:\n* $1 - the time (localized)\n{{Related|Day-at}}",
- "bad_image_list": "箇条信息只出现在引导管理员用正确个格式加链接。弗会徕Mediawiki别荡处出现。",
+ "bad_image_list": "This message only appears to guide administrators to add links with the right format. This will not appear anywhere else in MediaWiki.",
"variantname-zh-hans": "{{Optional}}\n\nVariant option for wikis with variants conversion enabled.",
"variantname-zh-hant": "{{Optional}}\n\nVariant option for wikis with variants conversion enabled.",
"variantname-zh-cn": "{{Optional}}\n\nVariant option for wikis with variants conversion enabled.",
"unpatrolledletter": "!",
"number_of_watching_users_pageview": "[$1 {{PLURAL:$1|utende|utinde}} ca condrollene]",
"rc_categories": "Limite de le categorije (separate cu \"|\")",
- "rc_categories_any": "Tutte",
+ "rc_categories_any": "Qualsiasi de le scacchiate",
"rc-change-size": "$1",
"rc-change-size-new": "$1 {{PLURAL:$1|byte|byte}} apprisse 'u cangiamende",
"newsectionsummary": "/* $1 */ seziona nove",
"newpageletter": "N",
"boteditletter": "b",
"number_of_watching_users_pageview": "[temo {{PLURAL:$1|spremlja|spremljata|spremljajo|spremlja|spremlja}} $1 {{PLURAL:$1|uporabnik|uporabnika|uporabniki|uporabnikov|uporabnikov}}]",
- "rc_categories": "Omejitev na kategorije (ločite jih z »|«)",
- "rc_categories_any": "Katerokoli",
+ "rc_categories": "Omejitev na kategorije (ločite jih z »|«):",
+ "rc_categories_any": "Katera koli od izbranih",
"rc-change-size-new": "po spremembi: $1 {{PLURAL:$1|zlog|zloga|zlogi|zlogov}}",
"newsectionsummary": "/* $1 */ nov razdelek",
"rc-enhanced-expand": "Pokaži podrobnosti",
"stub-threshold": "Праг за обликовање <a href=\"#\" class=\"stub\">везе као клице</a> (у бајтовима):",
"stub-threshold-disabled": "Онемогућено",
"recentchangesdays": "Број дана у скорашњим изменама:",
- "recentchangesdays-max": "(највише $1 {{PLURAL:$1|дан|дана|дана}})",
+ "recentchangesdays-max": "Највише $1 {{PLURAL:$1|дан|дана}}",
"recentchangescount": "Број измена за приказ:",
"prefs-help-recentchangescount": "Подразумева скорашње измене, историје страница и дневнике.",
"prefs-help-watchlist-token2": "Ово је тајни кључ за веб довод вашег списка надгледања.\nСвако ко зна овај кључ биће у могућности да види ваша надгледања стога немојте га одавати никоме.\nАко је потребно можете га [[Special:ResetTokens|ресетовати]].",
"content-model-text": "čist tekst",
"content-model-javascript": "javaskript",
"content-model-css": "CSS",
+ "duplicate-args-warning": "<strong>Upozorenje:</strong> [[:$1]] poziva [[:$2]] sa više vrednosti za parametar „$3“. Samo poslednja navedena vrednost će biti korišćena.",
"expensive-parserfunction-warning": "'''Upozorenje:''' ova stranica sadrži previše poziva za raščlanjivanje.\n\nTrebalo bi da ima manje od $2 {{PLURAL:$2|poziv|poziva|poziva}}, a sada ima $1.",
"expensive-parserfunction-category": "Stranice s previše poziva za raščlanjivanje",
"post-expand-template-inclusion-warning": "'''Upozorenje:''' veličina uključenog šablona je prevelika.\nNeki šabloni neće biti uključeni.",
"search-category": "(kategorija $1)",
"search-file-match": "(podudara se sadržaj datoteke)",
"search-suggest": "Da li ste mislili na: $1",
+ "search-rewritten": "Prikazani rezultati za $1. Ipak pretraži $2.",
"search-interwiki-caption": "Bratski projekti",
"search-interwiki-default": "Rezultati sa $1:",
"search-interwiki-more": "(više)",
"stub-threshold": "Prag za oblikovanje <a href=\"#\" class=\"stub\">veze kao klice</a> (u bajtovima):",
"stub-threshold-disabled": "Onemogućeno",
"recentchangesdays": "Broj dana u skorašnjim izmenama:",
- "recentchangesdays-max": "(najviše $1 {{PLURAL:$1|dan|dana|dana}})",
+ "recentchangesdays-max": "Najviše $1 {{PLURAL:$1|dan|dana}}",
"recentchangescount": "Broj izmena za prikaz:",
"prefs-help-recentchangescount": "Podrazumeva skorašnje izmene, istorije stranica i dnevnike.",
"prefs-help-watchlist-token2": "Ovo je tajni ključ za veb dovod vašeg spiska nadgledanja.\nSvako ko zna ovaj ključ biće u mogućnosti da vidi vaša nadgledanja stoga nemojte ga odavati nikome.\nAko je potrebno možete ga [[Special:ResetTokens|resetovati]].",
"htmlform-cloner-create": "Dodaj još",
"htmlform-cloner-delete": "Ukloni",
"htmlform-cloner-required": "Bar jedna vrednost je potrebna.",
+ "htmlform-user-not-exists": "<strong>$1</strong> ne postoji.",
+ "htmlform-user-not-valid": "<strong>$1</strong> nije ispravno korisničko ime.",
"sqlite-has-fts": "$1 s podrškom pretrage celog teksta",
"sqlite-no-fts": "$1 bez podrške pretrage celog teksta",
"logentry-delete-delete": "$1 je {{GENDER:$2|obrisao|obrisala}} stranicu $3",
"tog-watchlisthideminor": "Приховати незначні редагування у списку спостереження",
"tog-watchlisthideliu": "Приховати редагування зареєстрованих дописувачів у списку спостереження",
"tog-watchlisthideanons": "Приховати редагування анонімних користувачів у списку спостереження",
- "tog-watchlisthidepatrolled": "Приховати відпатрульовані правки у списку спостереження",
+ "tog-watchlisthidepatrolled": "Приховати відпатрульовані редагування у списку спостереження",
"tog-ccmeonemails": "Надсилати мені копії листів, які я надсилаю іншим користувачам",
"tog-diffonly": "Не показувати вміст сторінки під різницею версій",
"tog-showhiddencats": "Показувати приховані категорії",
"showpreview": "Попередній перегляд",
"showdiff": "Показати зміни",
"blankarticle": "'''Попередження:''' Створена вами сторінка порожня.\nЯкщо Ви знову натиснете «{{int:savearticle}}», сторінку буде створено без вмісту.",
- "anoneditwarning": "<strong>Увага!</strong> Ð\92и не авÑ\82оÑ\80изÑ\83валиÑ\81Ñ\8f на Ñ\81айÑ\82Ñ\96. Ð\92аÑ\88а IP-адÑ\80еÑ\81а бÑ\83де пÑ\83блÑ\96Ñ\87но видима, Ñ\8fкÑ\89о ви бÑ\83деÑ\82е вноÑ\81иÑ\82и бÑ\83дÑ\8c-Ñ\8fкÑ\96 пÑ\80авки. ЯкÑ\89о ви <strong>[$1 Ñ\83вÑ\96йдеÑ\82е]</strong> або <strong>[$2 Ñ\81Ñ\82воÑ\80иÑ\82е облÑ\96ковий запиÑ\81]</strong>, пÑ\80авки замÑ\96Ñ\81Ñ\82Ñ\8c Ñ\86Ñ\8cого бÑ\83дÑ\83Ñ\82Ñ\8c пов'Ñ\8fзанÑ\96 з ваÑ\88им Ñ\96м'Ñ\8fм коÑ\80иÑ\81Ñ\82Ñ\83ваÑ\87а, а Ñ\82акож Ñ\83 вас з'являться інші переваги.",
+ "anoneditwarning": "<strong>Увага!</strong> Ð\92и не авÑ\82оÑ\80изÑ\83валиÑ\81Ñ\8f на Ñ\81айÑ\82Ñ\96. Ð\92аÑ\88а IP-адÑ\80еÑ\81а бÑ\83де пÑ\83блÑ\96Ñ\87но видима, Ñ\8fкÑ\89о Ð\92и бÑ\83деÑ\82е вноÑ\81иÑ\82и бÑ\83дÑ\8c-Ñ\8fкÑ\96 Ñ\80едагÑ\83ваннÑ\8f. ЯкÑ\89о Ð\92и <strong>[$1 Ñ\83вÑ\96йдеÑ\82е]</strong> або <strong>[$2 Ñ\81Ñ\82воÑ\80иÑ\82е облÑ\96ковий запиÑ\81]</strong>, Ñ\80едагÑ\83ваннÑ\8f бÑ\83дÑ\83Ñ\82Ñ\8c наÑ\82омÑ\96Ñ\81Ñ\82Ñ\8c пов'Ñ\8fзанÑ\96 з Ð\92аÑ\88им Ñ\96менем коÑ\80иÑ\81Ñ\82Ñ\83ваÑ\87а, а Ñ\89е Ñ\83 Ð\92ас з'являться інші переваги.",
"anonpreviewwarning": "''Ви не увійшли в систему. Якщо ви виконаєте збереження, то в історію сторінки буде записана ваша IP-адреса.''",
"missingsummary": "'''Нагадування''': Ви не дали короткого опису змін.\nНатиснувши кнопку «Зберегти» ще раз, ви збережете зміни без коментаря.",
"selfredirect": "<strong>Попередження:</strong> Ви створюєте перенаправлення на цю ж сторінку.\nВи могли вказати невірну цільову сторінку, або ж редагуєте хибну сторінку.\nЯкщо Ви натиснете \"{{int:savearticle}}\" ще раз, перенаправлення буде створено.",
"session_fail_preview": "'''Система не може зберегти ваші редагування, оскільки втрачені дані сеансу. Будь ласка, повторіть вашу спробу.\nЯкщо помилка буде повторюватись, спробуйте [[Special:UserLogout|вийти з системи]] і увійти знову.'''",
"session_fail_preview_html": "<strong>Вибачте! Неможливо зберегти ваші зміни через втрату даних HTML-сесії.</strong>\n\n''Оскільки {{SITENAME}} дозволяє використовувати чистий HTML, попередній перегляд відключено, щоб попередити JavaScript-атаки.''\n\n<strong>Якщо це легітимна спроба редагування, будь ласка, спробуйте ще раз. Якщо не вийде знову, — спробуйте [[Special:UserLogout|завершити сеанс роботи]] й ще раз ввійти до системи.</strong>",
"token_suffix_mismatch": "'''Ваше редагування було відхилене, оскільки ваша програма неправильно обробляє знаки пунктуації у вікні редагування. Редагування було скасоване для запобігання спотворенню тексту статті.\nПодібні проблеми можуть виникати при використанні анонімізуючих веб-проксі, що містять помилки.'''",
- "edit_form_incomplete": "'''Частина даних із форми редагування не досягла сервера. Уважно перевірте, чи не пошкоджені ваші правки і спробуйте ще раз.'''",
+ "edit_form_incomplete": "<strong>Частина даних із форми редагування не досягла сервера. Уважно перевірте, чи не пошкоджені Ваші редагування і спробуйте ще раз.</strong>",
"editing": "Редагування $1",
"creating": "Створення $1",
"editingsection": "Редагування $1 (розділ)",
"undo-norev": "Редагування не може бути скасоване, бо його не існує або було вилучено.",
"undo-nochange": "Схоже, редагування вже було скасовано.",
"undo-summary": "Скасування редагування № $1 користувача [[Special:Contribs/$2|$2]] ([[User talk:$2|обговорення]])",
- "undo-summary-username-hidden": "СкаÑ\81Ñ\83ваÑ\82и пÑ\80авкÑ\83 $1, виконану прихованим користувачем",
+ "undo-summary-username-hidden": "СкаÑ\81Ñ\83ваÑ\82и веÑ\80Ñ\81Ñ\96Ñ\8e $1, виконану прихованим користувачем",
"cantcreateaccounttitle": "Неможливо створити обліковий запис",
"cantcreateaccount-text": "Створення облікових записів із цієї IP-адреси ('''$1''') було заблоковане [[User:$3|користувачем $3]].\n\n$3 зазначив таку причину: ''$2''",
"cantcreateaccount-range-text": "Створення облікового запису із IP-адрес у діапазоні '''$1''', який включає вашу IP-адресу ('''$4'''), було заблоковано користувачем [[User:$3|$3]].\n\nКористувач $3 вказав як причину ''$2''",
"revdelete-selected-text": "{{PLURAL:$1|Вибрана редакція|Вибрані редакції}} із [[:$2]]:",
"revdelete-selected-file": "{{PLURAL:$1|Вибрана версія файлу|Вибрані версії файлу}} із [[:$2]]:",
"logdelete-selected": "{{PLURAL:$1|1=Обраний запис|Обрані записи}} журналу:",
- "revdelete-text-text": "Видалені версії будуть як і раніше, показані в історії сторінки, але частини їх вмісту будуть недоступні для учасників.",
- "revdelete-text-file": "Видалені версії файлу будуть як і раніше видно в історії сторінки, але їх частини вмісту будуть доступні для учасників.",
- "logdelete-text": "Видалені події в журналі будуть як і раніше видно в журналах, але частини їх вмісту будуть недоступні для учасників.",
+ "revdelete-text-text": "Видалені версії будуть як і раніше, показані в історії сторінки, але частини їх вмісту будуть недоступні для загалу.",
+ "revdelete-text-file": "Видалені версії файлу будуть як і раніше видно в історії сторінки, але їх частини вмісту будуть доступні для загалу.",
+ "logdelete-text": "Видалені події в журналі будуть як і раніше видно в журналах, але частини їх вмісту будуть недоступні для загалу.",
"revdelete-text-others": "Інші адміністратори, як і раніше, будуть мати можливість доступу до прихованого вмісту і зможуть відновити його, якщо не встановлено додаткові обмеження.",
"revdelete-confirm": "Будь ласка, підтвердіть, що ви справді бажаєте це здійснити, що усвідомлюєте наслідки та робите це згідно з [[{{MediaWiki:Policy-url}}|правилами]].",
"revdelete-suppress-text": "Приховування може відбуватися '''лише''' в таких випадках:\n* Потенційно наклепницькі відомості\n* Недоречна особиста інформація\n*: ''домашні адреси, номери телефонів, номер паспорта тощо.''",
"showhideselectedversions": "Показати/приховати обрані версії",
"editundo": "скасувати",
"diff-empty": "(Немає відмінностей)",
- "diff-multi-sameuser": "(не {{PLURAL:$1|показано однÑ\83 пÑ\80омÑ\96жнÑ\83 веÑ\80Ñ\81Ñ\96Ñ\8e|показанÑ\96 $1 пÑ\80омÑ\96жнÑ\96 веÑ\80Ñ\81Ñ\96Ñ\97|показано $1 пÑ\80омÑ\96жниÑ\85 веÑ\80Ñ\81Ñ\96й}} Ñ\86Ñ\8cого Ñ\83Ñ\87аÑ\81ника)",
- "diff-multi-otherusers": "(не {{PLURAL:$1|показана $1 пÑ\80омÑ\96жна веÑ\80Ñ\81Ñ\96Ñ\8f|показано $1 пÑ\80омÑ\96жнÑ\96 веÑ\80Ñ\81Ñ\96Ñ\97|показанÑ\96 $1 пÑ\80омÑ\96жниÑ\85 веÑ\80Ñ\81Ñ\96й}} {{PLURAL:$2|Ñ\89е одного Ñ\83Ñ\87аÑ\81ника|$2 Ñ\83Ñ\87аÑ\81ників}})",
+ "diff-multi-sameuser": "(Ð\9dе {{PLURAL:$1|показано однÑ\83 пÑ\80омÑ\96жнÑ\83 веÑ\80Ñ\81Ñ\96Ñ\8e|показанÑ\96 $1 пÑ\80омÑ\96жнÑ\96 веÑ\80Ñ\81Ñ\96Ñ\97|показано $1 пÑ\80омÑ\96жниÑ\85 веÑ\80Ñ\81Ñ\96й}} Ñ\86Ñ\8cого коÑ\80иÑ\81Ñ\82Ñ\83ваÑ\87а)",
+ "diff-multi-otherusers": "(Ð\9dе {{PLURAL:$1|показана $1 пÑ\80омÑ\96жна веÑ\80Ñ\81Ñ\96Ñ\8f|показано $1 пÑ\80омÑ\96жнÑ\96 веÑ\80Ñ\81Ñ\96Ñ\97|показанÑ\96 $1 пÑ\80омÑ\96жниÑ\85 веÑ\80Ñ\81Ñ\96й}} {{PLURAL:$2|Ñ\89е одного коÑ\80иÑ\81Ñ\82Ñ\83ваÑ\87а|$2 коÑ\80иÑ\81Ñ\82Ñ\83ваÑ\87ів}})",
"diff-multi-manyusers": "({{PLURAL:$1|не показана $1 проміжна версія|не показані $1 проміжні версії|не показано $1 проміжних версій}}, зроблених більш, ніж {{PLURAL:$2|1=$1 користувачем|$2 користувачами}})",
"difference-missing-revision": "{{PLURAL:$2|$2 версія|$2 версії|$2 версій}} для цього порівняння ($1) не {{PLURAL:$2|1=знайдена|знайдені}}.\n\nІмовірно, ви перейшли за застарілим посиланням на порівняння версій вилученої сторінки.\nПодробиці можна дізнатися з [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журналу вилучень].",
"searchresults": "Результати пошуку",
"boteditletter": "б",
"unpatrolledletter": "!",
"number_of_watching_users_pageview": "[$1 {{PLURAL:$1|користувач спостерігає|користувачі спостерігають|користувачів спостерігають}}]",
- "rc_categories": "ТÑ\96лÑ\8cки з каÑ\82егоÑ\80Ñ\96й (Ñ\80аздÑ\96лÑ\8eваÑ\87 «|»)",
- "rc_categories_any": "Ð\91Ñ\83дÑ\8c-Ñ\8fкий",
+ "rc_categories": "ТÑ\96лÑ\8cки з каÑ\82егоÑ\80Ñ\96й (Ñ\80оздÑ\96лÑ\8eваÑ\87 «|»):",
+ "rc_categories_any": "Ð\91Ñ\83дÑ\8c-Ñ\8fка з обÑ\80аниÑ\85",
"rc-change-size": "$1",
"rc-change-size-new": "Розмір після зміни: $1 {{PLURAL:$1|байт|байти|байтів}}",
"newsectionsummary": "/* $1 */ нова тема",
"listgrouprights-removegroup-self-all": "може вилучати всі групи зі свого облікового запису",
"listgrouprights-namespaceprotection-header": "Обмеження простору назв",
"listgrouprights-namespaceprotection-namespace": "Простір назв",
- "listgrouprights-namespaceprotection-restrictedto": "Права, що дозволяють учаснику редагувати",
+ "listgrouprights-namespaceprotection-restrictedto": "Права, що дозволяють користувачу редагувати",
"trackingcategories": "Відстежувані категорії",
"trackingcategories-summary": "На цій сторінці перераховані відстежують категорії, які заповнюються автоматично програмним забезпеченням MediaWiki. Їх можна перейменувати, змінивши відповідні системні повідомлення в просторі назв {{ns:8}}.",
"trackingcategories-msg": "Відстежувана категорія",
"import-error-special": "Сторінку «$1» не було імпортовано, оскільки вона належить до особливого простору назв, що не дозволяє створення сторінок.",
"import-error-invalid": "Сторінку «$1» не було імпортовано, оскільки назва, у яку вона імпортується, неприпустима у цій вікі.",
"import-error-unserialize": "Версія $2 сторінки «$1» не може бути деструктурованою (десеріалізованою). Отримано повідомлення, що у цій версії використано модель $3 сериалізована як $4.",
- "import-error-bad-location": "Ð\9fÑ\80авка $2, що використовує модель вмісту $3, не може бути збережена у «$1» цієї вікі, тому що ця модель не підтримується на цій сторінці.",
+ "import-error-bad-location": "Ð\92еÑ\80Ñ\81Ñ\96Ñ\8f $2, що використовує модель вмісту $3, не може бути збережена у «$1» цієї вікі, тому що ця модель не підтримується на цій сторінці.",
"import-options-wrong": "{{PLURAL:$2|1=Неправильна опція|Неправильні опції}}: <nowiki>$1</nowiki>",
"import-rootpage-invalid": "Вказана некоректна назва кореневої сторінки",
"import-rootpage-nosubpage": "В просторі назв вказаної кореневої сторінки «$1» заборонені підсторінки",
"pageinfo-firstuser": "Створив сторінку",
"pageinfo-firsttime": "Дата створення сторінки",
"pageinfo-lastuser": "Останній редактор",
- "pageinfo-lasttime": "Дата останньої правки",
+ "pageinfo-lasttime": "Дата останнього редагування",
"pageinfo-edits": "Загальна кількість редагувань",
"pageinfo-authors": "Загальна кількість унікальних авторів",
"pageinfo-recent-edits": "Кількість поточних редагувань в історії (протягом $1)",
"special-characters-title-endash": "коротке тире",
"special-characters-title-emdash": "довге тире",
"special-characters-title-minus": "мінус",
+ "mw-widgets-dateinput-no-date": "Дати не вибрано",
"mw-widgets-titleinput-description-new-page": "сторінка ще не існує",
"mw-widgets-titleinput-description-redirect": "перенаправлення на $1"
}
"newpageletter": "新",
"boteditletter": "机",
"number_of_watching_users_pageview": "[$1个关注用户]",
- "rc_categories": "分类限制(用“|”分隔)",
- "rc_categories_any": "任意",
+ "rc_categories": "分类限制(用“|”分隔):",
+ "rc_categories_any": "任何选择的",
"rc-change-size-new": "更改后有$1字节",
"newsectionsummary": "/* $1 */ 新段落",
"rc-enhanced-expand": "显示细节",
/* MediaWiki Legacy */
- 'mediawiki.legacy.ajax' => array(
- 'scripts' => 'resources/src/mediawiki.legacy/ajax.js',
- 'dependencies' => array(
- 'mediawiki.util',
- 'mediawiki.legacy.wikibits',
- ),
- 'position' => 'top',
- ),
'mediawiki.legacy.commonPrint' => array(
'position' => 'top',
'styles' => array(
+++ /dev/null
-/**
- * Remote Scripting Library
- * Copyright 2005 modernmethod, inc
- * Under the open source BSD license
- * http://www.modernmethod.com/sajax/
- */
-
-/*jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
-/*global alert */
-( function ( mw ) {
-
- /**
- * if sajax_debug_mode is true, this function outputs given the message into
- * the element with id = sajax_debug; if no such element exists in the document,
- * it is injected.
- */
- function debug( text ) {
- if ( !window.sajax_debug_mode ) {
- return false;
- }
-
- var b, m,
- e = document.getElementById( 'sajax_debug' );
-
- if ( !e ) {
- e = document.createElement( 'p' );
- e.className = 'sajax_debug';
- e.id = 'sajax_debug';
-
- b = document.getElementsByTagName( 'body' )[0];
-
- if ( b.firstChild ) {
- b.insertBefore( e, b.firstChild );
- } else {
- b.appendChild( e );
- }
- }
-
- m = document.createElement( 'div' );
- m.appendChild( document.createTextNode( text ) );
-
- e.appendChild( m );
-
- return true;
- }
-
- /**
- * Compatibility wrapper for creating a new XMLHttpRequest object.
- */
- function createXhr() {
- debug( 'sajax_init_object() called..' );
- var a;
- try {
- // Try the new style before ActiveX so we don't
- // unnecessarily trigger warnings in IE 7 when
- // set to prompt about ActiveX usage
- a = new XMLHttpRequest();
- } catch ( xhrE ) {
- try {
- a = new window.ActiveXObject( 'Msxml2.XMLHTTP' );
- } catch ( msXmlE ) {
- try {
- a = new window.ActiveXObject( 'Microsoft.XMLHTTP' );
- } catch ( msXhrE ) {
- a = null;
- }
- }
- }
- if ( !a ) {
- debug( 'Could not create connection object.' );
- }
-
- return a;
- }
-
- /**
- * Perform an AJAX call to MediaWiki. Calls are handled by AjaxDispatcher.php
- * func_name - the name of the function to call. Must be registered in $wgAjaxExportList
- * args - an array of arguments to that function
- * target - the target that will handle the result of the call. If this is a function,
- * if will be called with the XMLHttpRequest as a parameter; if it's an input
- * element, its value will be set to the resultText; if it's another type of
- * element, its innerHTML will be set to the resultText.
- *
- * Example:
- * sajax_do_call( 'doFoo', [1, 2, 3], document.getElementById( 'showFoo' ) );
- *
- * This will call the doFoo function via MediaWiki's AjaxDispatcher, with
- * (1, 2, 3) as the parameter list, and will show the result in the element
- * with id = showFoo
- */
- function doAjaxRequest( func_name, args, target ) {
- var i, x, uri, post_data;
- uri = mw.util.wikiScript() + '?action=ajax';
- if ( window.sajax_request_type === 'GET' ) {
- if ( uri.indexOf( '?' ) === -1 ) {
- uri = uri + '?rs=' + encodeURIComponent( func_name );
- } else {
- uri = uri + '&rs=' + encodeURIComponent( func_name );
- }
- for ( i = 0; i < args.length; i++ ) {
- uri = uri + '&rsargs[]=' + encodeURIComponent( args[i] );
- }
- // uri = uri + '&rsrnd=' + new Date().getTime();
- post_data = null;
- } else {
- post_data = 'rs=' + encodeURIComponent( func_name );
- for ( i = 0; i < args.length; i++ ) {
- post_data = post_data + '&rsargs[]=' + encodeURIComponent( args[i] );
- }
- }
- x = createXhr();
- if ( !x ) {
- alert( 'AJAX not supported' );
- return false;
- }
-
- try {
- x.open( window.sajax_request_type, uri, true );
- } catch ( e ) {
- if ( location.hostname === 'localhost' ) {
- alert( 'Your browser blocks XMLHttpRequest to "localhost", try using a real hostname for development/testing.' );
- }
- throw e;
- }
- if ( window.sajax_request_type === 'POST' ) {
- x.setRequestHeader( 'Method', 'POST ' + uri + ' HTTP/1.1' );
- x.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
- }
- x.setRequestHeader( 'Pragma', 'cache=yes' );
- x.setRequestHeader( 'Cache-Control', 'no-transform' );
- x.onreadystatechange = function () {
- if ( x.readyState !== 4 ) {
- return;
- }
-
- debug( 'received (' + x.status + ' ' + x.statusText + ') ' + x.responseText );
-
- // if ( x.status != 200 )
- // alert( 'Error: ' + x.status + ' ' + x.statusText + ': ' + x.responseText );
- // else
-
- if ( typeof target === 'function' ) {
- target( x );
- } else if ( typeof target === 'object' ) {
- if ( target.tagName === 'INPUT' ) {
- if ( x.status === 200 ) {
- target.value = x.responseText;
- }
- // else alert( 'Error: ' + x.status + ' ' + x.statusText + ' (' + x.responseText + ')' );
- } else {
- if ( x.status === 200 ) {
- target.innerHTML = x.responseText;
- } else {
- target.innerHTML = '<div class="error">Error: ' + x.status +
- ' ' + x.statusText + ' (' + x.responseText + ')</div>';
- }
- }
- } else {
- alert( 'Bad target for sajax_do_call: not a function or object: ' + target );
- }
- };
-
- debug( func_name + ' uri = ' + uri + ' / post = ' + post_data );
- x.send( post_data );
- debug( func_name + ' waiting..' );
-
- return true;
- }
-
- /**
- * @return {boolean} Whether the browser supports AJAX
- */
- function wfSupportsAjax() {
- var request = createXhr(),
- supportsAjax = request ? true : false;
-
- request = undefined;
- return supportsAjax;
- }
-
- // Expose + Mark as deprecated
- var deprecationNotice = 'Sajax is deprecated, use jQuery.ajax or mediawiki.api instead.';
-
- // Variables
- mw.log.deprecate( window, 'sajax_debug_mode', false, deprecationNotice );
- mw.log.deprecate( window, 'sajax_request_type', 'GET', deprecationNotice );
- // Methods
- mw.log.deprecate( window, 'sajax_debug', debug, deprecationNotice );
- mw.log.deprecate( window, 'sajax_init_object', createXhr, deprecationNotice );
- mw.log.deprecate( window, 'sajax_do_call', doAjaxRequest, deprecationNotice );
- mw.log.deprecate( window, 'wfSupportsAjax', wfSupportsAjax, deprecationNotice );
-
-}( mediaWiki ) );
var $spinner, href, rcid, apiRequest;
// Start preloading the notification module (normally loaded by mw.notify())
- mw.loader.load( ['mediawiki.notification'], null, true );
+ mw.loader.load( 'mediawiki.notification' );
// Hide the link and create a spinner to show it inside the brackets.
$spinner = $.createSpinner( {
( function ( mw, $ ) {
- mw.page = {};
+ // Support: MediaWiki < 1.26
+ // Cached HTML will not yet have this from OutputPage::getHeadScripts.
+ document.documentElement.className = document.documentElement.className
+ .replace( /(^|\s)client-nojs(\s|$)/, '$1client-js$2' );
- // Client profile classes for <html>
- // Allows for easy hiding/showing of JS or no-JS-specific UI elements
- $( document.documentElement )
- .addClass( 'client-js' )
- .removeClass( 'client-nojs' );
+ mw.page = {};
$( function () {
mw.util.init();
var action, api, $link;
// Start preloading the notification module (normally loaded by mw.notify())
- mw.loader.load( ['mediawiki.notification'], null, true );
+ mw.loader.load( 'mediawiki.notification' );
action = mwUriGetAction( this.href );
/**
* Creates an mw.widgets.CalendarWidget object.
*
+ * You will most likely want to use mw.widgets.DateInputWidget instead of CalendarWidget directly.
+ *
* @class
* @extends OO.ui.Widget
* @mixins OO.ui.mixin.TabIndexedElement
* @constructor
* @param {Object} [config] Configuration options
* @cfg {string} [precision='day'] Date precision to use, 'day' or 'month'
- * @cfg {string|null} [date=null] Day or month date (depending on `precision`), in the
- * format 'YYYY-MM-DD' or 'YYYY-MM'. When null, defaults to current date.
+ * @cfg {string|null} [date=null] Day or month date (depending on `precision`), in the format
+ * 'YYYY-MM-DD' or 'YYYY-MM'. When null, the calendar will show today's date, but not select
+ * it.
*/
mw.widgets.CalendarWidget = function MWWCalendarWidget( config ) {
// Config initialization
if (
this.displayLayer === this.previousDisplayLayer &&
+ this.date === this.previousDate &&
this.previousMoment &&
this.previousMoment.isSame( this.moment, this.precision === 'month' ? 'month' : 'day' )
) {
this.previousMoment = moment( this.moment );
this.previousDisplayLayer = this.displayLayer;
+ this.previousDate = this.date;
this.$body.on( 'click', this.onBodyClick.bind( this ) );
};
* Set the date.
*
* @param {string|null} [date=null] Day or month date, in the format 'YYYY-MM-DD' or 'YYYY-MM'.
- * When null, defaults to current date. When invalid, the date is not changed.
+ * When null, the calendar will show today's date, but not select it. When invalid, the date
+ * is not changed.
*/
mw.widgets.CalendarWidget.prototype.setDate = function ( date ) {
var mom = date !== null ? moment( date, this.getDateFormat() ) : moment();
if ( mom.isValid() ) {
this.moment = mom;
- this.setDateFromMoment();
+ if ( date !== null ) {
+ this.setDateFromMoment();
+ } else if ( this.date !== null ) {
+ this.date = null;
+ this.emit( 'change', this.date );
+ }
this.displayLayer = this.getDisplayLayers()[ 0 ];
this.updateUI();
}
* Get current date, in the format 'YYYY-MM-DD' or 'YYYY-MM', depending on precision. Digits will
* not be localised.
*
- * @returns {string} Date string
+ * @returns {string|null} Date string
*/
mw.widgets.CalendarWidget.prototype.getDate = function () {
return this.date;
}
.mw-widget-calendarWidget-day-today {
- border: 1px solid #3787fb;
+ box-shadow: inset 0 0 0 1px #3787fb;
border-radius: ((@calendarHeight / 7) / 2);
- margin: -1px;
}
.mw-widget-calendarWidget-item-selected {
&.mw-widget-calendarWidget-day-heading {
border-radius: ((@calendarHeight / 7) / 4);
// Hide the border from .mw-widget-calendarWidget-day-today
- border: 0;
- margin: 0;
+ box-shadow: none;
}
&.mw-widget-calendarWidget-month {
/**
* Creates an mw.widgets.DateInputWidget object.
*
+ * @example
+ * // Date input widget showcase
+ * var fieldset = new OO.ui.FieldsetLayout( {
+ * items: [
+ * new OO.ui.FieldLayout(
+ * new mw.widgets.DateInputWidget(),
+ * {
+ * align: 'top',
+ * label: 'Select date'
+ * }
+ * ),
+ * new OO.ui.FieldLayout(
+ * new mw.widgets.DateInputWidget( { precision: 'month' } ),
+ * {
+ * align: 'top',
+ * label: 'Select month'
+ * }
+ * ),
+ * new OO.ui.FieldLayout(
+ * new mw.widgets.DateInputWidget( {
+ * inputFormat: 'DD.MM.YYYY',
+ * displayFormat: 'Do [of] MMMM [anno Domini] YYYY'
+ * } ),
+ * {
+ * align: 'top',
+ * label: 'Select date (custom formats)'
+ * }
+ * )
+ * ]
+ * } );
+ * $( 'body' ).append( fieldset.$element );
+ *
+ * The value is stored in 'YYYY-MM-DD' or 'YYYY-MM' format:
+ *
+ * @example
+ * // Accessing values in a date input widget
+ * var dateInput = new mw.widgets.DateInputWidget();
+ * var $label = $( '<p>' );
+ * $( 'body' ).append( $label, dateInput.$element );
+ * dateInput.on( 'change', function () {
+ * // The value will always be a valid date or empty string, malformed input is ignored
+ * var date = dateInput.getValue();
+ * $label.text( 'Selected date: ' + ( date || '(none)' ) );
+ * } );
+ *
* @class
* @extends OO.ui.InputWidget
*
* @private
*/
mw.widgets.DateInputWidget.prototype.activate = function () {
- if ( this.getValue() === '' ) {
- // Setting today's date is probably more helpful than leaving the widget empty? We could just
- // display the placeholder and leave it there, but it's likely that at least the year will be
- // the same as today's.
-
- // Use English locale to avoid number formatting
- this.setValue( moment().locale( 'en' ).format( this.getInternalFormat() ) );
- }
-
this.$element.addClass( 'mw-widget-dateInputWidget-active' );
this.handle.toggle( false );
this.textInput.toggle( true );
border: 1px solid #ccc;
border-radius: 0.1em;
line-height: 1.275em;
+ background-color: white;
}
> .oo-ui-textInputWidget input {
}
/**
- * Adds a script tag to the DOM, either using document.write or low-level DOM manipulation,
- * depending on whether document-ready has occurred yet and whether we are in async mode.
+ * Load and execute a script with callback.
*
* @private
* @param {string} src URL to script, will be used as the src attribute in the script tag
* @param {Function} [callback] Callback which will be run when the script is done
- * @param {boolean} [async=false] Whether to load modules asynchronously.
- * Ignored (and defaulted to `true`) if the document-ready event has already occurred.
*/
- function addScript( src, callback, async ) {
- // Using isReady directly instead of storing it locally from a $().ready callback (bug 31895)
- if ( $.isReady || async ) {
- $.ajax( {
- url: src,
- dataType: 'script',
- // Force jQuery behaviour to be for crossDomain. Otherwise jQuery would use
- // XHR for a same domain request instead of <script>, which changes the request
- // headers (potentially missing a cache hit), and reduces caching in general
- // since browsers cache XHR much less (if at all). And XHR means we retreive
- // text, so we'd need to $.globalEval, which then messes up line numbers.
- crossDomain: true,
- cache: true,
- async: true
- } ).always( callback );
- } else {
- /*jshint evil:true */
- document.write( mw.html.element( 'script', { 'src': src }, '' ) );
- if ( callback ) {
- // Document.write is synchronous, so this is called when it's done.
- // FIXME: That's a lie. doc.write isn't actually synchronous.
- callback();
- }
- }
+ function addScript( src, callback ) {
+ $.ajax( {
+ url: src,
+ dataType: 'script',
+ // Force jQuery behaviour to be for crossDomain. Otherwise jQuery would use
+ // XHR for a same domain request instead of <script>, which changes the request
+ // headers (potentially missing a cache hit), and reduces caching in general
+ // since browsers cache XHR much less (if at all). And XHR means we retreive
+ // text, so we'd need to $.globalEval, which then messes up line numbers.
+ crossDomain: true,
+ cache: true
+ } ).always( callback );
}
/**
registry[module].state = 'ready';
handlePending( module );
};
- nestedAddScript = function ( arr, callback, async, i ) {
+ nestedAddScript = function ( arr, callback, i ) {
// Recursively call addScript() in its own callback
// for each element of arr.
if ( i >= arr.length ) {
}
addScript( arr[i], function () {
- nestedAddScript( arr, callback, async, i + 1 );
- }, async );
+ nestedAddScript( arr, callback, i + 1 );
+ } );
};
if ( $.isArray( script ) ) {
- nestedAddScript( script, markModuleReady, registry[module].async, 0 );
+ nestedAddScript( script, markModuleReady, 0 );
} else if ( $.isFunction( script ) ) {
// Pass jQuery twice so that the signature of the closure which wraps
// the script can bind both '$' and 'jQuery'.
mw.templates.set( module, registry[module].templates );
}
- if ( $.isReady || registry[module].async ) {
- // Make sure we don't run the scripts until all (potentially asynchronous)
- // stylesheet insertions have completed.
- ( function () {
- var pending = 0;
- checkCssHandles = function () {
- // cssHandlesRegistered ensures we don't take off too soon, e.g. when
- // one of the cssHandles is fired while we're still creating more handles.
- if ( cssHandlesRegistered && pending === 0 && runScript ) {
- runScript();
- runScript = undefined; // Revoke
+ // Make sure we don't run the scripts until all stylesheet insertions have completed.
+ ( function () {
+ var pending = 0;
+ checkCssHandles = function () {
+ // cssHandlesRegistered ensures we don't take off too soon, e.g. when
+ // one of the cssHandles is fired while we're still creating more handles.
+ if ( cssHandlesRegistered && pending === 0 && runScript ) {
+ runScript();
+ runScript = undefined; // Revoke
+ }
+ };
+ cssHandle = function () {
+ var check = checkCssHandles;
+ pending++;
+ return function () {
+ if ( check ) {
+ pending--;
+ check();
+ check = undefined; // Revoke
}
};
- cssHandle = function () {
- var check = checkCssHandles;
- pending++;
- return function () {
- if ( check ) {
- pending--;
- check();
- check = undefined; // Revoke
- }
- };
- };
- }() );
- } else {
- // We are in blocking mode, and so we can't afford to wait for CSS
- cssHandle = function () {};
- // Run immediately
- checkCssHandles = runScript;
- }
+ };
+ }() );
// Process styles (see also mw.loader.implement)
// * back-compat: { <media>: css }
* @param {string|string[]} dependencies Module name or array of string module names
* @param {Function} [ready] Callback to execute when all dependencies are ready
* @param {Function} [error] Callback to execute when any dependency fails
- * @param {boolean} [async=false] Whether to load modules asynchronously.
- * Ignored (and defaulted to `true`) if the document-ready event has already occurred.
*/
- function request( dependencies, ready, error, async ) {
+ function request( dependencies, ready, error ) {
// Allow calling by single module name
if ( typeof dependencies === 'string' ) {
dependencies = [dependencies];
return;
}
queue.push( module );
- if ( async ) {
- registry[module].async = true;
- }
}
} );
}
/**
- * Asynchronously append a script tag to the end of the body
- * that invokes load.php
+ * Load modules from load.php
* @private
* @param {Object} moduleMap Module map, see #buildModulesString
* @param {Object} currReqBase Object with other parameters (other than 'modules') to use in the request
* @param {string} sourceLoadScript URL of load.php
- * @param {boolean} async Whether to load modules asynchronously.
- * Ignored (and defaulted to `true`) if the document-ready event has already occurred.
*/
- function doRequest( moduleMap, currReqBase, sourceLoadScript, async ) {
+ function doRequest( moduleMap, currReqBase, sourceLoadScript ) {
var request = $.extend(
{ modules: buildModulesString( moduleMap ) },
currReqBase
);
request = sortQuery( request );
// Support: IE6
- // Append &* to satisfy load.php's WebRequest::checkUrlExtension test. This script
- // isn't actually used in IE6, but MediaWiki enforces it in general.
- addScript( sourceLoadScript + '?' + $.param( request ) + '&*', null, async );
+ // Append &* to satisfy load.php's WebRequest::checkUrlExtension test.
+ // This script isn't actually used in IE6, but MediaWiki enforces it in general.
+ addScript( sourceLoadScript + '?' + $.param( request ) + '&*' );
}
/**
var reqBase, splits, maxQueryLength, q, b, bSource, bGroup, bSourceGroup,
source, concatSource, origBatch, group, i, modules, sourceLoadScript,
currReqBase, currReqBaseLength, moduleMap, l,
- lastDotIndex, prefix, suffix, bytesAdded, async;
+ lastDotIndex, prefix, suffix, bytesAdded;
// Build a list of request parameters common to all requests.
reqBase = {
currReqBase.user = mw.config.get( 'wgUserName' );
}
currReqBaseLength = $.param( currReqBase ).length;
- async = true;
// We may need to split up the request to honor the query string length limit,
// so build it piece by piece.
l = currReqBaseLength + 9; // '&modules='.length == 9
if ( maxQueryLength > 0 && !$.isEmptyObject( moduleMap ) && l + bytesAdded > maxQueryLength ) {
// This request would become too long, create a new one
// and fire off the old one
- doRequest( moduleMap, currReqBase, sourceLoadScript, async );
+ doRequest( moduleMap, currReqBase, sourceLoadScript );
moduleMap = {};
- async = true;
l = currReqBaseLength + 9;
mw.track( 'resourceloader.splitRequest', { maxQueryLength: maxQueryLength } );
}
moduleMap[prefix] = [];
}
moduleMap[prefix].push( suffix );
- if ( !registry[modules[i]].async ) {
- // If this module is blocking, make the entire request blocking
- // This is slightly suboptimal, but in practice mixing of blocking
- // and async modules will only occur in debug mode.
- async = false;
- }
l += bytesAdded;
}
// If there's anything left in moduleMap, request that too
if ( !$.isEmptyObject( moduleMap ) ) {
- doRequest( moduleMap, currReqBase, sourceLoadScript, async );
+ doRequest( moduleMap, currReqBase, sourceLoadScript );
}
}
}
* @param {string} [type='text/javascript'] MIME type to use if calling with a URL of an
* external script or style; acceptable values are "text/css" and
* "text/javascript"; if no type is provided, text/javascript is assumed.
- * @param {boolean} [async] Whether to load modules asynchronously.
- * Ignored (and defaulted to `true`) if the document-ready event has already occurred.
- * Defaults to `true` if loading a URL, `false` otherwise.
*/
- load: function ( modules, type, async ) {
+ load: function ( modules, type ) {
var filtered, l;
// Validate input
// Allow calling with an external url or single dependency as a string
if ( typeof modules === 'string' ) {
if ( /^(https?:)?\/\//.test( modules ) ) {
- if ( async === undefined ) {
- // Assume async for bug 34542
- async = true;
- }
if ( type === 'text/css' ) {
// Support: IE 7-8
// Use properties instead of attributes as IE throws security
return;
}
if ( type === 'text/javascript' || type === undefined ) {
- addScript( modules, null, async );
+ addScript( modules );
return;
}
// Unknown type
return;
}
// Since some modules are not yet ready, queue up a request.
- request( filtered, undefined, undefined, async );
+ request( filtered, undefined, undefined );
},
/**
$CODE.registrations();
+ mw.config.set( $VARS.configuration );
+
+ // Must be after mw.config.set because these callbacks may use mw.loader which
+ // needs to have values 'skin', 'debug' etc. from mw.config.
window.RLQ = window.RLQ || [];
while ( RLQ.length ) {
RLQ.shift()();
fn();
}
};
-
- mw.config.set( $VARS.configuration );
}
// Conditional script injection
if ( isCompatible() ) {
- document.write( $VARS.baseModulesScript );
+ ( function () {
+ var script = document.createElement( 'script' );
+ script.src = $VARS.baseModulesUri;
+ document.getElementsByTagName( 'head' )[0].appendChild( script );
+ }() );
+} else {
+ // Undo class swapping in case of an unsupported browser.
+ // See OutputPage::getHeadScripts().
+ document.documentElement.className = document.documentElement.className
+ .replace( /(^|\s)client-js(\s|$)/, '$1client-nojs$2' );
}
|</noinclude>style="color:red;"||Bar
!! endarticle
+!! article
+Template:table_attribs_6
+!! text
+style="background: <nowiki>
+
+
+red;</nowiki>" |
+!! endarticle
+
+!! article
+Template:table_attribs_7
+!! text
+<noinclude>
+|</noinclude>style{{=}}"background:#f9f9f9;"|Foo<ref>foo</ref>
+!! endarticle
+
!! article
Template:table_header_cells
!! text
Non-word characters are valid in extension tags (T19663)
!! wikitext
<tåg>tåg</tåg>
-!! html
+!! html/php
<pre>
'tåg'
array (
!! test
Isolated close tags should be treated as literal text (bug 52760)
+!! options
+parsoid=wt2html
!! wikitext
</b>
<s.foo>s</s>
-!! html+tidy
+!! html/php+tidy
+<p><s.foo>s</p>
+!! html/parsoid
<p><s.foo>s</p>
!! end
<nowiki> unordered list
!! wikitext
<nowiki>* This is not an unordered list item.</nowiki>
-!! html
+!! html/php
<p>* This is not an unordered list item.
</p>
+!! html/parsoid
+<p><span typeof="mw:Nowiki">* This is not an unordered list item.</span></p>
!! end
!! test
:and a colon
</nowiki>
-!! html
+!! html/php
<p>Lorem ipsum dolor
sed abit.
:and a colon
</p>
+!! html/parsoid
+<p><span typeof="mw:Nowiki">Lorem ipsum dolor
+
+sed abit.
+ sed nullum.
+
+:and a colon
+</span></p>
!! end
!! test
*There is not nowiki.
*There is <nowiki>nowiki</nowiki>.
-!! html
+!! html/php
<dl><dd>There is not nowiki.</dd>
<dd>There is nowiki.</dd></dl>
<ol><li>There is not nowiki.</li>
<ul><li>There is not nowiki.</li>
<li>There is nowiki.</li></ul>
+!! html/parsoid
+<dl><dd data-parsoid='{}'>There is not nowiki.</dd>
+<dd data-parsoid='{}'>There is <span typeof="mw:Nowiki">nowiki</span>.</dd></dl>
+
+<ol><li data-parsoid='{}'>There is not nowiki.</li>
+<li data-parsoid='{}'>There is <span typeof="mw:Nowiki">nowiki</span>.</li></ol>
+
+<ul><li data-parsoid='{}'>There is not nowiki.</li>
+<li data-parsoid='{}'>There is <span typeof="mw:Nowiki">nowiki</span>.</li></ul>
!! end
!! test
!! html
<p>* </nowiki> tag</p>
!! wikitext
-<nowiki>* </nowiki></nowiki> tag
+<nowiki>*</nowiki> <nowiki></nowiki></nowiki> tag
!! end
!! test
</nowiki>
</pre>
-!! html
+!! html/php
<pre>
<nowiki>
</pre>
</pre>
</p>
+!! html/parsoid
+<pre data-parsoid='{"stx":"html","strippedNL":true}'><nowiki>
+</pre>
+<p><span typeof="mw:Placeholder" data-parsoid='{"src":"</nowiki>"}'></nowiki></span>
+</pre></p>
+
+<p><span typeof="mw:Nowiki">
+<pre>
+<nowiki>
+</pre>
+</span>
+</pre></p>
!! end
!! test
'' no-italic ''
[[ NoLink ]]
</pre>
-!! html
+!! html/php
<pre>
* foo
# bar
[[ NoLink ]]
</pre>
+!! html/parsoid
+<pre data-parsoid='{"stx":"html","strippedNL":true}'>* foo
+# bar
+= no-h =
+'' no-italic ''
+[[ NoLink ]]
+</pre>
!!end
###
</dl>
</dd>
</dl>
+!! html/parsoid
+<dl><dt>a</dt><dd data-parsoid='{"stx":"row"}'>b</dd>
+<dt><b>a:b</b></dt>
+<dt><i data-parsoid='{"stx":"html"}'>a:b</i></dt>
+<dt><span data-parsoid='{"stx":"html"}'>a:b</span></dt>
+<dt><div data-parsoid='{"stx":"html"}'>a:b</div></dt>
+<dt><div data-parsoid='{"stx":"html","autoInsertedEnd":true}'>a</div></dt>
+<dd>b</dd>
+<dt><span about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1","spc":["","","",""]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a:b"}},"i":0}}]}'>a:b</span></dt>
+<dt><i about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1","spc":["","","",""]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"''a:b''"}},"i":0}}]}'>a:b</i>
+<dl><dt><dl><dt><i>a:b</i></dt></dl></dt></dl></dt></dl>
!! end
!! test
</tbody></table>
!! end
+## Edge case fix to prevent future regressions
+!! test
+T107652: <ref>s in templates that also generate table cell attributes should be rendered properly
+!! wikitext
+{|
+|{{table_attribs_7}}
+|}
+<references />
+!! html/parsoid
+<table>
+<tbody><tr><td style="background:#f9f9f9;" typeof="mw:Transclusion" about="#mwt1" data-mw='{"parts":["|",{"template":{"target":{"wt":"table_attribs_7","href":"./Template:Table_attribs_7"},"params":{},"i":0}}]}'>Foo<span class="mw-ref" id="cite_ref-1" rel="dc:references" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></span></td></tr>
+</tbody></table>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
+!! end
+
!! test
Table with row followed by newlines and table heading
!! wikitext
<br title=bar/>
<br title=bar/ >
!! html/php
-<p><br title="title" />
-<br title="title" />
+<p><br title="" />
+<br title="" />
<br />
<br title="bar" />
<br title="bar" />
<meta property="mw:PageProp/noeditsection" data-parsoid='{"magicSrc":"__NOEDITSECTION__"}'/>
!! end
+!!test
+__proto__ is treated as normal wikitext (T105997)
+!!wikitext
+__proto__
+!!html
+<p>__proto__
+</p>
+!!end
+
###
### Magic links
###
msgnw keyword
!! wikitext
{{msgnw:MSGNW test}}
-!! html
+!! html/php
<p>''None'' of '''this''' should be
* interpreted
 but rather passed unmodified
</tbody></table>
!! end
+# T107622
+!! test
+4. Entities and nowikis inside templated attributes should be handled correctly inside templated tables
+!! wikitext
+{|
+| {{table_attribs_6}} hi
+|}
+!! html/php
+<table>
+<tr>
+<td style="background: red;"> hi
+</td></tr></table>
+
+!! html/parsoid
+<table>
+<tbody><tr><td style="background: red;" typeof="mw:Transclusion" about="#mwt1" data-parsoid='{"autoInsertedEnd":true,"pi":[[]]}' data-mw='{"parts":["| ",{"template":{"target":{"wt":"table_attribs_6","href":"./Template:Table_attribs_6"},"params":{},"i":0}}," hi"]}'> hi</td></tr>
+</tbody></table>
+!! end
+
!!test
Templates: HTML Tables: 1. Generating start of a HTML table
!! wikitext
!! test
pre-save transform: subst:
!! options
-PST
+pst
!! wikitext
{{subst:test}}
-!! html
+!! html/php
This is a test template
!! end
!! test
pre-save transform: normal template
!! options
-PST
+pst
!! wikitext
{{test}}
-!! html
+!! html/php
{{test}}
!! end
!! test
pre-save transform: nonexistent template
!! options
-PST
+pst
!! wikitext
{{thistemplatedoesnotexist}}
-!! html
+!! html/php
{{thistemplatedoesnotexist}}
!! end
-
!! test
pre-save transform: subst magic variables
!! options
-PST
+pst
!! wikitext
{{subst:SITENAME}}
-!! html
+!! html/php
MediaWiki
!! end
pst
!! wikitext
{{subst:paramtest|param="something else"}}
-!! html
+!! html/php
This is a test template with parameter "something else"
!! end
pst
!! wikitext
{{subst:nowikitest}}
-!! html
+!! html/php
<nowiki>'''not wiki'''</nowiki>
!! end
-
!! article
Template:commenttest
!! text
pst
!! wikitext
{{subst:commenttest}}
-!! html
+!! html/php
This template has <!-- a comment --> in it.
!! end
pst noxml
!! wikitext
<nowiki>'''not wiki'''
-!! html
+!! html/php
<nowiki>'''not wiki'''
!! end
pst noxml
!! wikitext
<NOwiki>'''not wiki'''</noWIKI>
-!! html
+!! html/php
<NOwiki>'''not wiki'''</noWIKI>
!! end
pst noxml
!! wikitext
wiki<nowiki>nowiki<!--nowiki</nowiki>wiki
-!! html
+!! html/php
wiki<nowiki>nowiki<!--nowiki</nowiki>wiki
!!end
pst
!! wikitext
<!-- <gallery>data</gallery> -->
-!! html
+!! html/php
<!-- <gallery>data</gallery> -->
!!end
pst
!! wikitext
<!-- <tag>data</tag> -->
-!! html
+!! html/php
<!-- <tag>data</tag> -->
!!end
pst
!! wikitext
<!-- <nowiki>data</nowiki> -->
-!! html
+!! html/php
<!-- <nowiki>data</nowiki> -->
!!end
pst
!! wikitext
{{subst:Includes}}
-!! html
+!! html/php
Foobar
!! end
pst
!! wikitext
{{subst:Includes2}}
-!! html
+!! html/php
Foo
!! end
pst
!! wikitext
{{subst:SafeSubstTest}}{{safesubst:SubstTest}}
-!! html
+!! html/php
FoobarFoobar
!! end
[[|Article (context)]]
[[Bar:X (Y) Z|]]
[[:Bar:X (Y) Z|]]
-!! html
+!! html/php
[[Article (context)|Article]]
[[Bar:Article|Article]]
[[:Bar:Article|Article]]
[[:interwiki:Article|]]
[[interwiki:Bar:Article|]]
[[:interwiki:Bar:Article|]]
-!! html
+!! html/php
[[interwiki:Article|Article]]
[[:interwiki:Article|Article]]
[[interwiki:Bar:Article|Bar:Article]]
pst title=[[Somearticle (context)]]
!! wikitext
[[|Article]]
-!! html
+!! html/php
[[Article (context)|Article]]
!! end
[[|Otherplace]]
[[Otherplace, Elsewhere|]]
[[Otherplace, Elsewhere, Anywhere|]]
-!! html
+!! html/php
[[Otherplace, Somewhere|Otherplace]]
[[Otherplace, Elsewhere|Otherplace]]
[[Otherplace, Elsewhere, Anywhere|Otherplace]]
!! wikitext
[[|Otherplace]]
[[Otherplace (place), Elsewhere|]]
-!! html
+!! html/php
[[Otherplace, Somewhere|Otherplace]]
[[Otherplace (place), Elsewhere|Otherplace]]
!! end
!! wikitext
[[|Yes, you.]]
[[Me, Myself, and I (1937 song)|]]
-!! html
+!! html/php
[[Yes, you. (context)|Yes, you.]]
[[Me, Myself, and I (1937 song)|Me, Myself, and I]]
!! end
pst title=[[Ns:Somearticle]]
!! wikitext
[[|Article]]
-!! html
+!! html/php
[[Ns:Article|Article]]
!! end
pst title=[[Ns:Somearticle (context)]]
!! wikitext
[[|Article]]
-!! html
+!! html/php
[[Ns:Article (context)|Article]]
!! end
pst title=[[Ns:Somearticle, Context, Whatever]]
!! wikitext
[[|Article]]
-!! html
+!! html/php
[[Ns:Article, Context, Whatever|Article]]
!! end
pst title=[[Ns:Somearticle, Context (context)]]
!! wikitext
[[|Article]]
-!! html
+!! html/php
[[Ns:Article (context)|Article]]
!! end
pst title=[[Ns:Somearticle (IGNORED), Context]]
!! wikitext
[[|Article]]
-!! html
+!! html/php
[[Ns:Article, Context|Article]]
!! end
[[|Article(context)]]
[[Bar:X(Y)Z|]]
[[:Bar:X(Y)Z|]]
-!! html
+!! html/php
[[Article(context)|Article]]
[[Bar:Article(context)|Article]]
[[:Bar:Article(context)|Article]]
[[|Article (context)]]
[[Bar:X (Y) Z|]]
[[:Bar:X (Y) Z|]]
-!! html
+!! html/php
[[Article (context)|Article]]
[[Bar:Article (context)|Article]]
[[:Bar:Article (context)|Article]]
[[|Article(context)]]
[[Bar:X(Y)Z|]]
[[:Bar:X(Y)Z|]]
-!! html
+!! html/php
[[Article(context)|Article]]
[[Bar:Article(context)|Article]]
[[:Bar:Article(context)|Article]]
[[Bar:Article (context),context|]]
[[:Bar:Article (context), context|]]
[[:Bar:Article (context),context|]]
-!! html
+!! html/php
[[Article (context), context|Article]]
[[Article (context),context|Article]]
[[Bar:Article (context), context|Article]]
-!! html
+!! html/php
Empty lines are trimmed
!! end
* <noinclude>~~~</noinclude>
* <includeonly>~~~</includeonly>
* <onlyinclude>~~~</onlyinclude>
-!! html
+!! html/php
* [[Special:Contributions/127.0.0.1|127.0.0.1]]
* <noinclude>[[Special:Contributions/127.0.0.1|127.0.0.1]]</noinclude>
* <includeonly>[[Special:Contributions/127.0.0.1|127.0.0.1]]</includeonly>
But not inside includeonly
<includeonly>{{subst:Foo}}</includeonly>
-!! html
+!! html/php
Shall not expand:
<nowiki>~~~~</nowiki>
</p>
!! end
+# Parsoid does not serialize to empty attribute syntax,
+# so wt2wt and html2wt cases are skipped
!! test
-Attribute test: no value
+Attribute test: no value (T54330)
+!! options
+parsoid=wt2html,html2html
!! wikitext
<font color>foo</font>
-!! html
-<p><font color="color">foo</font>
+!! html/php
+<p><font color="">foo</font>
</p>
+!! html/parsoid
+<p><font color="">foo</font></p>
!! end
!! test
Parser hook: empty input
!! wikitext
<tag></tag>
-!! html
+!! html/php
<pre>
''
array (
Parser hook: empty input using terminated empty elements
!! wikitext
<tag/>
-!! html
+!! html/php
<pre>
NULL
array (
Parser hook: empty input using terminated empty elements (space before)
!! wikitext
<tag />
-!! html
+!! html/php
<pre>
NULL
array (
Parser hook: basic input
!! wikitext
<tag>input</tag>
-!! html
+!! html/php
<pre>
'input'
array (
Parser hook: case insensitive
!! wikitext
<TAG>input</TAG>
-!! html
+!! html/php
<pre>
'input'
array (
Parser hook: case insensitive, redux
!! wikitext
<TaG>input</TAg>
-!! html
+!! html/php
<pre>
'input'
array (
noxml
!! wikitext
<tag><tag></tag></tag>
-!! html
+!! html/php
<pre>
'<tag>'
array (
Parser hook: basic arguments
!! wikitext
<tag width=200 height = "100" depth = '50' square></tag>
-!! html
+!! html/php
<pre>
''
array (
'width' => '200',
'height' => '100',
'depth' => '50',
- 'square' => 'square',
+ 'square' => '',
)
</pre>
Parser hook: argument containing a forward slash (bug 5344)
!! wikitext
<tag filename='/tmp/bla'></tag>
-!! html
+!! html/php
<pre>
''
array (
Parser hook: empty input using terminated empty elements (bug 2374)
!! wikitext
<tag foo=bar/>text
-!! html
+!! html/php
<pre>
NULL
array (
<tag width=200 height = "100" depth = '50' square/>
other stuff
</tag>
-!! html
+!! html/php
<pre>
NULL
array (
'width' => '200',
'height' => '100',
'depth' => '50',
- 'square' => 'square',
+ 'square' => '',
)
</pre>
<p>other stuff
!! wikitext
<statictag>hello, world</statictag>
<statictag action=flush/>
-!! html
+!! html/php
<p>hello, world
</p>
!! end
!! wikitext
<!-- <statictag>hello, world</statictag> -->
<statictag action=flush/>
-!! html
+!! html/php
<p><br />
</p>
!! end
!! test
Sanitizer: Closing of closed but not open tags
+!! options
+parsoid=wt2html
!! wikitext
</s>
-!! html
-<p></s>
-</p>
+!! html/php+tidy
+!! html/parsoid
!! end
!! test
Sanitizer: Closing of closed but not open table tags
+!! options
+parsoid=wt2html
!! wikitext
Table not started</td></tr></table>
-!! html
-<p>Table not started</td></tr></table>
-</p>
+!! html/php+tidy
+<p>Table not started</p>
+!! html/parsoid
+<p>Table not started</p>
!! end
!! test
<link rel="stylesheet" itemprop="hello" href="{{SERVER}}">
</div>
!! html
-<div itemscope="itemscope">
+<div itemscope="">
<p> <meta itemprop="hello" content="world" />
<meta http-equiv="refresh" content="5">
<meta itemprop="hello" content="5" />
===bc===
==c==
===ca===
-!! html
+!! html/php
start
!! end
===bc===
==c==
===ca===
-!! html
+!! html/php
==a==
===aa===
====aaa====
===bc===
==c==
===ca===
-!! html
+!! html/php
===aa===
====aaa====
!! end
===bc===
==c==
===ca===
-!! html
+!! html/php
====aaa====
!! end
===bc===
==c==
===ca===
-!! html
+!! html/php
==b==
===ba===
===bb===
===bc===
==c==
===ca===
-!! html
+!! html/php
===ba===
!! end
===bc===
==c==
===ca===
-!! html
+!! html/php
===bb===
====bba====
!! end
===bc===
==c==
===ca===
-!! html
+!! html/php
====bba====
!! end
===bc===
==c==
===ca===
-!! html
+!! html/php
===bc===
!! end
===bc===
==c==
===ca===
-!! html
+!! html/php
==c==
===ca===
!! end
===bc===
==c==
===ca===
-!! html
+!! html/php
===ca===
!! end
===bc===
==c==
===ca===
-!! html
+!! html/php
!! end
!! test
==a==
==bogus== not a legal section
==b==
-!! html
+!! html/php
==a==
==bogus== not a legal section
!! end
==a==
==bogus== not a legal section
==b==
-!! html
+!! html/php
==b==
!! end
==a==
==b== <!-- -->
==c==
-!! html
+!! html/php
==a==
!! end
==a==
==b== <!-- -->
==c==
-!! html
+!! html/php
==b== <!-- -->
!! end
==a==
==bogus== <nowiki>not a legal section</nowiki>
==b==
-!! html
+!! html/php
==a==
==bogus== <nowiki>not a legal section</nowiki>
!! end
==a==
==bogus== <nowiki>not a legal section</nowiki>
==b==
-!! html
+!! html/php
==b==
!! end
-
# Formerly testing for bug 2587, now resolved by the use of unmarked sections
# instead of respecting commented sections
!! test
!! wikitext
<!-- -->==sec1==
==sec2==
-!! html
+!! html/php
==sec2==
!!end
!! wikitext
<!-- -->==sec1==
==sec2==
-!! html
+!! html/php
!!end
-
# Formerly testing for bug 2607, now resolved by the use of unmarked sections
# instead of respecting HTML-style headings
!! test
one
==2==
two
-!! html
+!! html/php
==1==
one
!! end
one
==2==
two
-!! html
+!! html/php
==2==
two
!! end
!! wikitext
<noinclude>==unmarked==</noinclude>
==marked==
-!! html
+!! html/php
==marked==
!!end
=== <!--
--> <!-- -->
But just in case it doesn't...
-!! html
+!! html/php
=== <!--
--> <!-- -->
But just in case it doesn't...
===bc===
==c==
===ca===
-!! html
+!! html/php
xxx
==a==
===bc===
==c==
===ca===
-!! html
+!! html/php
start
xxx
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
xxx
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
Preformatted initial line
==a==
===a===
-!! html
+!! html/php
Preformatted initial line
==a==
xxx
!! wikitext
==a==
a
-!! html
+!! html/php
==a==
a
!! end
!! wikitext
==a==
a
-!! html
+!! html/php
==a==
a
!! end
== Section Two ==
stuff
-!! html
+!! html/php
== Section Two ==
stuff
!! end
== Section Two ==
stuff
-!! html
+!! html/php
== Section One ==
<pre>
=======
!! end
-
!! test
Handling of 
 in URLs
!! wikitext
MSGNW magic word
!! wikitext
{{MSGNW:msg}}
-!! html
+!! html/php
<p>[[:Template:Msg]]
</p>
!! end
wgRestrictDisplayTitle=false
!! wikitext
this is not the the title
-!! html
+!! html/php
Parser test
<p>this is not the the title
</p>
!! wikitext
this is not the the title
{{DISPLAYTITLE:whatever}}
-!! html
+!! html/php
whatever
<p>this is not the the title
</p>
!! wikitext
this is not the the title
{{DISPLAYTITLE:whatever}}
-!! html
+!! html/php
Screen
<p>this is not the the title
</p>
!! wikitext
this is not the the title
{{DISPLAYTITLE:screen}}
-!! html
+!! html/php
screen
<p>this is not the the title
</p>
!! wikitext
this is not the the title
{{DISPLAYTITLE:screen}}
-!! html
+!! html/php
Screen
<p>this is not the the title
<a href="/index.php?title=Template:DISPLAYTITLE:screen&action=edit&redlink=1" class="new" title="Template:DISPLAYTITLE:screen (page does not exist)">Template:DISPLAYTITLE:screen</a>
wgAllowDisplayTitle=false
!! wikitext
this is not the the title
-!! html
+!! html/php
Screen
<p>this is not the the title
</p>
!! wikitext
this is not the the title
{{DISPLAYTITLE:<span style="display: none;">s</span>creen}}
-!! html
+!! html/php
<span style="/* attempt to bypass $wgRestrictDisplayTitle */">s</span>creen
<p>this is not the the title
</p>
!! wikitext
this is not the the title
{{DISPLAYTITLE:<span style="color: red;">s</span>creen}}
-!! html
+!! html/php
<span style="color: red;">s</span>creen
<p>this is not the the title
</p>
showindicators
!! wikitext
<indicator name="empty" />
-<indicator name></indicator>
+<indicator name="name"></indicator>
!! html
empty=
name=
preload
!! wikitext
Hello <noinclude>cruel</noinclude><includeonly>kind</includeonly> world.
-!! html
+!! html/php
Hello kind world.
!! end
preload
!! wikitext
Goodbye <onlyinclude>Hello world</onlyinclude>
-!! html
+!! html/php
Hello world
!! end
preload
!! wikitext
<includeonly><</includeonly>includeonly>Hello world<includeonly><</includeonly>/includeonly>
-!! html
+!! html/php
<includeonly>Hello world</includeonly>
!! end
preload
!! wikitext
* <!-- Hello --> ''{{world}}'' {{<includeonly>subst:</includeonly>How are you}}{{ {{{|safesubst:}}} #if:1|2|3}}
-!! html
+!! html/php
* <!-- Hello --> ''{{world}}'' {{subst:How are you}}{{ {{{|safesubst:}}} #if:1|2|3}}
!! end
<small><figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a></figure></small>
!! end
+!! test
+3. Bad treebuilder fixup of formatting elt is cleaned up
+!! options
+parsoid=wt2html,wt2wt
+!! wikitext
+<small>'''foo[[File:Foobar.jpg|thumb|caption]]bar'''</small>
+!! html/parsoid
+<p><small><b>foo</b></small></p>
+<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><small><b>caption</b></small></figcaption></figure>
+<p><small><b>bar</b></small></p>
+!! end
+
+!! test
+4. Bad treebuilder fixup of formatting elt is cleaned up: formatting tags around captionless images are ignored
+!! options
+parsoid=wt2html,wt2wt
+!! wikitext
+'''<small>[[Image:Foobar.jpg|right|300px]]</small>'''
+!! html/parsoid
+<p><b><small></small></b></p>
+<figure class="mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a></figure>
+<p></p>
+!! end
+
#### ----------------------------------------------------------------
#### Parsoid-only testing of Parsoid's impl of <ref> and <references>
#### tags. Parsoid's output for these tags differs from that of the
!! test
Headings: 6a. Heading chars in SOL context (with trailing spaces)
-!! options
-parsoid
!! wikitext
<nowiki>=a=</nowiki>
<nowiki>=a=</nowiki>
<nowiki>=a=</nowiki>
-!! html
-<p>=a=</p>
-<p>=a= </p>
-<p>=a= </p>
-<p>=a= </p>
+!! html/php
+<p>=a=
+</p><p>=a=
+</p><p>=a=
+</p><p>=a=
+</p>
+!! html/parsoid
+<p><span typeof="mw:Nowiki">=a=</span></p>
+
+<p><span typeof="mw:Nowiki">=a=</span></p>
+
+<p><span typeof="mw:Nowiki">=a=</span></p>
+
+<p><span typeof="mw:Nowiki">=a=</span></p>
!!end
!! test
Headings: 6b. Heading chars in SOL context (with trailing newlines)
-!! options
-parsoid
!! wikitext
<nowiki>=a=
b</nowiki>
<nowiki>=a=
b</nowiki>
-!! html
+!! html/php
<p>=a=
-b</p>
-<p>=a=
-b</p>
-<p>=a=
-b</p>
-<p>=a=
-b</p>
+b
+</p><p>=a=
+b
+</p><p>=a=
+b
+</p><p>=a=
+b
</p>
+!! html/parsoid
+<p><span typeof="mw:Nowiki">=a=
+b</span></p>
+
+<p><span typeof="mw:Nowiki">=a=
+b</span></p>
+
+<p><span typeof="mw:Nowiki">=a=
+b</span></p>
+
+<p><span typeof="mw:Nowiki">=a=
+b</span></p>
!!end
!! test
Headings: 6c. Heading chars in SOL context (leading newline break)
-!! options
-parsoid
!! wikitext
a
<nowiki>=b=</nowiki>
-!! html
+!! html/php
<p>a
-=b=</p>
+=b=
+</p>
+!! html/parsoid
+<p>a
+<span typeof="mw:Nowiki">=b=</span>
!!end
!! test
Headings: 6d. Heading chars in SOL context (with interspersed comments)
-!! options
-parsoid
!! wikitext
<!--c0--><nowiki>=a=</nowiki>
<!--c1--><nowiki>=a=</nowiki> <!--c2--> <!--c3-->
-!! html
-<p><!--c0-->=a=</p>
-<p><!--c1-->=a= <!--c2--> <!--c3--></p>
+!! html/php
+<p>=a=
+</p><p>=a=
+</p>
+!! html/parsoid
+<!--c0--><p><span typeof="mw:Nowiki">=a=</span></p>
+
+<!--c1--><p><span typeof="mw:Nowiki">=a=</span></p> <!--c2--> <!--c3-->
!!end
!! test
Headings: 6d. Heading chars in SOL context (No escaping needed)
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
=a=<div>b</div>
!! wikitext
=a=<div>b</div>
Headings: 7. Insert a newline between new content and headings
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<h2>NEW</h2>
<p>new</p>
-<h2 data-parsoid='{"dsr":[0,5,2,2]}'>A</h2>
-<p data-parsoid='{"dsr":[6,7,0,0]}'>a</p>
+<h2 data-parsoid='{}'>A</h2>
+<p data-parsoid='{}'>a</p>
!! wikitext
== NEW ==
new
<nowiki>#</nowiki>foo
<nowiki>;Foo:</nowiki>bar
-!! html
+!! html/php
<p>*foo
</p><p>#foo
</p><p>;Foo:bar
</p>
+!! html/parsoid
+<p><span typeof="mw:Nowiki">*</span>foo</p>
+
+<p><span typeof="mw:Nowiki">#</span>foo</p>
+
+<p><span typeof="mw:Nowiki">;Foo:</span>bar</p>
!!end
!! test
!!test
Encapsulate protected attributes from wt
!! wikitext
-<div typeof="mw:placeholder stuff" data-parsoid="weird" data-parsoid-other="no" about="time" rel="mw:true">foo</div>
+<div typeof="mw:placeholder stuff" data-mw="whoo" data-parsoid="weird" data-parsoid-other="no" about="time" rel="mw:true">foo</div>
!! html/parsoid
-<body><div data-x-typeof="mw:placeholder stuff" data-x-data-parsoid="weird" data-x-data-parsoid-other="no" data-x-about="time" data-x-rel="mw:true">foo</div>
+<body><div data-x-typeof="mw:placeholder stuff" data-x-data-mw="whoo" data-x-data-parsoid="weird" data-x-data-parsoid-other="no" data-x-about="time" data-x-rel="mw:true">foo</div>
</body>
!!end
!! end
!! test
-Headings: Force sol-transparent links and behavior switches to serialize before/after
+1. Headings: Force sol-transparent links and behavior switches to serialize before/after
!! options
-parsoid=html2wt
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": false
+}
+!! html
+<h2>hello there<link href="Category:A1" rel="mw:PageProp/Category" /></h2>
+<h2><link href="Category:A2" rel="mw:PageProp/Category" />hi pal</h2>
+
+<h2><!--foo--> <link href="Category:A3" rel="mw:PageProp/Category" /> how goes it</h2>
+<h2>it goes well <link href="Category:A4" rel="mw:PageProp/Category" /> <!--bar--></h2>
+
+<h2 data-parsoid='{}'>howdy<link href="Category:A5" rel="mw:PageProp/Category" /></h2>
+
+<h2><meta property="mw:PageProp/toc" /> ok</h2>
+!! wikitext
+== hello there [[Category:A1]] ==
+
+== [[Category:A2]] hi pal ==
+
+== <!--foo--> [[Category:A3]] how goes it ==
+
+== it goes well [[Category:A4]] <!--bar--> ==
+
+==howdy [[Category:A5]] ==
+
+== __TOC__ ok ==
+!! end
+
+!! test
+2. Headings: Force sol-transparent links and behavior switches to serialize before/after
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
!! html
<h2>hello there<link href="Category:A1" rel="mw:PageProp/Category" /></h2>
<h2><link href="Category:A2" rel="mw:PageProp/Category" />hi pal</h2>
!! test
Headings: Don't hoist metas that come from templates
!! options
-parsoid=html2wt
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
!! html
<h2><span about="#mwt1" typeof="mw:Transclusion" data-parsoid="{}" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo [[Category:Foo]]"}},"i":0}}]}'>foo </span><link rel="mw:PageProp/Category" href="./Category:Foo" about="#mwt1" data-parsoid="{}" /></h2>
!! wikitext
!! test
Headings: Category in ref isn't hoisted
!! options
-parsoid=html2wt
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
!! html
<h2> foo <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span> </h2>
baz</li>
<li>foo <b>bar</b>
baz</li></ul>
+
+<dl><dt>hi
+ho </dt><dd data-parsoid='{"stx":"row"}'> hi
+ho</dd></dl>
+
+<dl><dd> <table>
+<tbody><tr><td> ha
+ha
+ha</td></tr>
+</tbody></table></dd></dl>
!! wikitext
== testing 123 ==
* foo bar baz
* foo '''bar''' baz
+
+; hi ho : hi ho
+
+: {|
+| ha
+ha
+ha
+|}
!! end
!! test
x<nowiki/>http://cscott.net<nowiki/>x
!! end
+!! test
+WTS of edited autolink-like text (T103364)
+!! options
+parsoid={
+ "modes": ["wt2wt"],
+ "changes": [
+ [ "span[typeof]", "removeAttr", "typeof" ]
+ ]
+}
+!! wikitext
+Not a link: <nowiki>http://example.com</nowiki>.
+!! wikitext/edited
+Not a link: <span><nowiki>http://example.com</nowiki></span>.
+!! end
+
+!! test
+WTS of newly-authored autolink-like text (T103364)
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p>http://example.com is not a link.</p>
+!! wikitext
+<nowiki>http://example.com is not a link.</nowiki>
+!! end
+
!! test
Edited Redirect link should emit a non-piped wikitext link
!! options
!! end
!! test
-Headings: Add space before/after == (T53744)
+1. Headings: Add space before/after == (T53744)
!! options
parsoid=html2wt
!! html
<h2> bar</h2>
<h2>baz </h2>
<h2><span> baz</span></h2>
-
-<!-- Even after hoisted content -->
-<h2> <link href="Category:A2" rel="mw:PageProp/Category" />ok</h2>
!! wikitext
== foo ==
== baz ==
== <span> baz</span> ==
+!! end
-<!-- Even after hoisted content -->
+!! test
+2. Headings: Add space before/after == even after hoisted content
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html
+<h2> <link href="Category:A2" rel="mw:PageProp/Category" />ok</h2>
+!! wikitext
[[Category:A2]]
== ok ==
}
!! html
<p> hi</p>
+<p> hello</p>
!! wikitext
hi
+
+hello
!! end
!! test
parsoid=html2wt
!! html
<p> hi</p>
+<p> hello</p>
!! wikitext
<nowiki> </nowiki>hi
+
+<nowiki> </nowiki> hello
+!! end
+
+!! test
+3. Indent Pre Nowiki: suppress whitespace after newlines in new paragraph or table cell
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html/parsoid
+<p>Foo
+ bar
+baz</p>
+
+<table><tr><td>Foo
+ bar
+ baz bang</td></tr></table>
+
+<p><!--boo--> foo
+ bar</p>
+
+<p> foo
+ bar<span>boo</span></p>
+!! wikitext
+Foo
+bar
+baz
+
+{|
+|Foo
+bar
+baz bang
+|}
+
+<!--boo-->foo
+bar
+
+foo
+bar<span>boo</span>
+!! end
+
+!! test
+1. New links that end in spaces
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": false
+}
+!! html
+<p><a rel="mw:WikiLink" href="./Berlin" title="Berlin">Berlin </a>is the capital of Germany.</p>
+<p><a rel="mw:WikiLink" href="./Foo" title="Foo">Foo </a><b>bar</b></p>
+!! wikitext
+[[Berlin ]]<nowiki/>is the capital of Germany.
+
+[[Foo ]]'''bar'''
+!! end
+
+!! test
+2. New links that end in spaces
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html
+<p><a rel="mw:WikiLink" href="./Berlin" title="Berlin">Berlin </a>is the capital of Germany.</p>
+<p><a rel="mw:WikiLink" href="./Foo" title="Foo">Foo </a><b>bar</b></p>
+!! wikitext
+[[Berlin]] is the capital of Germany.
+
+[[Foo]] '''bar'''
+!! end
+
+!! test
+3. Existing links that end in spaces
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html
+<p><a rel="mw:WikiLink" href="./Berlin" title="Berlin" data-parsoid='{"stx":"simple","a":{"href":"./Berlin"},"sa":{"href":"Berlin "}}'>Berlin </a>is the capital of Germany.</p>
+
+<p><a rel="mw:WikiLink" href="./Foo" title="Foo" data-parsoid='{"stx":"simple","a":{"href":"./Foo"},"sa":{"href":"Foo "}}'>Foo </a><b>bar</b></p>
+!! wikitext
+[[Berlin ]]<nowiki/>is the capital of Germany.
+
+[[Foo ]]'''bar'''
!! end
# ---------------------------------------------------
array(
array( 'test.foo', ResourceLoaderModule::TYPE_SCRIPTS ),
"<script>var RLQ = RLQ || []; RLQ.push( function () {\n"
- . 'document.write("\u003Cscript src=\"http://127.0.0.1:8080/w/load.php?'
- . 'debug=false\u0026amp;lang=en\u0026amp;modules=test.foo\u0026amp;only'
- . '=scripts\u0026amp;skin=fallback\u0026amp;*\"\u003E\u003C/script\u003E");'
+ . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.foo\u0026only=scripts\u0026skin=fallback\u0026*");'
. "\n} );</script>"
),
array(
// Don't condition wrap raw modules (like the startup module)
array( 'test.raw', ResourceLoaderModule::TYPE_SCRIPTS ),
- '<script src="http://127.0.0.1:8080/w/load.php?debug=false&lang=en&modules=test.raw&only=scripts&skin=fallback&*"></script>'
+ '<script async src="http://127.0.0.1:8080/w/load.php?debug=false&lang=en&modules=test.raw&only=scripts&skin=fallback&*"></script>'
),
// Load module styles only
// This also tests the order the modules are put into the url
array(
array( array( 'test.group.foo', 'test.group.bar' ), ResourceLoaderModule::TYPE_COMBINED ),
"<script>var RLQ = RLQ || []; RLQ.push( function () {\n"
- . 'document.write("\u003Cscript src=\"http://127.0.0.1:8080/w/load.php?debug=false\u0026amp;lang=en\u0026amp;modules=test.group.bar\u0026amp;skin=fallback\u0026amp;*\"\u003E\u003C/script\u003E");'
+ . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.group.bar\u0026skin=fallback\u0026*");'
. "\n} );</script>\n"
. "<script>var RLQ = RLQ || []; RLQ.push( function () {\n"
- . 'document.write("\u003Cscript src=\"http://127.0.0.1:8080/w/load.php?debug=false\u0026amp;lang=en\u0026amp;modules=test.group.foo\u0026amp;skin=fallback\u0026amp;*\"\u003E\u003C/script\u003E");'
+ . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.group.foo\u0026skin=fallback\u0026*");'
. "\n} );</script>"
),
);
--- /dev/null
+<?php
+
+use Liuggio\StatsdClient\Entity\StatsdData;
+
+class SamplingStatsdClientTest extends PHPUnit_Framework_TestCase {
+ /**
+ * @dataProvider samplingDataProvider
+ */
+ public function testSampling( $data, $sampleRate, $seed, $expectWrite ) {
+ $sender = $this->getMock( 'Liuggio\StatsdClient\Sender\SenderInterface' );
+ $sender->expects( $this->any() )->method( 'open' )->will( $this->returnValue( true ) );
+ if ( $expectWrite ) {
+ $sender->expects( $this->once() )->method( 'write' )
+ ->with( $this->anything(), $this->equalTo( $data ) );
+ } else {
+ $sender->expects( $this->never() )->method( 'write' );
+ }
+ mt_srand( $seed );
+ $client = new SamplingStatsdClient( $sender );
+ $client->send( $data, $sampleRate );
+ }
+
+ public function samplingDataProvider() {
+ $unsampled = new StatsdData();
+ $unsampled->setKey( 'foo' );
+ $unsampled->setValue( 1 );
+
+ $sampled = new StatsdData();
+ $sampled->setKey( 'foo' );
+ $sampled->setValue( 1 );
+ $sampled->setSampleRate( '0.1' );
+
+ return array(
+ // $data, $sampleRate, $seed, $expectWrite
+ array( $unsampled, 1, 0 /*0.44*/, $unsampled ),
+ array( $sampled, 1, 0 /*0.44*/, null ),
+ array( $sampled, 1, 4 /*0.03*/, $sampled ),
+ array( $unsampled, 0.1, 4 /*0.03*/, $sampled ),
+ array( $sampled, 0.5, 0 /*0.44*/, null ),
+ array( $sampled, 0.5, 4 /*0.03*/, $sampled ),
+ );
+ }
+}