"extends": "wikimedia",
"env": {
"browser": true,
- "jquery": true,
- "qunit": true
+ "jquery": true
},
"globals": {
"require": false,
"rules": {
"declaration-no-important": null,
- "indentation": null,
-
"no-descending-specificity": null,
- "selector-list-comma-newline-after": null,
"selector-no-id": null,
"selector-pseudo-element-colon-notation": null,
# complement that setup by testing MediaWiki on travis
#
language: php
+# Using HHVM-3.6+ requires Trusty (Travis default: precise)
+# https://docs.travis-ci.com/user/languages/php#HHVM-versions
+# https://github.com/travis-ci/travis-ci/issues/7368
+sudo: required
+group: edge
+dist: trusty
matrix:
fast_finish: true
- env: dbtype=postgres
php: 5.5
- env: dbtype=mysql
- php: hhvm
+ php: hhvm-3.12
- env: dbtype=mysql
php: 7
--pass travis
--dbtype "$dbtype"
--dbname traviswiki
- --dbuser travis
+ --dbuser root
--dbpass ""
--scriptpath "/w"
all: [
'**/*.js',
'!docs/**',
- '!tests/**',
'!node_modules/**',
'!resources/lib/**',
'!resources/src/jquery.tipsy/**',
'!resources/src/jquery/jquery.farbtastic.js',
'!resources/src/mediawiki.libs/**',
+ // Third-party code of PHPUnit coverage report
+ '!tests/coverage/**',
'!vendor/**',
// Explicitly say "**/*.js" here in case of symlinks
'!extensions/**/*.js',
* Updated QUnit from v1.22.0 to v1.23.1.
* Updated cssjanus from v1.1.2 to 1.1.3.
* Updated psr/log from v1.0.0 to v1.0.2.
+* Update Moment.js from v2.8.4 to v2.15.0.
==== New external libraries ====
$revision = $this->mArticle->getRevisionFetched();
if ( $revision === null ) {
if ( !$this->contentModel ) {
- $this->contentModel = $this->getTitle()->getContentModel();
+ throw new RuntimeException( 'EditPage contentModel was false' );
}
$handler = ContentHandler::getForModelID( $this->contentModel );
if ( $content === false || $content === null ) {
if ( !$this->contentModel ) {
- $this->contentModel = $this->getTitle()->getContentModel();
+ throw new RuntimeException( 'EditPage contentModel was false' );
}
$handler = ContentHandler::getForModelID( $this->contentModel );
* - confirm-rollback-button
* - rollbackfailed
* - rollback-missingparam
+ * - rollback-success-notify
*/
/**
$old = Linker::revUserTools( $current );
$new = Linker::revUserTools( $target );
- $this->getOutput()->addHTML( $this->msg( 'rollback-success' )->rawParams( $old, $new )
- ->parseAsBlock() );
+ $this->getOutput()->addHTML(
+ $this->msg( 'rollback-success' )
+ ->rawParams( $old, $new )
+ ->params( $current->getUserText( Revision::FOR_THIS_USER, $user ) )
+ ->params( $target->getUserText( Revision::FOR_THIS_USER, $user ) )
+ ->parseAsBlock()
+ );
if ( $user->getBoolOption( 'watchrollback' ) ) {
$user->addWatch( $this->page->getTitle(), User::IGNORE_USER_RIGHTS );
"apierror-reauthenticate": "Non se autentificou recentemente nesta sesión. Por favor, volva a autentificarse.",
"apierror-revwrongpage": "r$1 non é unha revisión de $2.",
"apierror-searchdisabled": "A busca <var>$1</var> está desactivada.",
+ "apierror-sectionreplacefailed": "Non se puido combinar a sección actualizada.",
+ "apierror-sectionsnotsupported": "As seccións non son compatibles co modelo de contido $1.",
"apierror-sectionsnotsupported-what": "As seccións non son compatibles con $1.",
"apierror-show": "Parámetro incorrecto - non se poden proporcionar valores mutuamente excluíntes.",
+ "apierror-siteinfo-includealldenied": "Non se pode ver a información de tódolos servidores a menos que <var>$wgShowHostNames</var> teña valor verdadeiro.",
"apierror-sizediffdisabled": "A diferenza de tamaño está deshabilitada no modo Miser.",
"apierror-spamdetected": "A súa edición foi rexeitada por conter un fragmento de publicidade: <code>$1</code>.",
"apierror-specialpage-cantexecute": "Non ten permiso para ver os resultados desta páxina especial.",
"apierror-unknownformat": "Formato descoñecido \"$1\".",
"apierror-unrecognizedparams": "{{PLURAL:$2|Parámetro non recoñecido|Parámetros non recoñecidos}}: $1.",
"apierror-unrecognizedvalue": "Valor non recoñecido para o parámetro <var>$1</var>: $2.",
+ "apierror-urlparamnormal": "Non se puideron normalizar os parámetros de imaxe de $1.",
+ "apierror-writeapidenied": "Non ten permiso para editar este wiki a través da API.",
+ "apiwarn-alldeletedrevisions-performance": "Para ter un mellor rendemento á hora de xerar títulos, estableza <kbd>$1dir=newer</kbd>.",
+ "apiwarn-badurlparam": "Non se puido analizar <var>$1urlparam</var> para $2. Só se usará a anchura e a altura.",
"apiwarn-deprecation-httpsexpected": "Utilizouse HTTP cando esperábase HTTPS.",
"apiwarn-deprecation-parameter": "O parámetro <var>$1</var> está obsoleto.",
"apiwarn-invalidcategory": "\"$1\" non é unha categoría.",
"apierror-upload-filekeyneeded": "חובה לספק <var>filekey</var> כאשר <var>offset</var> אינו אפס.",
"apierror-upload-filekeynotallowed": "לא ניתן לספק <var>filekey</var> כאשר <var>offset</var> הוא 0.",
"apierror-upload-missingresult": "אין תוצאות בנתוני מצב.",
+ "apierror-writeapidenied": "אין לך הרשאה לערוך את הוויקי הזה דרך ה־API.",
+ "apiwarn-alldeletedrevisions-performance": "לביצועים טובים יותר בעת יצירת כותרת, יש להשתמש ב־<kbd>$1dir=newer</kbd>.",
+ "apiwarn-badurlparam": "לא היה אפשר לפענח את <var>$1urlparam</var> עבור $2. משתמשים רק ב־width ו־height.",
+ "apiwarn-badutf8": "הערך הערך שהועבר ל־<var>$1</var> מכיל נתונים בלתי־תקינים או בלתי־מנורמלים. נתונים טקסט אמורים להיות תקינים, מנורמלי NFC ללא תווי בקרה C0 למעט HT (\\t), LF (\\n), ו־CR (\\r).",
+ "apiwarn-checktoken-percentencoding": "נא לבדוק שסימנים כמו \"+\" באסימון מקודדים עם אחוזים בצורה נכונה ב־URL.",
+ "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd> הוצהר בתור מיושן. נא להשתמש ב־ <kbd>prop=deletedrevisions</kbd> או ב־<kbd>list=alldeletedrevisions</kbd> במקום זה.",
+ "apiwarn-deprecation-expandtemplates-prop": "מכיוון שלא ניתנו ערכים לפרמטר <var>prop</var>, תסדיר מיושן ישמש לפלט. התסדיר הזה מיושן, ובעתיד יינתן ערך בררת מחדל לפרמטר <var>prop</var>, כך שתמיד ישמש התסדיר החדש.",
+ "apiwarn-deprecation-httpsexpected": "משמש HTTP כשהיה צפוי HTTPS.",
+ "apiwarn-deprecation-login-botpw": "כניסה לחשבון עיקרי (main-account) דרך <kbd>action=login</kbd> מיושנת ועלולה להפסיק לעבוד ללא אזהרה נוספת. כדי להמשיך להיכנס עם <kbd>action=login</kbd>, ר' [[Special:BotPasswords]]. כדי להמשיך באופן מאובטח באמצעות חשבון עיקרי, ר' <kbd>action=clientlogin</kbd>.",
+ "apiwarn-deprecation-login-token": "אחזור אסימון דרך <kbd>action=login</kbd> מיושן. נא להשתמש ב־<kbd>action=query&meta=tokens&type=login</kbd> במקום זה.",
+ "apiwarn-deprecation-parameter": "הפרמטר <var>$1</var> מיושן.",
+ "apiwarn-deprecation-parse-headitems": "<kbd>prop=headitems</kbd> מיושן מאז מדיה־ויקי 1.28. יש להשתמש ב־<kbd>prop=headhtml</kbd> בעת יצירת מסמכי HTML חדשים, או ב־<kbd>prop=modules|jsconfigvars</kbd> בעת עדכון מסמך בצד הלקוח.",
+ "apiwarn-deprecation-purge-get": "שימוש ב־<kbd>action=purge</kbd> דרך GET מיושן. יש להשתמש ב־POST במקום זה.",
+ "apiwarn-deprecation-withreplacement": "<kbd>$1</kbd> מיושן. יש להשתמש ב־<kbd>$2</kbd> במקום זה.",
+ "apiwarn-difftohidden": "לא היה אפשר לעשות השוואה עם גרסה $1: התוכן מוסתר.",
+ "apiwarn-errorprinterfailed": "מדפיס השגיאות לא עבד. ינסה שוב ללא פרמטרים.",
+ "apiwarn-errorprinterfailed-ex": "מדפיס השגיאות לא עבד (ינסה שוב ללא פרמטרים): $1",
"apiwarn-invalidcategory": "\"$1\" אינה קטגוריה.",
"apiwarn-invalidtitle": "\"$1\" אינה כותרת תקינה.",
+ "apiwarn-invalidxmlstylesheetext": "לגיליון הסגנונות אמור להיות הסיומת <code dir=\"ltr\">.xsl</code>.",
+ "apiwarn-invalidxmlstylesheet": "ניתן גיליון סגנונות שאינו תקין או אינו קיים.",
+ "apiwarn-invalidxmlstylesheetns": "גיליון הסגנונות אמור להיות במרחב השם {{ns:MediaWiki}}.",
+ "apiwarn-moduleswithoutvars": "המאפיין <kbd>modules</kbd> לא הוגדר, אבל לא <kbd>jsconfigvars</kbd> או <kbd>encodedjsconfigvars</kbd>. משתני הגדרות נחוצים בשביל שימוש נכון במודולים.",
"apiwarn-notfile": "\"$1\" אינו קובץ.",
+ "apiwarn-nothumb-noimagehandler": "לא היה אפשר ליצור תמונה ממוזערת כי לקובץ $1 לא משויך מטפל תמונה.",
+ "apiwarn-parse-nocontentmodel": "לא ניתן <var>title</var> או <var>contentmodel</var>, נניח שזה $1.",
+ "apiwarn-parse-titlewithouttext": "<var>title</var> שימש ללא <var>text</var>, והתבקשו מאפייני דף מפוענח. האם התכוונת להשתמש ב־<var>page</var> במקום <var>title</var>?",
+ "apiwarn-redirectsandrevids": "פתרון הפניות לא יכול לשמש יחד עם הפרמטר <var>revids</var>. הפניות ש־<var>revids</var> מצביע אליהן לא נפתרו.",
"apiwarn-tokennotallowed": "הפעולה \"$1\" אינה מותרת למשתמש הנוכחי.",
"apiwarn-tokens-origin": "לא ניתן לקבל אסימונים כשמדיניות המקור הזהה אינה חלה.",
"apiwarn-toomanyvalues": "יותר מדי ערכים סופקו לפרמטר <var>$1</var>: המגבלה היא $2.",
"apiwarn-deprecation-parse-headitems": "{{doc-apierror}}",
"apiwarn-deprecation-purge-get": "{{doc-apierror}}",
"apiwarn-deprecation-withreplacement": "{{doc-apierror}}\n\nParameters:\n* $1 - Query string fragment that is deprecated, e.g. \"action=tokens\".\n* $2 - Query string fragment to use instead, e.g. \"action=tokens\".",
- "apiwarn-difftohidden": "{{doc-apierror}}\n\nParameters:\n* $1 - Revision ID number.",
+ "apiwarn-difftohidden": "{{doc-apierror}}\n\nParameters:\n* $1 - Revision ID number.\n\n\"r\" is short for \"revision\". You may translate it.",
"apiwarn-errorprinterfailed": "{{doc-apierror}}",
"apiwarn-errorprinterfailed-ex": "{{doc-apierror}}\n\nParameters:\n* $1 - Exception message, which may already end in punctuation. Probably in English.",
"apiwarn-invalidcategory": "{{doc-apierror}}\n\nParameters:\n* $1 - Supplied category name.",
return new CollationFa;
default:
$match = [];
- if ( preg_match( '/^uca-([a-z@=-]+)$/', $collationName, $match ) ) {
+ if ( preg_match( '/^uca-([A-Za-z@=-]+)$/', $collationName, $match ) ) {
return new IcuCollation( $match[1] );
}
"config-apc": "[http://www.php.net/apc APC] е инсталиран",
"config-apcu": "[http://www.php.net/apc APC] е инсталиран",
"config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] е инсталиран",
+ "config-no-cache-apcu": "<strong>Внимание:</strong> [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] и [http://www.iis.net/download/WinCacheForPhp WinCache] не могат да бъдат открити.\nКеширането на обекти не е активирано.",
"config-mod-security": "<strong>Предупреждение:</strong> [http://modsecurity.org/ mod_security]/mod_security2 е включено на вашия уеб сървър. Много от обичайните му конфигурации пораждат проблеми с МедияУики и друг софтуер, който позволява публикуване на произволно съдържание.\nАко е възможно, моля изключете го. В противен случай се обърнете към [http://modsecurity.org/documentation/ документацията на mod_security] или се свържете с поддръжката на хостинга си, ако се сблъскате със случайни грешки.",
"config-diff3-bad": "GNU diff3 не беше намерен.",
"config-git": "Налична е системата за контрол на версиите Git: <code>$1</code>.",
"config-db-host": "Хост на базата от данни:",
"config-db-host-help": "Ако базата от данни е на друг сървър, в кутията се въвежда името на хоста или IP адреса.\n\nАко се използва споделен уеб хостинг, доставчикът на услугата би трябвало да е предоставил в документацията си коректния хост.\n\nАко инсталацията протича на Windows-сървър и се използва MySQL, използването на \"localhost\" може да е неприемливо. В такива случаи се използва \"127.0.0.1\" за локален IP адрес.\n\nПри използване на PostgreSQL, това поле се оставя празно, за свързване чрез Unix socket.",
"config-db-host-oracle": "TNS на базата данни:",
+ "config-db-host-oracle-help": "Въведете валидно [http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm Local Connect Name]; файлът tnsnames.ora трябва да бъде видим за инсталацията.<br />Ако използвате клиентска библиотека версия 10g или по-нова можете да използвате метода [http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.htm Easy Connect].",
"config-db-wiki-settings": "Идентифициране на това уики",
"config-db-name": "Име на базата от данни:",
"config-db-name-help": "Избира се име, което да идентифицира уикито.\nТо не трябва да съдържа интервали.\n\nАко се използва споделен хостинг, доставчикът на услугата би трябвало да е предоставил или име на базата от данни, която да бъде използвана, или да позволява създаването на бази от данни чрез контролния панел.",
"config-mysql-innodb": "InnoDB",
"config-mysql-myisam": "MyISAM",
"config-mysql-myisam-dep": "'''Предупреждение''': Избрана е MyISAM като система за складиране в MySQL, която не се препоръчва за използване с МедияУики, защото:\n* почти не поддържа паралелност заради заключване на таблиците\n* е по-податлива на повреди в сравнение с други системи\n* кодът на МедияУики не винаги поддържа MyISAM коректно\n\nАко инсталацията на MySQL поддържа InnoDB, силно е препоръчително да се използва тя.\nАко инсталацията на MySQL не поддържа InnoDB, вероятно е време за обновяване.",
+ "config-mysql-only-myisam-dep": "<strong>Внимание:</strong> MyISAM e единственият наличен на тази машина тип на таблиците за MySQL и не е препоръчителен за употреба при МедияУики защото:\n* има слаба поддръжка на конкурентност на заявките, поради закючването на таблиците\n* е много по-податлив на грешки в базите от данни от другите типове таблици\n* кодът на МедияУики не винаги работи с MyISAM както трябва\n\nВашият MySQL не поддържа InnoDB, така че може би е дошло време за актуализиране.",
"config-mysql-engine-help": "'''InnoDB''' почти винаги е най-добрата възможност заради навременната си поддръжка.\n\n'''MyISAM''' може да е по-бърза при инсталации с един потребител или само за четене.\nБазите от данни MyISAM се повреждат по-често от InnoDB.",
"config-mysql-charset": "Набор от символи в базата от данни:",
"config-mysql-binary": "Бинарен",
"config-mysql-utf8": "UTF-8",
"config-mysql-charset-help": "В '''бинарен режим''' МедияУики съхранява текстовете в UTF-8 в бинарни полета в базата от данни.\nТова е по-ефективно от UTF-8 режима на MySQL и позволява използването на пълния набор от символи в Уникод.\n\nВ '''UTF-8 режим''' MySQL ще знае в кой набор от символи са данните от уикито и ще може да ги показва и променя по подходящ начин, но няма да позволява складиране на символи извън [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Основния многоезичен набор].",
"config-mssql-auth": "Тип на удостоверяването:",
+ "config-mssql-install-auth": "Изберете начин за удостоверяване, който ще бъде използван за връзка с базата от данни по време на инсталацията.\nАко изберете \"{{int:config-mssql-windowsauth}}\", ще се използват идентификационните данни на потребителя под който работи уеб сървъра.",
+ "config-mssql-web-auth": "Изберете начина за удостоверяване, който ще се използва от уеб сървъра за връзка със сървъра за бази от данни по време на нормалните операции на уикито.\nАко изберете \"{{int:config-mssql-windowsauth}}\", ще се използват идентификационните данни на потребителя под който работи уеб сървъра.",
"config-mssql-sqlauth": "Удостоверяване чрез SQL Server",
"config-mssql-windowsauth": "Удостоверяване чрез Windows",
"config-site-name": "Име на уикито:",
"config-profile-help": "Викијата функционираат најдобро кога имаат што повеќе уредници.\nВо МедијаВики лесно се проверуваат скорешните промени, и лесно се исправа (технички: „враќа“) штетата направена од неупатени или злонамерни корисници.\n\nМногумина имаат најдено најразлични полезни примени за МедијаВики, но понекогаш не е лесно да убедите некого во предностите на вики-концептот.\nЗначи имате избор.\n\n'''{{int:config-profile-wiki}}''' — модел според кој секој може да уредува, дури и без најавување.\nАко имате вики со '''задолжително отворање на сметка''', тогаш добивате повеќе контрола, но ова може даги одврати спонтаните учесници.\n\n'''{{int:config-profile-fishbowl}}''' — може да уредуваат само уредници што имаат добиено дозвола за тоа, но јавноста може да ги гледа страниците, вклучувајќи ја нивната историја.\n'''{{int:config-profile-private}}''' — страниците се видливи и уредливи само за овластени корисници.\n\nПо воспоставката имате на избор и посложени кориснички права и поставки. Погледајте во [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:User_rights прирачникот].",
"config-license": "Авторски права и лиценца:",
"config-license-none": "Без подножје за лиценца",
- "config-license-cc-by-sa": "Криејтив комонс НаведиИзвор СподелиПодИстиУслови",
- "config-license-cc-by": "Криејтив комонс НаведиИзвор",
- "config-license-cc-by-nc-sa": "Криејтив комонс НаведиИзвор-Некомерцијално-СподелиПодИстиУслови",
+ "config-license-cc-by-sa": "Криејтив комонс Наведи извор-Сподели под исти услови",
+ "config-license-cc-by": "Криејтив комонс Наведи извор",
+ "config-license-cc-by-nc-sa": "Криејтив комонс Наведи извор-Сподели под исти услови",
"config-license-cc-0": "Криејтив комонс Нула (јавна сопственост)",
"config-license-gfdl": "ГНУ-ова лиценца за слободна документација 1.3 или понова",
"config-license-pd": "Јавна сопственост",
}
}
-class_alias( 'Database', 'DatabaseBase' );
+class_alias( Database::class, 'DatabaseBase' );
}
}
-class_alias( 'Wikimedia\Rdbms\Blob', 'Blob' );
+class_alias( Blob::class, 'Blob' );
function isNullable();
}
-class_alias( 'Wikimedia\Rdbms\Field', 'Field' );
+class_alias( Field::class, 'Field' );
* @param array $localFileRefs List of files
*/
protected function saveFileDependencies( ResourceLoaderContext $context, $localFileRefs ) {
- // Normalise array
- $localFileRefs = array_values( array_unique( $localFileRefs ) );
- sort( $localFileRefs );
try {
+ // Related bugs and performance considerations:
+ // 1. Don't needlessly change the database value with the same list in a
+ // different order or with duplicates.
+ // 2. Use relative paths to avoid ghost entries when $IP changes. (T111481)
+ // 3. Don't needlessly replace the database with the same value
+ // just because $IP changed (e.g. when upgrading a wiki).
+ // 4. Don't create an endless replace loop on every request for this
+ // module when '../' is used anywhere. Even though both are expanded
+ // (one expanded by getFileDependencies from the DB, the other is
+ // still raw as originally read by RL), the latter has not
+ // been normalized yet.
+
+ // Normalise
+ $localFileRefs = array_values( array_unique( $localFileRefs ) );
+ sort( $localFileRefs );
+ $localPaths = self::getRelativePaths( $localFileRefs );
+
+ $storedPaths = self::getRelativePaths( $this->getFileDependencies( $context ) );
// If the list has been modified since last time we cached it, update the cache
- if ( $localFileRefs !== $this->getFileDependencies( $context ) ) {
+ if ( $localPaths !== $storedPaths ) {
$vary = $context->getSkin() . '|' . $context->getLanguage();
$cache = ObjectCache::getLocalClusterInstance();
$key = $cache->makeKey( __METHOD__, $this->getName(), $vary );
return; // T124649; avoid write slams
}
- // Use relative paths to avoid ghost entries when $IP changes (T111481)
- $deps = FormatJson::encode( self::getRelativePaths( $localFileRefs ) );
+ $deps = FormatJson::encode( $localPaths );
$dbw = wfGetDB( DB_MASTER );
$dbw->upsert( 'module_deps',
[
}
}
+ if ( !$wikiModules ) {
+ // Nothing to preload
+ return;
+ }
+
$pageNames = array_keys( $allPages );
sort( $pageNames );
$hash = sha1( implode( '|', $pageNames ) );
foreach ( glob( $this->basepath . '/*.php' ) as $file ) {
$this->readFile( $file );
}
-
- // Legacy aliases (1.28)
- $this->forceClassPath( 'DatabaseBase',
- $this->basepath . '/includes/libs/rdbms/database/Database.php' );
- // Legacy aliases (1.29)
- $this->forceClassPath( 'Blob',
- $this->basepath . '/includes/libs/rdbms/encasing/Blob.php' );
- $this->forceClassPath( 'Field',
- $this->basepath . '/includes/libs/rdbms/field/Field.php' );
}
}
*/
protected $tokens;
+ /**
+ * @var array Class alias with target/name fields
+ */
+ protected $alias;
+
/**
* @var string $code PHP code (including <?php) to detect class names from
* @return array List of FQCN detected within the tokens
$this->namespace = '';
$this->classes = [];
$this->startToken = null;
+ $this->alias = null;
$this->tokens = [];
foreach ( token_get_all( $code ) as $token ) {
if ( is_string( $token ) ) {
return;
}
+ // Note: When changing class name discovery logic,
+ // AutoLoaderTest.php may also need to be updated.
switch ( $token[0] ) {
case T_NAMESPACE:
case T_CLASS:
case T_TRAIT:
case T_DOUBLE_COLON:
$this->startToken = $token;
+ break;
+ case T_STRING:
+ if ( $token[1] === 'class_alias' ) {
+ $this->startToken = $token;
+ $this->alias = [];
+ }
}
}
}
break;
+ case T_STRING:
+ if ( $this->alias !== null ) {
+ // Flow 1 - Two string literals:
+ // - T_STRING class_alias
+ // - '('
+ // - T_CONSTANT_ENCAPSED_STRING 'TargetClass'
+ // - ','
+ // - T_WHITESPACE
+ // - T_CONSTANT_ENCAPSED_STRING 'AliasName'
+ // - ')'
+ // Flow 2 - Use of ::class syntax for first parameter
+ // - T_STRING class_alias
+ // - '('
+ // - T_STRING TargetClass
+ // - T_DOUBLE_COLON ::
+ // - T_CLASS class
+ // - ','
+ // - T_WHITESPACE
+ // - T_CONSTANT_ENCAPSED_STRING 'AliasName'
+ // - ')'
+ if ( $token === '(' ) {
+ // Start of a function call to class_alias()
+ $this->alias = [ 'target' => false, 'name' => false ];
+ } elseif ( $token === ',' ) {
+ // Record that we're past the first parameter
+ if ( $this->alias['target'] === false ) {
+ $this->alias['target'] = true;
+ }
+ } elseif ( is_array( $token ) && $token[0] === T_CONSTANT_ENCAPSED_STRING ) {
+ if ( $this->alias['target'] === true ) {
+ // We already saw a first argument, this must be the second.
+ // Strip quotes from the string literal.
+ $this->alias['name'] = substr( $token[1], 1, -1 );
+ }
+ } elseif ( $token === ')' ) {
+ // End of function call
+ $this->classes[] = $this->alias['name'];
+ $this->alias = null;
+ $this->startToken = null;
+ }
+ }
+ break;
+
case T_CLASS:
case T_INTERFACE:
case T_TRAIT:
* @return string HTML
*/
protected function shortDialogHtml( $profile, $term, $numResults, $totalResults, $offset ) {
+ $html = '';
+
$searchWidget = new SearchInputWidget( [
'id' => 'searchText',
'name' => 'search',
'align' => 'top',
] );
- $html =
- Html::hidden( 'title', $this->specialSearch->getPageTitle()->getPrefixedText() ) .
- Html::hidden( 'profile', $profile ) .
- Html::hidden( 'fulltext', '1' ) .
- $layout;
+ $html .= $layout;
if ( $totalResults > 0 && $offset < $totalResults ) {
$html .= Xml::tags(
);
}
+ $html .=
+ Html::hidden( 'title', $this->specialSearch->getPageTitle()->getPrefixedText() ) .
+ Html::hidden( 'profile', $profile ) .
+ Html::hidden( 'fulltext', '1' );
+
return $html;
}
"rev-deleted-text-unhide": "Гэтая вэрсія старонкі была <strong>выдаленая</strong>.\nПадрабязнасьці могуць быць знойдзеныя ў [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале выдаленьняў].\nВы можаце [$1 праглядзець гэтую вэрсію], калі жадаеце.",
"rev-suppressed-text-unhide": "Гэтая вэрсія старонкі была <strong>схаваная</strong>.\nПадрабязнасьці могуць быць знойдзеныя ў [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} журнале хаваньняў].\nВы можаце [$1 праглядзець гэтую вэрсію], калі жадаеце.",
"rev-deleted-text-view": "Гэтая вэрсія старонкі была <strong>выдаленая</strong>.\nВы можаце праглядзець яе; падрабязнасьці могуць быць знойдзеныя ў [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале выдаленьняў].",
- "rev-suppressed-text-view": "Гэтая вэрсія старонкі была '''схаваная'''.\nВы можаце яе праглядзець; падрабязнасьці могуць быць знойдзеныя ў [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} журнале хаваньняў].",
+ "rev-suppressed-text-view": "Гэтая вэрсія старонкі была <strong>схаваная</strong>.\nВы можаце яе праглядзець; падрабязнасьці могуць быць знойдзеныя ў [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} журнале хаваньняў].",
"rev-deleted-no-diff": "Вы ня можаце праглядаць гэтую розьніцу паміж вэрсіямі, таму што адна з вэрсіяў была '''выдаленая'''.\nМагчыма, падрабязнасьці могуць быць знойдзеныя ў [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале выдаленьняў].",
"rev-suppressed-no-diff": "Вы ня можаце праглядзець гэтую розьніцу, таму што адна з вэрсіяў была '''выдаленая'''.",
"rev-deleted-unhide-diff": "Адна з вэрсіяў гэтай старонкі была '''выдаленая'''.\nПадрабязнасьці могуць быць знойдзеныя ў [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале выдаленьняў].\nВы можаце праглядзець [$1 розьніцу паміж вэрсіямі], калі жадаеце.",
"authmanager-authn-no-local-user": "Пададзеныя ўліковыя зьвесткі не зьвязаныя зь ніводным удзельнікам гэтай вікі.",
"authmanager-authn-autocreate-failed": "Аўтаматычнае стварэньне лякальнага рахунку не атрымалася: $1",
"authmanager-change-not-supported": "Пададзеныя ўліковыя зьвесткі ня могуць быць зьмененыя, бо яны ня будуць выкарыстаныя.",
+ "authmanager-create-disabled": "Стварэньне рахункаў адключанае.",
"authmanager-realname-label": "Сапраўднае імя",
"authmanager-provider-temporarypassword": "Часовы пароль",
"changecredentials": "Зьмена ўліковых зьвестак",
"activeusers-intro": "Гэта пералік удзельнікаў, якія нешта рабілі за апошнія $1 {{PLURAL:$1|дзень|дзён}}.",
"activeusers-count": "$1 {{PLURAL:$1|дзеянне|дзеянні|дзеянняў}} за апошні{{PLURAL:$3| дзень|я $3 дні|я $3 дзён}}",
"activeusers-from": "Паказ, пачынаючы з:",
- "activeusers-groups": "Паказаць удзельнікаў, якія належаць да групаў:",
+ "activeusers-groups": "Паказаць удзельнікаў, якія належаць да груп:",
"activeusers-noresult": "Няма такіх удзельнікаў.",
"activeusers-submit": "Паказаць актыўных удзельнікаў",
"listgrouprights": "Дазволы для груп удзельнікаў",
"continue-editing": "Продължаване към полето за редактиране",
"previewconflict": "Този предварителен преглед отразява текста в горната текстова кутия така, както би се показал, ако съхраните.",
"session_fail_preview": "За съжаление редакцията ви не успя да бъде обработена поради загуба на данните за текущата сесия.\n\nМоже би сте излезли от системата. <strong>Моля, уверете се, че сте влезли в профила си и опитайте отново.</strong>\nАко все още не работи, опитайте да [[Special:UserLogout|излезете]] и да влезете отново, също така проверете дали браузърът ви позволява бисквитки от този сайт.",
- "session_fail_preview_html": "'''За съжаление редакцията ви не беше записана поради изтичането на сесията ви.'''\n\n''Тъй като {{SITENAME}} приема обикновен HTML, предварителният преглед е скрит като предпазна мярка срещу атаки чрез Джаваскрипт.''\n\n'''Опитайте отново. Ако все още не сработва, пробвайте да [[Special:UserLogout|излезете]] и влезете отново.'''",
+ "session_fail_preview_html": "За съжаление редакцията ви не беше записана поради изтичането на сесията ви.\n\n<em>Тъй като {{SITENAME}} приема обикновен HTML, предварителният преглед е скрит като предпазна мярка срещу атаки чрез JavaScript.</em>\n\n<strong>Ако това е обикновен опит за редактиране, моля опитайте отново.</strong>\nАко все още не сработва, пробвайте да [[Special:UserLogout|излезете]] и влезете отново, и се уверете, че браузъра ви приема бисквитки от този сайт.",
"token_suffix_mismatch": "'''Редакцията ви беше отхвърлена, защото браузърът ви е развалил пунктуационните знаци в редакционната отметка. Евентуалното съхранение би унищожило съдържанието на страницата. Понякога това се случва при използването на грешно работещи анонимни междинни сървъри.'''",
"edit_form_incomplete": "'''Някои части от формуляра за редактиране не достигнаха до сървъра; проверете дали редакциите ви са непокътнати и опитайте отново.'''",
"editing": "Редактиране на „$1“",
"permissionserrorstext-withaction": "Du bist aus {{PLURAL:$1|dem folgenden Grund|den folgenden Gründen}} nicht berechtigt, $2:",
"contentmodelediterror": "Du kannst diese Version nicht bearbeiten, da das Inhaltsmodell <code>$1</code> vom aktuellen Inhaltsmodell der Seite <code>$2</code> abweicht.",
"recreate-moveddeleted-warn": "<strong>Achtung: Du erstellst eine Seite, die bereits früher gelöscht wurde.</strong>\n\nBitte prüfe sorgfältig, ob die erneute Seitenerstellung den Richtlinien entspricht.\nZu deiner Information folgt das Lösch- und Verschiebungs-Logbuch mit der Begründung für die vorhergehende Löschung:",
- "moveddeleted-notice": "Diese Seite wurde gelöscht. Zur Information folgt das Lösch- und Verschiebungs-Logbuch dieser Seite.",
- "moveddeleted-notice-recent": "Leider wurde diese Seite kürzlich gelöscht (innerhalb der letzten 24 Stunden).\nZur Information wird das Lösch- und Verschiebungs-Logbuch für die Seite unten angezeigt.",
+ "moveddeleted-notice": "Diese Seite wurde gelöscht.\nZur Information folgt das Lösch- und Verschiebungs-Logbuch dieser Seite.",
+ "moveddeleted-notice-recent": "Diese Seite wurde kürzlich gelöscht (innerhalb der letzten 24 Stunden).\nZur Information folgt das Lösch- und Verschiebungs-Logbuch dieser Seite.",
"log-fulllog": "Alle Logbucheinträge ansehen",
"edit-hook-aborted": "Die Bearbeitung wurde ohne Erklärung durch eine Schnittstelle abgebrochen.",
"edit-gone-missing": "Die Seite konnte nicht aktualisiert werden.\nSie wurde anscheinend gelöscht.",
"missingsummary": "'''DİQET:''' Şıma jû xulasa nênuşte.\nEke şıma \"{{int:savearticle}}\" reyna bıtıknê, vırnayışê şıma bê xulasa qeyd beno.",
"missingcommenttext": "Cêr de jû fıkır bınusên, şıma rê zehmet.",
"missingcommentheader": "'''Diqet:''' Şıma seba nê fıkrvaci yew mewzu/sernuşte nênuşt.\nEke şıma reyna \"{{int:savearticle}}\" bıtıknê, vırnayışê şıa bê mewzu/sernuşte do qeyd bo.",
- "summary-preview": "Verqaytê xulasa:",
+ "summary-preview": "Verasayışê xulasa:",
"subject-preview": "Verqaytê mewzu:",
"previewerrortext": "Verasayışê vırnayışê şıma de yew xeta veciya miyan.",
"blockedtitle": "Karber blokekerdeo",
"deleting-backlinks-warning": "<strong>Προσοχή:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Άλλες σελίδες]] συνδέουν ή ενσωματώνουν τη σελίδα που πρόκειται να διαγράψετε.",
"rollback": "Επαναφορά επεξεργασιών",
"rollbacklink": "αναστροφή",
- "rollbacklinkcount": "Î\95Ï\80αναÏ\86οÏ\81ά $1 {{PLURAL:$1|επεξεργασίας|επεξεργασιών}}",
- "rollbacklinkcount-morethan": "εÏ\80αναÏ\86οÏ\81ά περισσότερων από $1 {{PLURAL:$1|επεξεργασία|επεξεργασίες}}",
+ "rollbacklinkcount": "Î\91ναÏ\83Ï\84Ï\81οÏ\86ή $1 {{PLURAL:$1|επεξεργασίας|επεξεργασιών}}",
+ "rollbacklinkcount-morethan": "αναÏ\83Ï\84Ï\81οÏ\86ή περισσότερων από $1 {{PLURAL:$1|επεξεργασία|επεξεργασίες}}",
"rollbackfailed": "Η επαναφορά απέτυχε.",
"cantrollback": "Δεν είναι δυνατή η αναίρεση αυτής της αλλαγής, πρόκειται για την αρχική ενέργεια δημιουργίας της σελίδας.",
"alreadyrolled": "Αδύνατον να αναιρεθεί η τελευταία αλλαγή της σελίδας [[:$1]] από το χρήστη ([[User:$2|$2]] ([[User talk:$2|Συζήτηση]]){{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]), διότι κάποιος έχει ήδη αναιρέσει την αλλαγή ή έχει αλλάξει εκ νέου τη σελίδα.\n\nΤελευταία αλλαγή από το χρήστη ([[User:$3|$3]] ([[User talk:$3|Συζήτηση]]){{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
"editcomment": "The edit summary was: <em>$1</em>.",
"revertpage": "Reverted edits by [[Special:Contributions/$2|$2]] ([[User talk:$2|talk]]) to last revision by [[User:$1|$1]]",
"revertpage-nouser": "Reverted edits by a hidden user to last revision by {{GENDER:$1|[[User:$1|$1]]}}",
- "rollback-success": "Reverted edits by $1;\nchanged back to last revision by $2.",
+ "rollback-success": "Reverted edits by {{GENDER:$3|$1}};\nchanged back to last revision by {{GENDER:$4|$2}}.",
"rollback-success-notify": "Reverted edits by $1;\nchanged back to last revision by $2. [$3 Show changes]",
"sessionfailure-title": "Session failure",
"sessionfailure": "There seems to be a problem with your login session;\nthis action has been canceled as a precaution against session hijacking.\nGo back to the previous page, reload that page and then try again.",
"createacct-email-ph": "Sisesta e-posti aadress",
"createacct-another-email-ph": "Sisesta e-posti aadress",
"createaccountmail": "Kasuta juhuslikku parooli ja saada see määratud e-posti aadressile",
+ "createaccountmail-help": "Saab kasutada konto loomiseks teisele kasutajale ilma parooli teada saamata.",
"createacct-realname": "Pärisnimi (valikuline)",
"createaccountreason": "Põhjus:",
"createacct-reason": "Põhjus",
"createacct-reason-ph": "Miks lood teist kontot?",
+ "createacct-reason-help": "Sõnum, mida näidatakse konto loomise logis",
"createacct-submit": "Loo konto",
"createacct-another-submit": "Loo konto",
+ "createacct-continue-submit": "Jätka konto loomist",
+ "createacct-another-continue-submit": "Jätka konto loomist",
"createacct-benefit-heading": "{{SITENAME}} on sinusuguste inimeste tehtud.",
"createacct-benefit-body1": "{{PLURAL:$1|muudatus|muudatust}}",
"createacct-benefit-body2": "{{PLURAL:$1|lehekülg|lehekülge}}",
"nocookiesnew": "Kasutajakonto loodi, aga sa ei ole sisse logitud, sest {{SITENAME}} kasutab kasutajate tuvastamisel küpsiseid. Sinu brauseris on küpsised keelatud. Palun sea küpsised lubatuks ja logi siis oma vastse kasutajanime ning parooliga sisse.",
"nocookieslogin": "{{SITENAME}} kasutab kasutajate tuvastamisel küpsiseid. Sinu brauseris on küpsised keelatud. Palun sea küpsised lubatuks ja proovi siis uuesti.",
"nocookiesfornew": "Kasutajakonto jäi loomata, kuna me ei saanud selle allikat kindlaks teha.\nVeendu, et sul on küpsised lubatud, taaslaadi see lehekülg ja proovi uuesti.",
+ "createacct-loginerror": "Konto on edukalt loodud, aga automaatselt ei õnnestunud sisse logida. Et jätkata, [[Special:UserLogin|logi palun sisse käsitsi]].",
"noname": "Sa ei sisestanud kasutajanime lubataval kujul.",
"loginsuccesstitle": "Sisse logitud",
"loginsuccess": "Oled sisse loginud. Sinu kasutajanimi on \"$1\".",
"missingcommenttext": "Palun sisesta siit allapoole kommentaar.",
"missingcommentheader": "<strong>Meeldetuletus:</strong> Sa pole kirjutanud kommentaarile teemat.\nKui klõpsad uuesti \"{{int:savearticle}}\", salvestatakse su kommentaar ilma teemata.",
"summary-preview": "Resümee eelvaade:",
- "subject-preview": "Alaosa pealkirja eelvaade:",
+ "subject-preview": "Resümee eelvaade:",
"previewerrortext": "Sinu muudatuste eelvaatluse juures esines tõrge.",
"blockedtitle": "Kasutaja on blokeeritud",
"blockedtext": "'''Sinu kasutajanimi või IP-aadress on blokeeritud.'''\n\nBlokeeris $1.\nTema põhjendus on järgmine: ''$2''.\n\n* Blokeeringu algus: $8\n* Blokeeringu lõpp: $6\n* Sooviti blokeerida: $7\n\nKüsimuse arutamiseks võid pöörduda kasutaja $1 või mõne teise [[{{MediaWiki:Grouppage-sysop}}|administraatori]] poole.\n\nPane tähele, et sa ei saa kasutajale teadet saata, kui sa pole kinnitanud oma [[Special:Preferences|eelistuste lehel]] kehtivat e-posti aadressi.\n\nSinu praegune IP-aadress on $3 ning blokeeringu number on #$5. Lisa need andmed kõigile järelepärimistele, mida kavatsed teha.",
"selfredirect": "<strong>Atención:</strong> Está redirixindo esta páxina a si mesma.\nQuizais especificou incorrectamente a páxina de destino ou poida que estea a editar unha páxina errónea.\nSe preme en \"{{int:savearticle}}\" de novo, crearase a redireción de calquera xeito.",
"missingcommenttext": "Por favor, escriba un comentario a continuación.",
"missingcommentheader": "<strong>Aviso:</strong> Non escribiu ningún texto no asunto deste comentario.\nSe preme en \"{{int:savearticle}}\" de novo, a súa edición gardarase sen el.",
- "summary-preview": "Vista previa do resumo:",
+ "summary-preview": "Vista previa do resumo de edición:",
"subject-preview": "Vista previa do asunto:",
"previewerrortext": "Produciuse un erro ao intentar previsualizar os cambios.",
"blockedtitle": "O usuario está bloqueado",
"saveusergroups": "Gardar os grupos {{GENDER:$1|do usuario|da usuaria}}",
"userrights-groupsmember": "Membro de:",
"userrights-groupsmember-auto": "Membro implícito de:",
- "userrights-groups-help": "Pode cambiar os grupos aos que {{GENDER:$1|o usuario|a usuaria}} pertence:\n* Se a caixa ten un sinal (✓) significa que {{GENDER:$1|o usuario|a usuaria}} pertence a ese grupo.\n* Se, pola contra, non o ten, significa que non pertence.\n* Un asterisco (*) indica que non pode eliminar o grupo unha vez que o engadiu, e viceversa.",
+ "userrights-groups-help": "Pode cambiar os grupos aos que {{GENDER:$1|o usuario|a usuaria}} pertence:\n* Se a caixa ten un sinal (✓) significa que {{GENDER:$1|o usuario|a usuaria}} pertence a ese grupo.\n* Se, pola contra, non o ten, significa que non pertence.\n* Un asterisco (*) indica que non pode eliminar o grupo unha vez que o engadiu, e viceversa.\n* Un # indica que só se pode atrasar a data de caducidade deste grupo; non se pode adiantar.",
"userrights-reason": "Motivo:",
"userrights-no-interwiki": "Non ten os permisos necesarios para editar os dereitos de usuario noutros wikis.",
"userrights-nodatabase": "A base de datos \"$1\" non existe ou non é local.",
"userrights-expiry-options": "1 día:1 día,1 semana:1 semana,1 mes:1 mes,3 meses:3 meses,6 meses:6 meses,1 ano:1 ano",
"userrights-invalid-expiry": "O tempo de caducidade para o grupo \"$1\" non é válido.",
"userrights-expiry-in-past": "O tempo de caducidade para o grupo \"$1\" está no pasado.",
+ "userrights-cannot-shorten-expiry": "Non pode adiantar a data de caducidade do grupo \"$1\". Só os usuarios con permisos para engadir e eliminar este grupo poden adiantar datas de caducidade.",
"userrights-conflict": "Hai un conflito na modificación dos dereitos de usuario! Por favor, revíseo e confirme os seus cambios.",
"group": "Grupo:",
"group-user": "Usuarios",
"tog-watchdefault": "Hanaraka ny pejy ary ny rakitra ovaiko",
"tog-watchmoves": "Hanaraka ny pejy ary ny rakitra ovaiko anarana",
"tog-watchdeletion": "Hanaraka ny pejy ary ny rakitra voafafako",
+ "tog-watchuploads": "Ampiana amin'ny pejy arahako ireo rakitra vaovao nalefako",
"tog-watchrollback": "Hanaraka pejy nanaovako famoana",
"tog-minordefault": "Mariho ho madinika foana aloha ny fanovana rehetra",
"tog-previewontop": "Asehoy alohan'ny boaty fanovana ny tsipalotra",
"tagline": "Avy amin'i {{SITENAME}}",
"help": "Fanoroana",
"search": "Tadiavo",
+ "search-ignored-headings": "#<!-- Avelao ho toa izao ity andalana ity --> <pre>\n# Ny lohatenim-pizarana dia tsy horaharahiana amin'ny karoka.\n# Ny fiovana atao eto dia hihatra rehefa voasoratra ao amin'ny tondro ilay pejy miaraka amin'ilay lohateny.\n# Azonao atao ny famerenana an-tondro an'ilay pejy amin'ny alalan'ny fanovana tsy misy inona inona.\n# Ny rariteny dia ireo manaraka:\n# *Izay andalana rehetra manomboka amin'ny \"#\" dia resaka\n# *Izay andalana tsy fotsy dia lohateny tsy horaharahiana, iaraka amin'ny haben-tsoratra\nTsiahy\nRohy ivelany\nJereo koa\n#</pre> <!-- Avelao ho toa izao ity andalana ity -->",
"searchbutton": "Tadiavo",
"go": "Ndao",
"searcharticle": "Tsidiho",
"passwordreset-emailtext-user": "Nisy mpikambana mitondra anarana $1 eo amin'i {{SITENAME}} nangataka fampatsiahivana mikasika ny kaontinao eo amin'i {{SITENAME}} ($4). Manana io adiresy imailaka {{PLURAL:$3|io kaontim-pikambana io|ireo kaontim-pikambana ireo}} :\n\n$2\n\nHitsahatra afaka {{PLURAL:$5|iray|$5}} andro {{PLURAL:$3|io|ireo}} tenimiafina {{PLURAL:$3|io|ireo}}. Mila miditra dien'izao ianao izao ary mifidy tenimiafina vaovao. Raha tsy avy aminao ity hataka ity na efa nahatadidy ny tenimiafinao taloha ianao, ary raha tsy tianao hovaina intsony ilay tenimiafinao, dia azonao tsy raharahiana ity hafatra ity ary mampiasa ny tenimiafinao taloha.",
"passwordreset-emailelement": "Anaram-pikambana : \n$1\n\nTenimiafina miserana : \n$2",
"passwordreset-emailsentemail": "Lasa ny mailaka famerenana tenimiafina.",
+ "passwordreset-nocaller": "Mila manitsy mpiantso",
+ "passwordreset-nosuchcaller": "Tsy misy ilay mpiantso: $1",
"changeemail": "Hanova ny adiresy imailaka",
"changeemail-header": "Hanova ny adiresy imailak'ilay kaonty",
"changeemail-no-info": "Mila tafiditra ianao vao avaka mijery ity pejy ity.",
"yourdiff": "Fampitahana",
"copyrightwarning": "Ny zavatra rehetra apetraka amin'ny {{SITENAME}} dia raisina ho azo adika malalaka araka ny fahazoan-dalana $2 (Jereo $1 ny fanazavana fanampiny). Raha toa ka tianao ho anao manokana ny tahirin-kevitra dia aleo tsy apetraka ato.\n\n<b>AZA MAMPIASA TAHIRINKEVITRA TSY NAHAZOAN-DALANA</b>",
"copyrightwarning2": "Ny fandraisana anjara ao amin'i {{SITENAME}} dia azo ovaina ary fafan'ny mpikambana hafa. Raha tsy tianao ho ampiasainan, ovaina na zarazaraina ny soratrao, dia aza alefa eto ilay vokatr'asanao<br />\nNy zava-tsoratanao eto dia vokatr'asa naverinao soratana na nodikainao tany amina loharano ao amin'ny vala sarababem-bahoaka na loharano malalaka hafa (Jereo $1 ho an'ny antsipirihany).\n\n'''Aza mampiasa tahirin-kevitra tsy nahazoan-dalana!'''",
+ "editpage-cannot-use-custom-model": "Tsy mety ovaina ny modelim-botoatin'ity pejy ity.",
"longpageerror": "'''Hadisoana : Ny tahirin-tsoratra nalefanao dia manana halava {{PLURAL:$1|iray|$1}} kilooktety, izay lava kokoa nohon'ny fetra avo indridra izay natao ho {{PLURAL:$2|iray|$2}} kilooktety.'''\nTsy afaka tahirizina ilay tahirin-tsoratra.",
"readonlywarning": "'''FAMPITANDREMANA: Nohidiana noho ny antony fikolokoloana aloha ny banky angona,\nkoa tsy afaka mitahiry ny fanovana nataonao aloha ianao izao. Angamba tokony hanao Couper coller aloha\nianao dia tehirizo anaty rakitra ny fanovanao mandra-paha.'''\n\nNy mpandrindra nanidy ny banky angona dia nanome ny antony : <br />$1",
"protectedpagewarning": "'''FAMPITANDREMANA: Voaaro ity pejy ity ka ny mpikambana manana ny fahazoan-dàlana sysop ihany no afaka manova azy.'''",
"invalid-content-data": "Data anaty votoatiny tsy miady amin'ny fepetra",
"content-not-allowed-here": "Votoatiny ''$1'' voarara eo amin'ny pejy [[$2]]",
"editwarning-warning": "Mety hahavery ny fanovana nataonao ny fialanao amin'ity pejy ity.\nRaha tafiditra ianao dia azonao esorina ity fampitandremana ity ao amin'ny fizarana \"{{int:prefs-editing}}\" ao amin'ny safidinao.",
+ "editpage-invalidcontentmodel-title": "Andrefim-botoatiny tsy zaka",
+ "editpage-invalidcontentmodel-text": "Andrefim-botoatiny \"$1\" tsy zaka.",
"editpage-notsupportedcontentformat-title": "Tsy zaka io andrefim-botoatiny io",
"editpage-notsupportedcontentformat-text": "Tsy zakan'ny maodelim-botoatiny $1 ny firafi-botoatiny $1",
"content-model-wikitext": "wiki-soratra",
"content-model-css": "CSS",
"content-json-empty-object": "Zavatra foana",
"content-json-empty-array": "Tabilao foana",
+ "deprecated-self-close-category": "Pejy mampiasa balizy HTML mihidy ho azy izay tsy azo raisina",
"duplicate-args-category": "Pejy mampiasa dika mitovy hevitra amin'ny fiantsoana endrika",
"expensive-parserfunction-warning": "Tandremo : Betsaka loatra ny fanantsoana ny tao parser.\n\nTsy maintsy latsaky ny $2 ny tao, kanefa misy $1. {{PLURAL:$2||}}",
"expensive-parserfunction-category": "Pejy mampiasa be loatra ny tao parser",
"search-interwiki-caption": "zandri-tetikasa",
"search-interwiki-default": "Valiny amin'ny $1 :",
"search-interwiki-more": "(be kokoa)",
+ "search-interwiki-more-results": "Valiny be kokoa",
"search-relatedarticle": "voadinika",
"searchrelated": "voadinika",
"searchall": "rehetra",
"youremail": "Imailaka:",
"username": "{{GENDER:$1}}Anaram-pikambana :",
"prefs-memberingroups": "Mpikambana{{GENDER:$2}} ao amin'ny vondrona{{PLURAL:$1}}:",
+ "group-membership-link-with-expiry": "$1 (hatramin'i $2)",
"prefs-registration": "Daty fidirana :",
"yourrealname": "Tena anarana marina:",
"yourlanguage": "Tenim-pirenena:",
"prefswarning-warning": "Efa nanova tamin'ny safidinao tsy mbola voatahiry ianao. Raha miala amin'ity pejy ity amin'ny alalan'ny fanindriana an'i \"$1\" ianao dia tsy ho voavao ny safidinao.",
"prefs-tabs-navigation-hint": "Torohevitra: afaka mampiasa ny zana-tsipika havia ary havanana ianao ho an'ny fitetezana ny vakizoro ao amin'ny lisi-bakizoro",
"userrights": "Fandrindràna ny fahefahan'ny mpikambana",
- "userrights-lookup-user": "Handrindra vondrom-pikambana",
+ "userrights-lookup-user": "Hisafidy mpikambana",
"userrights-user-editname": "Manomeza solonanarana:",
- "editusergroup": "Hanova satan'ny {{GENDER:$1|}}mpikambana",
+ "editusergroup": "Hampiditra vondrom-pikambana",
"editinguser": "Fanovana ny zon'ny mpikambana <strong>{{GENDER:$1|}}[[User:$1|$1]]</strong> $2",
"userrights-editusergroup": "Hanova vondrom-pikambana",
"saveusergroups": "{{GENDER:$1|}}Tehirizo ny vondrom-pikambana",
"userrights-changeable-col": "Ny gropy azonao ovaina",
"userrights-unchangeable-col": "Ny gropy tsy azonao ovaina",
"userrights-expiry-current": "Mitsahatra ny $1",
+ "userrights-expiry-none": "Tsy mitsahatra",
"userrights-expiry": "Fitsaharana:",
+ "userrights-expiry-existing": "Fotoam-pitsaharana ankehitriny: $3, $2",
+ "userrights-expiry-othertime": "Fotoana hafa:",
+ "userrights-expiry-options": "1 andro:1 day,herinandro:1 week,1 volana:1 month,3 volana:3 months,6 volana:6 months,herintaona:1 year",
+ "userrights-invalid-expiry": "Tsy azo raisina ny fotoam-pitsaharana ho an'ny vondrona \"$1\".",
"userrights-conflict": "Fifandonana fanovana zom-pikambana! Avereno vakiana ary marino ny fanovanao.",
"group": "Gropy :",
"group-user": "Mpikambana",
"permissionserrorstext": "Avètz pas la permission d’efectuar l’operacion demandada per {{PLURAL:$1|la rason seguenta|las rasons seguentas}} :",
"permissionserrorstext-withaction": "Sètz pas autorizat(ada) a $2, per {{PLURAL:$1|la rason seguenta|las rasons seguentas}} :",
"recreate-moveddeleted-warn": "'''Atencion : sètz a tornar crear una pagina qu'es estada suprimida precedentament.'''\n\nDemandatz-vos s'es vertadièrament apropriat de contunhar de l’editar.\nL’istoric de las supressions e dels cambiaments de nom es afichat çaijós :",
- "moveddeleted-notice": "Aquesta pagina es estat suprimida.\nL'istoric de las supressions e dels cambiaments de nom es afichat çaijós coma referéncia.",
+ "moveddeleted-notice": "Aquesta pagina es estada suprimida.\nL'istoric de las supressions e dels cambiaments de nom es afichat çaijós coma referéncia.",
"log-fulllog": "Veire lo jornal complet",
"edit-hook-aborted": "Modificacion fracassada per croquet.\nCap d'explicacion pas balhada.",
"edit-gone-missing": "A pas pogut metre a jorn la pagina.\nSembla que siá estada suprimida.",
"permissionserrorstext-withaction": "This message is \"with action\" version of {{msg-mw|Permissionserrorstext}}.\n\nParameters:\n* $1 - the number of reasons that were found why the action cannot be performed\n* $2 - one of the action-* messages (for example {{msg-mw|action-edit}}) or other such messages tagged with {{tl|doc-action}} in their documentation\n\nPlease report at [[Support]] if you are unable to properly translate this message. Also see [[phab:T16246]] (now closed) for background.",
"contentmodelediterror": "Error message shown when trying to edit an old revision with a content model different from that of the current revision\n* $1 - content model of the old revision\n* $2 - content model of the current revision",
"recreate-moveddeleted-warn": "Warning shown when creating a page which has already been deleted. See for example [[Test]].",
- "moveddeleted-notice": "Shown on top of a deleted page in normal view modus ([{{canonicalurl:Test}} example]).",
- "moveddeleted-notice-recent": "Shown on top of a recently deleted page in normal view modus ([{{canonicalurl:Test}} example]).",
+ "moveddeleted-notice": "Shown on top of a deleted page in normal view modus ([{{canonicalurl:Test}} example]).\n\nSee also {{msg-mw|moveddeleted-notice-recent}}",
+ "moveddeleted-notice-recent": "Shown on top of a recently deleted page in normal view modus ([{{canonicalurl:Test}} example]).\n\nSee also {{msg-mw|moveddeleted-notice}}",
"log-fulllog": "Used as link text.",
"edit-hook-aborted": "Used as error message.\n\nSee also:\n* {{msg-mw|edit-gone-missing}}\n* {{msg-mw|edit-conflict}}\n* {{msg-mw|edit-no-change}}\n* {{msg-mw|edit-already-exists}}",
"edit-gone-missing": "Used as error message.\n\nSee also:\n* {{msg-mw|edit-hook-aborted}}\n* {{msg-mw|edit-conflict}}\n* {{msg-mw|edit-no-change}}\n* {{msg-mw|edit-already-exists}}",
"booksources-text": "Used in [[Special:BookSources/1]].\n\nThis message is followed by a list of links to other sites.\n\nSee also:\n* {{msg-mw|Booksources|title}}\n* {{msg-mw|Booksources-text|text}}",
"booksources-invalid-isbn": "This message is displayed after an invalid ISBN is entered on [[Special:Booksources]].",
"magiclink-tracking-rfc": "Name of the [[mw:Special:MyLanguage/Help:Tracking categories|tracking category]] where pages that use RFC magic links will be added.\n\nSee [https://en.wikipedia.org/wiki/Help:Magic_links#RFC Help:Magic links] for more information on RFC magic links.",
- "magiclink-tracking-rfc-desc": "Description of the tracking category {{mw-msg|magiclink-tracking-rfc}}",
+ "magiclink-tracking-rfc-desc": "Description of the tracking category {{msg-mw|magiclink-tracking-rfc}}",
"magiclink-tracking-pmid": "Name of the [[mw:Special:MyLanguage/Help:Tracking categories|tracking category]] where pages that use PMID magic links will be added.",
- "magiclink-tracking-pmid-desc": "Description of the tracking category {{mw-msg|magiclink-tracking-pmid}}",
+ "magiclink-tracking-pmid-desc": "Description of the tracking category {{msg-mw|magiclink-tracking-pmid}}",
"magiclink-tracking-isbn": "Name of the [[mw:Special:MyLanguage/Help:Tracking categories|tracking category]] where pages that use ISBN magic links will be added.",
- "magiclink-tracking-isbn-desc": "Description of the tracking category {{mw-msg|magiclink-tracking-isbn}}",
+ "magiclink-tracking-isbn-desc": "Description of the tracking category {{msg-mw|magiclink-tracking-isbn}}",
"rfcurl": "{{notranslate}}\nParameters:\n* $1 - RFC number\nSee also:\n* {{msg-mw|Pubmedurl}}",
"pubmedurl": "{{notranslate}}\nParameters:\n* $1 - Pubmed number\nSee also:\n* {{msg-mw|Rfcurl}}",
"specialloguserlabel": "Used in [[Special:Log]] as a label for an input field with which the log can be filtered for entries describing actions ''performed'' by the specified user. \"Carried out\" and \"done\" are possible alternatives for \"performed\".",
"editcomment": "Only shown if there is an edit {{msg-mw|Summary}}. Parameters:\n* $1 - the edit summary",
"revertpage": "Parameters:\n* $1 - username 1\n* $2 - username 2\n* $3 - (Optional) revision ID of the revision reverted to\n* $4 - (Optional) timestamp of the revision reverted to\n* $5 - (Optional) revision ID of the revision reverted from\n* $6 - (Optional) timestamp of the revision reverted from\nSee also:\n* {{msg-mw|Revertpage-nouser}}\n{{Identical|Revert}}",
"revertpage-nouser": "This is a confirmation message a user sees after reverting, when the username of the version is hidden with RevisionDelete.\n\nIn other cases the message {{msg-mw|Revertpage}} is used.\n\nParameters:\n* $1 - username 1, can be used for GENDER\n* $2 - (Optional) username 2\n* $3 - (Optional) revision ID of the revision reverted to\n* $4 - (Optional) timestamp of the revision reverted to\n* $5 - (Optional) revision ID of the revision reverted from\n* $6 - (Optional) timestamp of the revision reverted from",
- "rollback-success": "This message shows up on screen after successful revert (generally visible only to admins). $1 describes user whose changes have been reverted, $2 describes user which produced version, which replaces reverted version.\n{{Identical|Revert}}\n{{Identical|Rollback}}",
+ "rollback-success": "This message shows up on screen after successful revert (generally visible only to admins). Parameters:\n* $1 - user whose changes have been reverted\n* $2 - user who produced version, which replaces reverted version\n* $3 - the first user's name, can be used for GENDER\n* $4 - the second user's name, can be used for GENDER\n{{Identical|Revert}}\n{{Identical|Rollback}}",
"rollback-success-notify": "Notification shown after a successful revert.\n* $1 - User whose changes have been reverted\n* $2 - User that made the edit that was restored\n* $3 - Url to the diff of the rollback\nSee also:\n* {{msg-mw|showdiff}}\n{{related|rollback-success}}\n{{Format|jquerymsg}}",
"sessionfailure-title": "Used as title of the error message {{msg-mw|Sessionfailure}}.",
"sessionfailure": "Used as error message.\n\nThe title for this error message is {{msg-mw|Sessionfailure-title}}.",
"uploaddisabledtext": "கோப்பு பதிவேற்றங்கள் செயலிழக்கச் செய்யப்பட்டுள்ளன.",
"php-uploaddisabledtext": "கோப்பு தரவேற்றம் PHP இல் முடக்கப்பட்டுள்ளது.தயவுகூர்ந்து file_uploads அமைப்பை சரிபார்க்கவும்.",
"uploadscripted": "இந்தக் கோப்பு உலாவியால் பிழையாக விளங்கிக் கொள்ளக்கூடிய எச்.டி.எம்.எல். அல்லது வேறு நிரல்களைக் கொண்டுள்ளது.",
- "uploadscriptednamespace": "இந்த SVG கோப்பு ஒரு சரியில்லாத பெயரிடைவெளியை \"<nowiki>$1</nowiki>\" கொண்டுள்ளது.",
+ "uploadscriptednamespace": "இந்த SVG கோப்பு ஒரு சரியில்லாத பெயரிடைவெளியை கொண்டுள்ளது \"<nowiki>$1</nowiki>\".",
"uploadinvalidxml": "ஏற்றபட்ட கோப்பில் உள்ள XML ஆராய முடியாது.",
"uploadvirus": "கோப்பு நச்சுநிரலைக் (வைரஸ்) கொண்டுள்ளது! விபரங்கள்:$1",
"uploadjava": "இது ஒரு zip கோப்பு.இதில் java.class என்ற கோப்பு உள்ளது.\nஜாவா கோப்புகளை தகவலேற்றுவது தடைசெய்யப்பட்டுள்ளது.ஏனெனில் அது பாதுகாப்பு தடைகளை மீற வழிவகுக்கும்.",
"period-am": "AM",
"period-pm": "PM",
"pagecategories": "{{PLURAL:$1|分类}}",
- "category_header": "å\88\86ç±»â\80\9c$1â\80\9dä¸的页面",
+ "category_header": "å\88\86ç±»â\80\9c$1â\80\9dä¸\8b的页面",
"subcategories": "子分类",
"category-media-header": "分类“$1”中的媒体文件",
"category-empty": "<em>本分类目前不含有任何页面或媒体文件。</em>",
"randompage-nopages": "在以下{{PLURAL:$2|名字空间}}中没有页面:$1。",
"randomincategory": "分类中随机页面",
"randomincategory-invalidcategory": "“$1”不是一个有效的分类名称。",
- "randomincategory-nopages": "[[:Category:$1|$1]]å\88\86ç±»ä¸没有页面。",
+ "randomincategory-nopages": "[[:Category:$1|$1]]å\88\86ç±»ä¸\8b没有页面。",
"randomincategory-category": "分类:",
"randomincategory-legend": "分类中随机页面",
"randomincategory-submit": "提交",
"ancientpages": "最老页面",
"move": "移动",
"movethispage": "移动本页",
- "unusedimagestext": "以下文件实际存在,但并没有插入任何页面。请注意,其他网站可能会使用直接URL链接某个文件,因此它即使被实际使用也可能在这里列出。",
+ "unusedimagestext": "存在以下没有插入任何页面的文件。请注意,其他网站可能会使用直接URL链接某个文件,因此它即使被实际使用也可能在这里列出。",
"unusedcategoriestext": "以下分类页面实际存在,即使没有其它页面或分类利用它们。",
"notargettitle": "无目标",
"notargettext": "您还没有指定一个目标页面或用户以进行此项操作。",
"variantname-gan-hant": "hant",
"variantname-kk-cyrl": "kk-cyrl",
"metadata": "元数据",
- "metadata-help": "此文件中包含有扩展的信息。这些信息可能是由数码相机或扫描仪在创建或数字化过程中所添加的。\n\n如果此文件的源文件已经被修改,一些信息在修改后的文件中将不能完全反映出来。",
+ "metadata-help": "此文件中包含有额外的信息。这些信息可能是由数码相机或扫描仪在创建或数字化过程中所添加的。如果已自文件的初始状态修改,一些详细说明可能无法反映修改后的文件。",
"metadata-expand": "显示详细资料",
"metadata-collapse": "隐藏详细资料",
"metadata-fields": "在本信息中所列出的 EXIF 元数据域将包含在图片显示页面,当元数据表损坏时只显示以下信息。\n其他的元数据默认为隐藏。\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
"variantname-gan-hans": "中文(简体)",
"variantname-gan-hant": "中文(繁體)",
"metadata": "詮釋資料",
- "metadata-help": "此檔案包含額外的資訊,可能由數位相機或掃描機所建立的。\n若修改此檔案,部份資訊將無法保留。",
+ "metadata-help": "此檔案包含額外的資訊,可能由數位相機或掃描機所建立的。\n\n如果已自檔案初始狀態修改,一些詳細說明可能無法反映修改後的檔案。",
"metadata-expand": "顯示詳細資料",
"metadata-collapse": "隱藏詳細資料",
"metadata-fields": "在本訊息中所列出的 EXIF 詮釋資料域將包含在圖片顯示頁面,當詮釋資料表損壞時只顯示以下訊息。\n其他的詮釋資料預設為隱藏。\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
margin: 0 0 10px 10px;
}
-td, h3, p, h1, pre {
+h1,
+h3,
+p,
+pre,
+td {
margin: 0 20px 20px 20px;
font-size: 11px;
line-height: 140%;
margin-bottom: 0.2em;
}
-.config-block-label label, .config-label {
+.config-block-label label,
+.config-label {
font-weight: bold;
padding-right: 0.5em;
padding-top: 0.2em;
position: absolute;
cursor: crosshair;
}
-.farbtastic, .farbtastic .wheel {
+.farbtastic,
+.farbtastic .wheel {
width: 195px;
height: 195px;
}
-.farbtastic .color, .farbtastic .overlay {
+.farbtastic .color,
+.farbtastic .overlay {
top: 47px;
left: 47px;
width: 101px;
*
* @author Timo Tijhof, 2011-2012
*/
+/* eslint-env qunit */
( function ( mw, $ ) {
'use strict';
font-size: 1em;
}
-h1, h2, h3, h4, h5, h6 {
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
font-weight: bolder;
}
line-height: 1.6em !important;
}
+/* stylelint-disable selector-list-comma-newline-after */
h2:lang( anp ), h3:lang( anp ), h4:lang( anp ), h5:lang( anp ), h6:lang( anp ),
h2:lang( as ), h3:lang( as ), h4:lang( as ), h5:lang( as ), h6:lang( as ),
h2:lang( bho ), h3:lang( bho ), h4:lang( bho ), h5:lang( bho ), h6:lang( bho ),
h2:lang( te ), h3:lang( te ), h4:lang( te ), h5:lang( te ), h6:lang( te ) {
line-height: 1.2em;
}
+/* stylelint-enable selector-list-comma-newline-after */
/* Localised ordered list numbering for some languages */
ol:lang( azb ) li,
list-style-type: oriya;
}
-#toc ul, .toc ul {
+#toc ul,
+.toc ul {
margin: 0.3em 0;
}
}
/* Images */
-/* @noflip */div.floatright, table.floatright {
+/* @noflip */
+div.floatright,
+table.floatright {
margin: 0 0 0.5em 0.5em;
}
font-style: italic;
}
-/* @noflip */div.floatleft, table.floatleft {
+/* @noflip */
+div.floatleft,
+table.floatleft {
margin: 0 0.5em 0.5em 0;
}
padding-right: 15px;
}
-.mw-body a.external[href$=".ogg"], .mw-body a.external[href$=".OGG"],
-.mw-body a.external[href$=".mid"], .mw-body a.external[href$=".MID"],
-.mw-body a.external[href$=".midi"], .mw-body a.external[href$=".MIDI"],
-.mw-body a.external[href$=".mp3"], .mw-body a.external[href$=".MP3"],
-.mw-body a.external[href$=".wav"], .mw-body a.external[href$=".WAV"],
-.mw-body a.external[href$=".wma"], .mw-body a.external[href$=".WMA"],
+.mw-body a.external[href$=".ogg"],
+.mw-body a.external[href$=".OGG"],
+.mw-body a.external[href$=".mid"],
+.mw-body a.external[href$=".MID"],
+.mw-body a.external[href$=".midi"],
+.mw-body a.external[href$=".MIDI"],
+.mw-body a.external[href$=".mp3"],
+.mw-body a.external[href$=".MP3"],
+.mw-body a.external[href$=".wav"],
+.mw-body a.external[href$=".WAV"],
+.mw-body a.external[href$=".wma"],
+.mw-body a.external[href$=".WMA"],
.link-audio {
background: url( images/audio-ltr.png ) center right no-repeat;
/* @embed */
padding-right: 15px;
}
-.mw-body a.external[href$=".ogm"], .mw-body a.external[href$=".OGM"],
-.mw-body a.external[href$=".avi"], .mw-body a.external[href$=".AVI"],
-.mw-body a.external[href$=".mpeg"], .mw-body a.external[href$=".MPEG"],
-.mw-body a.external[href$=".mpg"], .mw-body a.external[href$=".MPG"],
+.mw-body a.external[href$=".ogm"],
+.mw-body a.external[href$=".OGM"],
+.mw-body a.external[href$=".avi"],
+.mw-body a.external[href$=".AVI"],
+.mw-body a.external[href$=".mpeg"],
+.mw-body a.external[href$=".MPEG"],
+.mw-body a.external[href$=".mpg"],
+.mw-body a.external[href$=".MPG"],
.link-video {
background: url( images/video.png ) center right no-repeat;
/* @embed */
padding-right: 15px;
}
-.mw-body a.external[href$=".pdf"], .mw-body a.external[href$=".PDF"],
-.mw-body a.external[href*=".pdf#"], .mw-body a.external[href*=".PDF#"],
-.mw-body a.external[href*=".pdf?"], .mw-body a.external[href*=".PDF?"],
+.mw-body a.external[href$=".pdf"],
+.mw-body a.external[href$=".PDF"],
+.mw-body a.external[href*=".pdf#"],
+.mw-body a.external[href*=".PDF#"],
+.mw-body a.external[href*=".pdf?"],
+.mw-body a.external[href*=".PDF?"],
.link-document {
background: url( images/document-ltr.png ) center right no-repeat;
/* @embed */
unicode-bidi: isolate;
}
-sup, sub {
+sup,
+sub {
line-height: 1;
}
.mw-image-border > *:first-child > img {
border: 1px solid #ccc;
margin: 3px;
+ background: #fff;
}
/* Hide the caption for frameless and plain floated images */
color: #faa700;
}
-a:hover, a:focus {
+a:hover,
+a:focus {
text-decoration: underline;
}
color: #723;
}
-a.new, #p-personal a.new {
+a.new,
+#p-personal a.new {
color: #ba0000;
}
-a.new:visited, #p-personal a.new:visited {
+a.new:visited,
+#p-personal a.new:visited {
color: #a55858;
}
margin-bottom: 0.1em;
}
-pre, code, tt, kbd, samp, .mw-code {
+pre,
+code,
+tt,
+kbd,
+samp,
+.mw-code {
/*
* Some browsers will render the monospace text too small, namely Firefox, Chrome and Safari.
* Specifying any valid, second value will trigger correct behavior without forcing a different font.
}
/* Common for Special:Allpages and Special:PrefixIndex */
-.mw-allpages-body, .mw-prefixindex-body {
+.mw-allpages-body,
+.mw-prefixindex-body {
columns: 22em 3;
-moz-columns: 22em 3;
-webkit-columns: 22em 3;
.iw-headline {
font-weight: bold;
- font-size: 1rem;
- font-size: 16px;
- opacity: 0.7;
+ font-size: 1rem;
+ font-size: 16px;
+ opacity: 0.7;
}
.iw-results {
- list-style: none;
+ list-style: none;
margin: 0;
}
.iw-resultset {
margin-bottom: 1.2em;
background-color: #f2f4f7;
- vertical-align: top;
- width: 100%;
- float: left;
- list-style-type: none;
+ vertical-align: top;
+ width: 100%;
+ float: left;
+ list-style-type: none;
}
/* clearfix */
.iw-result:after {
- visibility: hidden;
+ visibility: hidden;
display: block;
font-size: 0;
content: " ";
}
* html .interwiki-result { /* IE6 */
- zoom: 1;
+ zoom: 1;
}
*:first-child + html .iw-resultset { /* IE7 */
- zoom: 1;
+ zoom: 1;
}
/* padding each .iw-resultset section seperately.
.iw-result__title,
.iw-result__content,
.iw-result__footer {
- padding: 0.25em 0.85em;
+ padding: 0.25em 0.85em;
}
/* definition titles appear inline,
to resemble a traditional dictionary definition */
.iw-resultset--definition .iw-result__title {
- display: inline;
- padding: 0;
+ display: inline;
+ padding: 0;
}
.iw-resultset > div:first-child {
- padding-top: 0.85em;
+ padding-top: 0.85em;
}
.iw-resultset > div:last-child {
- padding-bottom: 0.85em;
+ padding-bottom: 0.85em;
}
.iw-result__title {
- font-size: 16px; /* rem fallback */
- font-size: 1rem;
+ font-size: 16px; /* rem fallback */
+ font-size: 1rem;
}
.iw-result__title a.extiw {
- color: #252525;
- font-weight: bold;
+ color: #252525;
+ font-weight: bold;
}
.iw-result__content:after { /* clearfix */
- visibility: hidden;
- display: block;
- font-size: 0;
- content: " ";
- clear: both;
- height: 0;
+ visibility: hidden;
+ display: block;
+ font-size: 0;
+ content: " ";
+ clear: both;
+ height: 0;
}
.iw-result__footer {
- float: right;
+ float: right;
}
.iw-result__icon {
- display: inline-block;
- width: 24px;
- height: 24px;
- vertical-align: middle;
- margin-right: 0.25em;
- background: url( images/special.search/definition-icon.svg ) no-repeat 0 0;
- background-size: 100% 100%;
+ display: inline-block;
+ width: 24px;
+ height: 24px;
+ vertical-align: middle;
+ margin-right: 0.25em;
+ background: url( images/special.search/definition-icon.svg ) no-repeat 0 0;
+ background-size: 100% 100%;
}
@interwikiContentTypes: definition, travel, quotation, book, course, news, textbook, image;
.generate-iwIcons();
.generate-iwIcons( @i:1 ) when ( @i =< length( @interwikiContentTypes ) ) {
- @iwIcon: extract( @interwikiContentTypes, @i );
+ @iwIcon: extract( @interwikiContentTypes, @i );
- .iw-result__icon--@{iwIcon} {
- /* stylelint-disable-next-line function-url-quotes */
- background-image: url( 'images/special.search/@{iwIcon}-icon.png' );
- /* stylelint-disable-next-line function-url-quotes */
- background-image: url( 'images/special.search/@{iwIcon}-icon.svg' );
- }
+ .iw-result__icon--@{iwIcon} {
+ /* stylelint-disable-next-line function-url-quotes */
+ background-image: url( 'images/special.search/@{iwIcon}-icon.png' );
+ /* stylelint-disable-next-line function-url-quotes */
+ background-image: url( 'images/special.search/@{iwIcon}-icon.svg' );
+ }
- .generate-iwIcons( @i + 1 );
+ .generate-iwIcons( @i + 1 );
}
/* image search result */
.iw-result__mini-gallery {
- position: relative;
- float: left;
- width: 60%;
- height: 200px;
- box-sizing: border-box;
- padding: 0.25rem;
+ position: relative;
+ float: left;
+ width: 60%;
+ height: 200px;
+ box-sizing: border-box;
+ padding: 0.25rem;
}
-.iw-result__mini-gallery__image {
- display: block;
- position: relative;
- width: 100%;
- height: 100%;
- background-size: cover;
- background-repeat: no-repeat;
- background-position: center center;
+/* second and third images are small */
+.iw-result__mini-gallery:nth-child( 2 ),
+.iw-result__mini-gallery:nth-child( 3 ) { /* stylelint-disable-line indentation */
+ width: 40%;
+ height: 100px;
}
-.iw-result__mini-gallery__image:hover > .iw-result__mini-gallery__caption {
- visibility: visible;
+.iw-result__mini-gallery__image {
+ display: block;
+ position: relative;
+ width: 100%;
+ height: 100%;
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-position: center center;
}
.iw-result__mini-gallery__image > .iw-result__mini-gallery__caption { /* image gallery text */
- visibility: hidden;
- position: absolute;
- bottom: 0;
- left: 0;
- text-align: center;
- color: #fff;
- text-shadow: 0 0 10px rgba( 0, 0, 0, 0.4 ); /* improves legibility on white background*/
- font-size: 0.8em;
- padding: 5px;
- background-color: rgba( 0, 0, 0, 0.5 );
+ visibility: hidden;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ text-align: center;
+ color: #fff;
+ text-shadow: 0 0 10px rgba( 0, 0, 0, 0.4 ); /* improves legibility on white background*/
+ font-size: 0.8em;
+ padding: 5px;
+ background-color: rgba( 0, 0, 0, 0.5 );
}
-.iw-result__mini-gallery:nth-child(2),
-.iw-result__mini-gallery:nth-child(3) { /* second and third images are small */
- width: 40%;
- height: 100px;
+.iw-result__mini-gallery__image:hover > .iw-result__mini-gallery__caption {
+ visibility: visible;
}
/* different types of interwiki result boxes */
/* quotation box */
.iw-resultset--quotation .iw-result__content {
- border-left: 4px solid #afb1b5;
- margin-left: 1em;
- padding-top: 0;
- margin-top: 0.25em;
+ border-left: 4px solid #afb1b5;
+ margin-left: 1em;
+ padding-top: 0;
+ margin-top: 0.25em;
}
-.iw-resultset--quotation .iw-result__title{
- margin-left: 1em;
+.iw-resultset--quotation .iw-result__title {
+ margin-left: 1em;
}
-.iw-result--quotation .iw-result__title:before{
- content: ' — ';
- display: inline-block;
+.iw-result--quotation .iw-result__title:before {
+ content: ' — ';
+ display: inline-block;
}
.iw-result--quotation .iw-result__footer {
- text-align: right;
+ text-align: right;
}
/* no results
*/
.mw-search-nonefound ~ #mw-search-interwiki {
- width: 100%;
+ width: 100%;
}
.mw-search-nonefound ~ #mw-search-interwiki .iw-resultset {
- width: 30%;
- max-width: 300px;
- margin-left: 0.5em;
- margin-right: 0.5em;
+ width: 30%;
+ max-width: 300px;
+ margin-left: 0.5em;
+ margin-right: 0.5em;
}
/* mobile */
@media only screen and ( max-width: 768px ) {
- #mw-interwiki-results {
- width: 100%;
- }
- .mw-search-results {
- max-width: none !important;
- }
- .iw-resultset {
- width: 45% !important;
- margin-left: 0.5em !important;
- margin-right: 0.5em !important;
- }
+ #mw-interwiki-results {
+ width: 100%;
+ }
+ .mw-search-results {
+ max-width: none !important;
+ }
+ .iw-resultset {
+ width: 45% !important;
+ margin-left: 0.5em !important;
+ margin-right: 0.5em !important;
+ }
}
@media only screen and ( max-width: 600px ) {
- .iw-resultset {
- width: 100% !important;
- margin-left: 0 !important;
- margin-right: 0 !important;
- max-width: none !important;
- }
-}
-
-/* Evil temporary hax for cawiki */
-#sisterproject {
- display: none;
+ .iw-resultset {
+ width: 100% !important;
+ margin-left: 0 !important;
+ margin-right: 0 !important;
+ max-width: none !important;
+ }
}
// Remove the inner padding and cancel buttons in Chrome on OS X and Safari on OS X
&::-webkit-search-cancel-button,
&::-webkit-search-decoration {
- -webkit-appearance: none;
+ -webkit-appearance: none;
}
}
}
+@import 'mediawiki.mixins';
+
.mw-widgets-stashedFileWidget {
display: inline-block;
vertical-align: middle;
vertical-align: middle;
position: relative;
overflow: hidden;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
+ .box-sizing( border-box );
> .mw-widgets-stashedFileWidget-label {
line-height: 2.3em;
margin: 0;
overflow: hidden;
white-space: nowrap;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
+ .box-sizing( border-box );
text-overflow: ellipsis;
left: 0.5em;
right: 2.375em;
}
}
- &.oo-ui-optionWidget-highlighted, &.oo-ui-optionWidget-selected {
+ &.oo-ui-optionWidget-highlighted,
+ &.oo-ui-optionWidget-selected {
&.oo-ui-iconElement > .mw-widget-titleOptionWidget-hasImage {
opacity: 1;
}
'stashwrongowner',
'stashnosuchfilekey'
];
- mw.log.deprecate( mw.Api, 'errors', mw.Api.errors, 'mw.Api.errors' );
+ mw.log.deprecate( mw.Api, 'errors', mw.Api.errors, null, 'mw.Api.errors' );
/**
* @static
'duplicate',
'exists'
];
- mw.log.deprecate( mw.Api, 'warnings', mw.Api.warnings, 'mw.Api.warnings' );
+ mw.log.deprecate( mw.Api, 'warnings', mw.Api.warnings, null, 'mw.Api.warnings' );
}( mediaWiki, jQuery ) );
margin-left: 4px;
}
-.mw-icon-question:lang(ar),
-.mw-icon-question:lang(fa),
-.mw-icon-question:lang(ur) {
+/* stylelint-disable indentation */
+.mw-icon-question:lang( ar ),
+.mw-icon-question:lang( fa ),
+.mw-icon-question:lang( ur ) {
-webkit-transform: scaleX( -1 );
-ms-transform: scaleX( -1 );
transform: scaleX( -1 );
width: 20em;
}
-.apihelp-deprecated, .apihelp-flag-deprecated,
+.apihelp-deprecated,
+.apihelp-flag-deprecated,
.apihelp-flag-internal strong {
font-weight: bold;
color: #f00;
display: inline;
}
/* Display nested lists inline */
-.hlist dl dl, .hlist dl ol, .hlist dl ul,
-.hlist ol dl, .hlist ol ol, .hlist ol ul,
-.hlist ul dl, .hlist ul ol, .hlist ul ul {
+.hlist dl dl,
+.hlist dl ol,
+.hlist dl ul,
+.hlist ol dl,
+.hlist ol ol,
+.hlist ol ul,
+.hlist ul dl,
+.hlist ul ol,
+.hlist ul ul {
display: inline;
}
/* Generate interpuncts */
content: none;
}
/* Add parentheses around nested lists */
-.hlist dd dd:first-child:before, .hlist dd dt:first-child:before, .hlist dd li:first-child:before,
-.hlist dt dd:first-child:before, .hlist dt dt:first-child:before, .hlist dt li:first-child:before,
-.hlist li dd:first-child:before, .hlist li dt:first-child:before, .hlist li li:first-child:before {
+.hlist dd dd:first-child:before,
+.hlist dd dt:first-child:before,
+.hlist dd li:first-child:before,
+.hlist dt dd:first-child:before,
+.hlist dt dt:first-child:before,
+.hlist dt li:first-child:before,
+.hlist li dd:first-child:before,
+.hlist li dt:first-child:before,
+.hlist li li:first-child:before {
content: "(";
font-weight: normal;
}
-.hlist dd dd:last-child:after, .hlist dd dt:last-child:after, .hlist dd li:last-child:after,
-.hlist dt dd:last-child:after, .hlist dt dt:last-child:after, .hlist dt li:last-child:after,
-.hlist li dd:last-child:after, .hlist li dt:last-child:after, .hlist li li:last-child:after {
+.hlist dd dd:last-child:after,
+.hlist dd dt:last-child:after,
+.hlist dd li:last-child:after,
+.hlist dt dd:last-child:after,
+.hlist dt dt:last-child:after,
+.hlist dt li:last-child:after,
+.hlist li dd:last-child:after,
+.hlist li dt:last-child:after,
+.hlist li li:last-child:after {
content: ")";
font-weight: normal;
}
/* For IE8 */
-.hlist dd dd.hlist-last-child:after, .hlist dd dt.hlist-last-child:after, .hlist dd li.hlist-last-child:after,
-.hlist dt dd.hlist-last-child:after, .hlist dt dt.hlist-last-child:after, .hlist dt li.hlist-last-child:after,
-.hlist li dd.hlist-last-child:after, .hlist li dt.hlist-last-child:after, .hlist li li.hlist-last-child:after {
+.hlist dd dd.hlist-last-child:after,
+.hlist dd dt.hlist-last-child:after,
+.hlist dd li.hlist-last-child:after,
+.hlist dt dd.hlist-last-child:after,
+.hlist dt dt.hlist-last-child:after,
+.hlist dt li.hlist-last-child:after,
+.hlist li dd.hlist-last-child:after,
+.hlist li dt.hlist-last-child:after,
+.hlist li li.hlist-last-child:after {
content: ")";
font-weight: normal;
}
.removeAttr( 'height' );
// Stretch image to take up the required size
- if ( this.$thumbnail.width() > this.$thumbnail.height() ) {
- this.$img.attr( 'width', this.imageWidth + 'px' );
- } else {
- this.$img.attr( 'height', this.imageHeight + 'px' );
- }
+ this.$img.attr( 'height', ( this.imageHeight - this.$imgCaption.outerHeight() ) + 'px' );
// Make the image smaller in case the current image
// size is larger than the original file size.
var imageLi = this.getCurrentImage(),
caption = imageLi.find( '.gallerytext' );
- // Highlight current thumbnail
+ // The order of the following is important for size calculations
+ // 1. Highlight current thumbnail
this.$gallery
.find( '.gallerybox.slideshow-current' )
.removeClass( 'slideshow-current' );
imageLi.addClass( 'slideshow-current' );
- // Show thumbnail stretched to the right size while the image loads
+ // 2. Show thumbnail
this.$thumbnail = imageLi.find( 'img' );
this.$img.attr( 'src', this.$thumbnail.attr( 'src' ) );
this.$img.attr( 'alt', this.$thumbnail.attr( 'alt' ) );
this.$imgLink.attr( 'href', imageLi.find( 'a' ).eq( 0 ).attr( 'href' ) );
- this.setImageSize();
- // Copy caption
+ // 3. Copy caption
this.$imgCaption
.empty()
.append( caption.clone() );
- // Load image at the required size
+ // 4. Stretch thumbnail to correct size
+ this.setImageSize();
+
+ // 5. Load image at the required size
this.loadImage( this.$thumbnail ).done( function ( info, $img ) {
// Show this image to the user only if its still the current one
if ( this.$thumbnail.attr( 'src' ) === $img.attr( 'src' ) ) {
display: inline-block;
}
-ul.gallery, li.gallerybox {
+ul.gallery,
+li.gallerybox {
zoom: 1;
*display: inline;
}
!! end
-!!test
-Gallery override link with WikiLink (T36852)
-!! wikitext
-<gallery>
-File:foobar.jpg|caption|alt=galleryalt|link=InterWikiLink
-</gallery>
-!! html
-<ul class="gallery mw-gallery-traditional">
- <li class="gallerybox" style="width: 155px"><div style="width: 155px">
- <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/InterWikiLink"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
- <div class="gallerytext">
-<p>caption
-</p>
- </div>
- </div></li>
-</ul>
-
-!! end
-
!!test
Language parser function
!! wikitext
--- /dev/null
+<?php
+
+/**
+ * @covers ClassCollector
+ */
+class ClassCollectorTest extends PHPUnit_Framework_TestCase {
+
+ public static function provideCases() {
+ return [
+ [
+ "class Foo {}",
+ [ 'Foo' ],
+ ],
+ [
+ "namespace Example;\nclass Foo {}\nclass Bar {}",
+ [ 'Example\Foo', 'Example\Bar' ],
+ ],
+ [
+ "class_alias( 'Foo', 'Bar' );",
+ [ 'Bar' ],
+ ],
+ [
+ "namespace Example;\nclass Foo {}\nclass_alias( 'Example\Foo', 'Foo' );",
+ [ 'Example\Foo', 'Foo' ],
+ ],
+ [
+ "namespace Example;\nclass Foo {}\nclass_alias( 'Example\Foo', 'Bar' );",
+ [ 'Example\Foo', 'Bar' ],
+ ],
+ [
+ "class_alias( Foo::class, 'Bar' );",
+ [ 'Bar' ],
+ ],
+ [
+ "namespace Example;\nclass Foo {}\nclass_alias( Foo::class, 'Bar' );",
+ [ 'Example\Foo', 'Bar' ],
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider provideCases
+ */
+ public function testGetClasses( $code, array $classes, $message = null ) {
+ $cc = new ClassCollector();
+ $this->assertEquals( $classes, $cc->getClasses( "<?php\n$code" ), $message );
+ }
+}
}
// We could use token_get_all() here, but this is faster
+ // Note: Keep in sync with ClassCollector
$matches = [];
preg_match_all( '/
^ [\t ]* (?:
([\'"]) (?P<original> [^\'"]+) \g{-2} \s* , \s*
([\'"]) (?P<alias> [^\'"]+ ) \g{-2} \s*
\) \s* ;
+ |
+ class_alias \s* \( \s*
+ (?P<originalStatic> [a-zA-Z0-9_]+)::class \s* , \s*
+ ([\'"]) (?P<aliasString> [^\'"]+ ) \g{-2} \s*
+ \) \s* ;
)
/imx', $contents, $matches, PREG_SET_ORDER );
foreach ( $matches as $match ) {
if ( !empty( $match['class'] ) ) {
+ // 'class Foo {}'
$class = $fileNamespace . $match['class'];
$actual[$class] = $file;
$classesInFile[$class] = true;
} else {
- $aliasesInFile[$match['alias']] = $match['original'];
+ if ( !empty( $match['original'] ) ) {
+ // 'class_alias( "Foo", "Bar" );'
+ $aliasesInFile[$match['alias']] = $match['original'];
+ } else {
+ // 'class_alias( Foo::class, "Bar" );'
+ $aliasesInFile[$match['aliasString']] = $fileNamespace . $match['originalStatic'];
+ }
}
}
--- /dev/null
+{
+ "extends": "../../.eslintrc.json",
+ "env": {
+ "qunit": true
+ },
+ "globals": {
+ "sinon": false
+ },
+ "rules": {
+ "operator-linebreak": 0,
+ "quote-props": [ "error", "as-needed" ],
+ "valid-jsdoc": 0
+ }
+}
. "// languages, and parser modes. Intended for use by a unit test framework by looping\n"
. "// through the object and comparing its parser return value with the 'result' property.\n"
. '// Last generated with ' . basename( __FILE__ ) . ' at ' . gmdate( 'r' ) . "\n"
- . "//jscs:disable\n"
+ . "/* eslint-disable */\n"
. "\n"
. 'mediaWiki.libs.phpParserData = ' . FormatJson::encode( $phpParserData, true ) . ";\n";
// languages, and parser modes. Intended for use by a unit test framework by looping
// through the object and comparing its parser return value with the 'result' property.
// Last generated with generateJqueryMsgData.php at Fri, 10 Jul 2015 11:44:08 +0000
-//jscs:disable
+/* eslint-disable */
mediaWiki.libs.phpParserData = {
"messages": {
-/*global CompletenessTest, sinon */
+/* global CompletenessTest, sinon */
( function ( $, mw, QUnit ) {
'use strict';
- var mwTestIgnore, mwTester, addons;
+ var mwTestIgnore, addons;
/**
* Add bogus to url to prevent IE crazy caching
QUnit.config.testTimeout = 60 * 1000;
// Reduce default animation duration from 400ms to 0ms for unit tests
+ // eslint-disable-next-line no-underscore-dangle
$.fx.speeds._default = 0;
// Add a checkbox to QUnit header to toggle MediaWiki ResourceLoader debug mode.
return false;
};
- mwTester = new CompletenessTest( mw, mwTestIgnore );
+ // eslint-disable-next-line no-new
+ new CompletenessTest( mw, mwTestIgnore );
}
/**
}
function freshMessagesCopy( custom ) {
- return $.extend( /*deep=*/true, {}, liveMessages.get(), custom );
+ return $.extend( /* deep */true, {}, liveMessages.get(), custom );
}
/**
( function ( $ ) {
+ var getAccessKeyPrefixTestData, updateTooltipAccessKeysTestData;
+
QUnit.module( 'jquery.accessKeyLabel', QUnit.newMwEnvironment( {
messages: {
brackets: '[$1]',
}
} ) );
- var getAccessKeyPrefixTestData = [
- // ua string, platform string, expected prefix
- // Internet Explorer
- [ 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', 'Win32', 'alt-' ],
- [ 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)', 'Win32', 'alt-' ],
- [ 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; rv:11.0) like Gecko', 'Win64', 'alt-' ],
- [ 'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10136', 'Win64', 'alt-' ],
- // Firefox
- [ 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.19) Gecko/20110420 Firefox/3.5.19', 'MacIntel', 'ctrl-' ],
- [ 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110422 Ubuntu/10.10 (maverick) Firefox/3.6.17', 'Linux i686', 'alt-shift-' ],
- [ 'Mozilla/5.0 (Windows NT 6.0; rv:2.0.1) Gecko/20100101 Firefox/4.0.1', 'Win32', 'alt-shift-' ],
- [ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:50.0) Gecko/20100101 Firefox/50.0', 'MacIntel', 'ctrl-option-' ],
- [ 'Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20121202 Firefox/17.0 Iceweasel/17.0.1', 'Linux 1686', 'alt-shift-' ],
- [ 'Mozilla/5.0 (Windows NT 5.2; U; de; rv:1.8.0) Gecko/20060728 Firefox/1.5.0', 'Win32', 'alt-' ],
- // Safari / Konqueror
- [ 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; nl-nl) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7', 'MacIntel', 'ctrl-option-' ],
- [ 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_7; de-de) AppleWebKit/525.28.3 (KHTML, like Gecko) Version/3.2.3 Safari/525.28.3', 'MacIntel', 'ctrl-' ],
- [ 'Mozilla/5.0 (Windows; U; Windows NT 5.1; cs-CZ) AppleWebKit/525.28.3 (KHTML, like Gecko) Version/3.2.3 Safari/525.29', 'Win32', 'alt-' ],
- [ 'Mozilla/5.0 (Windows; U; Windows NT 6.0; cs-CZ) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7', 'Win32', 'alt-' ],
- [ 'Mozilla/5.0 (X11; Linux i686) KHTML/4.9.1 (like Gecko) Konqueror/4.9', 'Linux i686', 'ctrl-' ],
- // Opera
- [ 'Opera/9.80 (Windows NT 5.1)', 'Win32', 'shift-esc-' ],
- [ 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.52 Safari/537.36 OPR/15.0.1147.130', 'Win32', 'alt-shift-' ],
- // Chrome
- [ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_5_8) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.112 Safari/534.30', 'MacIntel', 'ctrl-option-' ],
- [ 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.68 Safari/534.30', 'Linux i686', 'alt-shift-' ],
- // Unknown! Note: These aren't necessarily *right*, this is just
- // testing that we're getting the expected output based on the
- // platform.
- [ 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-US; rv:1.0.1) Gecko/20021111 Chimera/0.6', 'MacPPC', 'ctrl-' ],
- [ 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3a) Gecko/20021207 Phoenix/0.5', 'Linux i686', 'alt-' ]
- ],
- // strings appended to title to make sure updateTooltipAccessKeys handles them correctly
- updateTooltipAccessKeysTestData = [ '', ' [a]', ' [test-a]', ' [alt-b]' ];
+ getAccessKeyPrefixTestData = [
+ // ua string, platform string, expected prefix
+ // Internet Explorer
+ [ 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', 'Win32', 'alt-' ],
+ [ 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)', 'Win32', 'alt-' ],
+ [ 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; rv:11.0) like Gecko', 'Win64', 'alt-' ],
+ [ 'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10136', 'Win64', 'alt-' ],
+ // Firefox
+ [ 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.19) Gecko/20110420 Firefox/3.5.19', 'MacIntel', 'ctrl-' ],
+ [ 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110422 Ubuntu/10.10 (maverick) Firefox/3.6.17', 'Linux i686', 'alt-shift-' ],
+ [ 'Mozilla/5.0 (Windows NT 6.0; rv:2.0.1) Gecko/20100101 Firefox/4.0.1', 'Win32', 'alt-shift-' ],
+ [ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:50.0) Gecko/20100101 Firefox/50.0', 'MacIntel', 'ctrl-option-' ],
+ [ 'Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20121202 Firefox/17.0 Iceweasel/17.0.1', 'Linux 1686', 'alt-shift-' ],
+ [ 'Mozilla/5.0 (Windows NT 5.2; U; de; rv:1.8.0) Gecko/20060728 Firefox/1.5.0', 'Win32', 'alt-' ],
+ // Safari / Konqueror
+ [ 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; nl-nl) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7', 'MacIntel', 'ctrl-option-' ],
+ [ 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_7; de-de) AppleWebKit/525.28.3 (KHTML, like Gecko) Version/3.2.3 Safari/525.28.3', 'MacIntel', 'ctrl-' ],
+ [ 'Mozilla/5.0 (Windows; U; Windows NT 5.1; cs-CZ) AppleWebKit/525.28.3 (KHTML, like Gecko) Version/3.2.3 Safari/525.29', 'Win32', 'alt-' ],
+ [ 'Mozilla/5.0 (Windows; U; Windows NT 6.0; cs-CZ) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7', 'Win32', 'alt-' ],
+ [ 'Mozilla/5.0 (X11; Linux i686) KHTML/4.9.1 (like Gecko) Konqueror/4.9', 'Linux i686', 'ctrl-' ],
+ // Opera
+ [ 'Opera/9.80 (Windows NT 5.1)', 'Win32', 'shift-esc-' ],
+ [ 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.52 Safari/537.36 OPR/15.0.1147.130', 'Win32', 'alt-shift-' ],
+ // Chrome
+ [ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_5_8) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.112 Safari/534.30', 'MacIntel', 'ctrl-option-' ],
+ [ 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.68 Safari/534.30', 'Linux i686', 'alt-shift-' ],
+ // Unknown! Note: These aren't necessarily *right*, this is just
+ // testing that we're getting the expected output based on the
+ // platform.
+ [ 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-US; rv:1.0.1) Gecko/20021111 Chimera/0.6', 'MacPPC', 'ctrl-' ],
+ [ 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3a) Gecko/20021207 Phoenix/0.5', 'Linux i686', 'alt-' ]
+ ];
+ // strings appended to title to make sure updateTooltipAccessKeys handles them correctly
+ updateTooltipAccessKeysTestData = [ '', ' [a]', ' [test-a]', ' [alt-b]' ];
function makeInput( title, accessKey ) {
// The properties aren't escaped, so make sure you don't call this function with values that need to be escaped!
} );
QUnit.test( 'updateTooltipAccessKeys - with access key', function ( assert ) {
- $.fn.updateTooltipAccessKeys.setTestMode( true );
var i, oldTitle, $input, newTitle;
+ $.fn.updateTooltipAccessKeys.setTestMode( true );
for ( i = 0; i < updateTooltipAccessKeysTestData.length; i++ ) {
oldTitle = 'Title' + updateTooltipAccessKeysTestData[ i ];
$input = $( makeInput( oldTitle, 'a' ) );
} );
QUnit.test( 'updateTooltipAccessKeys with label element', function ( assert ) {
+ var html, $label, $input;
$.fn.updateTooltipAccessKeys.setTestMode( true );
- var html = '<label for="testInput" title="Title">Label</label><input id="testInput" accessKey="a" />',
- $label, $input;
+ html = '<label for="testInput" title="Title">Label</label><input id="testInput" accessKey="a" />';
$( '#qunit-fixture' ).html( html );
$label = $( '#qunit-fixture label' );
$input = $( '#qunit-fixture input' );
} );
QUnit.test( 'updateTooltipAccessKeys with label element as parent', function ( assert ) {
+ var html, $label, $input;
$.fn.updateTooltipAccessKeys.setTestMode( true );
- var html = '<label title="Title">Label<input id="testInput" accessKey="a" /></label>',
- $label, $input;
+ html = '<label title="Title">Label<input id="testInput" accessKey="a" /></label>';
$( '#qunit-fixture' ).html( html );
$label = $( '#qunit-fixture label' );
$input = $( '#qunit-fixture input' );
expected: ''
}, options );
- QUnit.asyncTest( opt.description, 1, function ( assert ) {
- setTimeout( function () {
- opt.$input.appendTo( '#qunit-fixture' );
+ QUnit.test( opt.description, function ( assert ) {
+ opt.$input.appendTo( '#qunit-fixture' );
- // Simulate pressing keys for each of the sample characters
- addChars( opt.$input, opt.sample );
+ // Simulate pressing keys for each of the sample characters
+ addChars( opt.$input, opt.sample );
- assert.equal(
- opt.$input.val(),
- opt.expected,
- 'New value matches the expected string'
- );
-
- QUnit.start();
- } );
+ assert.equal(
+ opt.$input.val(),
+ opt.expected,
+ 'New value matches the expected string'
+ );
} );
}
} );
QUnit.test( 'Confirm properties and attributes set', function ( assert ) {
- var $el, $elA, $elB;
+ var $el;
$el = $( '<input>' ).attr( 'type', 'text' )
.attr( 'maxlength', '7' )
assert.strictEqual( $el.attr( 'maxlength' ), undefined, 'maxlength attribute removed for limit with callback' );
- $elA = $( '<input>' ).attr( 'type', 'text' )
+ $( '<input>' ).attr( 'type', 'text' )
.addClass( 'mw-test-byteLimit-foo' )
.attr( 'maxlength', '7' )
.appendTo( '#qunit-fixture' );
- $elB = $( '<input>' ).attr( 'type', 'text' )
+ $( '<input>' ).attr( 'type', 'text' )
.addClass( 'mw-test-byteLimit-foo' )
.attr( 'maxlength', '12' )
.appendTo( '#qunit-fixture' );
QUnit.test( 'Trim from insertion when limit exceeded', function ( assert ) {
var $el;
- // Use a new <input /> because the bug only occurs on the first time
+ // Use a new <input> because the bug only occurs on the first time
// the limit it reached (T42850)
$el = $( '<input>' ).attr( 'type', 'text' )
.appendTo( '#qunit-fixture' )
QUnit.test( 'getAttrs()', function ( assert ) {
var attrs = {
foo: 'bar',
- 'class': 'lorem',
+ class: 'lorem',
'data-foo': 'data value'
},
$el = $( '<div>' ).attr( attrs );
} );
QUnit.test( 'bracketedDevicePixelRatio', function ( assert ) {
- var devicePixelRatio = $.devicePixelRatio();
- assert.equal( typeof devicePixelRatio, 'number', '$.bracketedDevicePixelRatio() returns a number' );
+ var ratio = $.bracketedDevicePixelRatio();
+ assert.equal( typeof ratio, 'number', '$.bracketedDevicePixelRatio() returns a number' );
} );
QUnit.test( 'bracketDevicePixelRatio', function ( assert ) {
QUnit.module( 'jquery.highlightText', QUnit.newMwEnvironment() );
QUnit.test( 'Check', function ( assert ) {
- var $fixture, cases = [
- {
- desc: 'Test 001',
- text: 'Blue Öyster Cult',
- highlight: 'Blue',
- expected: '<span class="highlight">Blue</span> Öyster Cult'
- },
- {
- desc: 'Test 002',
- text: 'Blue Öyster Cult',
- highlight: 'Blue ',
- expected: '<span class="highlight">Blue</span> Öyster Cult'
- },
- {
- desc: 'Test 003',
- text: 'Blue Öyster Cult',
- highlight: 'Blue Ö',
- expected: '<span class="highlight">Blue</span> <span class="highlight">Ö</span>yster Cult'
- },
- {
- desc: 'Test 004',
- text: 'Blue Öyster Cult',
- highlight: 'Blue Öy',
- expected: '<span class="highlight">Blue</span> <span class="highlight">Öy</span>ster Cult'
- },
- {
- desc: 'Test 005',
- text: 'Blue Öyster Cult',
- highlight: ' Blue',
- expected: '<span class="highlight">Blue</span> Öyster Cult'
- },
- {
- desc: 'Test 006',
- text: 'Blue Öyster Cult',
- highlight: ' Blue ',
- expected: '<span class="highlight">Blue</span> Öyster Cult'
- },
- {
- desc: 'Test 007',
- text: 'Blue Öyster Cult',
- highlight: ' Blue Ö',
- expected: '<span class="highlight">Blue</span> <span class="highlight">Ö</span>yster Cult'
- },
- {
- desc: 'Test 008',
- text: 'Blue Öyster Cult',
- highlight: ' Blue Öy',
- expected: '<span class="highlight">Blue</span> <span class="highlight">Öy</span>ster Cult'
- },
- {
- desc: 'Test 009: Highlighter broken on starting Umlaut?',
- text: 'Österreich',
- highlight: 'Österreich',
- expected: '<span class="highlight">Österreich</span>'
- },
- {
- desc: 'Test 010: Highlighter broken on starting Umlaut?',
- text: 'Österreich',
- highlight: 'Ö',
- expected: '<span class="highlight">Ö</span>sterreich'
- },
- {
- desc: 'Test 011: Highlighter broken on starting Umlaut?',
- text: 'Österreich',
- highlight: 'Öst',
- expected: '<span class="highlight">Öst</span>erreich'
- },
- {
- desc: 'Test 012: Highlighter broken on starting Umlaut?',
- text: 'Österreich',
- highlight: 'Oe',
- expected: 'Österreich'
- },
- {
- desc: 'Test 013: Highlighter broken on punctuation mark?',
- text: 'So good. To be there',
- highlight: 'good',
- expected: 'So <span class="highlight">good</span>. To be there'
- },
- {
- desc: 'Test 014: Highlighter broken on space?',
- text: 'So good. To be there',
- highlight: 'be',
- expected: 'So good. To <span class="highlight">be</span> there'
- },
- {
- desc: 'Test 015: Highlighter broken on space?',
- text: 'So good. To be there',
- highlight: ' be',
- expected: 'So good. To <span class="highlight">be</span> there'
- },
- {
- desc: 'Test 016: Highlighter broken on space?',
- text: 'So good. To be there',
- highlight: 'be ',
- expected: 'So good. To <span class="highlight">be</span> there'
- },
- {
- desc: 'Test 017: Highlighter broken on space?',
- text: 'So good. To be there',
- highlight: ' be ',
- expected: 'So good. To <span class="highlight">be</span> there'
- },
- {
- desc: 'Test 018: en de Highlighter broken on special character at the end?',
- text: 'So good. xbß',
- highlight: 'xbß',
- expected: 'So good. <span class="highlight">xbß</span>'
- },
- {
- desc: 'Test 019: en de Highlighter broken on special character at the end?',
- text: 'So good. xbß.',
- highlight: 'xbß.',
- expected: 'So good. <span class="highlight">xbß.</span>'
- },
- {
- desc: 'Test 020: RTL he Hebrew',
- text: 'חסיד אומות העולם',
- highlight: 'חסיד אומות העולם',
- expected: '<span class="highlight">חסיד</span> <span class="highlight">אומות</span> <span class="highlight">העולם</span>'
- },
- {
- desc: 'Test 021: RTL he Hebrew',
- text: 'חסיד אומות העולם',
- highlight: 'חסי',
- expected: '<span class="highlight">חסי</span>ד אומות העולם'
- },
- {
- desc: 'Test 022: ja Japanese',
- text: '諸国民の中の正義の人',
- highlight: '諸国民の中の正義の人',
- expected: '<span class="highlight">諸国民の中の正義の人</span>'
- },
- {
- desc: 'Test 023: ja Japanese',
- text: '諸国民の中の正義の人',
- highlight: '諸国',
- expected: '<span class="highlight">諸国</span>民の中の正義の人'
- },
- {
- desc: 'Test 024: fr French text and « french quotes » (guillemets)',
- text: '« L\'oiseau est sur l’île »',
- highlight: '« L\'oiseau est sur l’île »',
- expected: '<span class="highlight">«</span> <span class="highlight">L\'oiseau</span> <span class="highlight">est</span> <span class="highlight">sur</span> <span class="highlight">l’île</span> <span class="highlight">»</span>'
- },
- {
- desc: 'Test 025: fr French text and « french quotes » (guillemets)',
- text: '« L\'oiseau est sur l’île »',
- highlight: '« L\'oise',
- expected: '<span class="highlight">«</span> <span class="highlight">L\'oise</span>au est sur l’île »'
- },
- {
- desc: 'Test 025a: fr French text and « french quotes » (guillemets) - does it match the single strings "«" and "L" separately?',
- text: '« L\'oiseau est sur l’île »',
- highlight: '« L',
- expected: '<span class="highlight">«</span> <span class="highlight">L</span>\'oiseau est sur <span class="highlight">l</span>’île »'
- },
- {
- desc: 'Test 026: ru Russian',
- text: 'Праведники мира',
- highlight: 'Праведники мира',
- expected: '<span class="highlight">Праведники</span> <span class="highlight">мира</span>'
- },
- {
- desc: 'Test 027: ru Russian',
- text: 'Праведники мира',
- highlight: 'Праве',
- expected: '<span class="highlight">Праве</span>дники мира'
- },
- {
- desc: 'Test 028 ka Georgian',
- text: 'მთავარი გვერდი',
- highlight: 'მთავარი გვერდი',
- expected: '<span class="highlight">მთავარი</span> <span class="highlight">გვერდი</span>'
- },
- {
- desc: 'Test 029 ka Georgian',
- text: 'მთავარი გვერდი',
- highlight: 'მთა',
- expected: '<span class="highlight">მთა</span>ვარი გვერდი'
- },
- {
- desc: 'Test 030 hy Armenian',
- text: 'Նոնա Գափրինդաշվիլի',
- highlight: 'Նոնա Գափրինդաշվիլի',
- expected: '<span class="highlight">Նոնա</span> <span class="highlight">Գափրինդաշվիլի</span>'
- },
- {
- desc: 'Test 031 hy Armenian',
- text: 'Նոնա Գափրինդաշվիլի',
- highlight: 'Նոն',
- expected: '<span class="highlight">Նոն</span>ա Գափրինդաշվիլի'
- },
- {
- desc: 'Test 032: th Thai',
- text: 'พอล แอร์ดิช',
- highlight: 'พอล แอร์ดิช',
- expected: '<span class="highlight">พอล</span> <span class="highlight">แอร์ดิช</span>'
- },
- {
- desc: 'Test 033: th Thai',
- text: 'พอล แอร์ดิช',
- highlight: 'พอ',
- expected: '<span class="highlight">พอ</span>ล แอร์ดิช'
- },
- {
- desc: 'Test 034: RTL ar Arabic',
- text: 'بول إيردوس',
- highlight: 'بول إيردوس',
- expected: '<span class="highlight">بول</span> <span class="highlight">إيردوس</span>'
- },
- {
- desc: 'Test 035: RTL ar Arabic',
- text: 'بول إيردوس',
- highlight: 'بو',
- expected: '<span class="highlight">بو</span>ل إيردوس'
- }
- ];
+ var $fixture,
+ cases = [
+ {
+ desc: 'Test 001',
+ text: 'Blue Öyster Cult',
+ highlight: 'Blue',
+ expected: '<span class="highlight">Blue</span> Öyster Cult'
+ },
+ {
+ desc: 'Test 002',
+ text: 'Blue Öyster Cult',
+ highlight: 'Blue ',
+ expected: '<span class="highlight">Blue</span> Öyster Cult'
+ },
+ {
+ desc: 'Test 003',
+ text: 'Blue Öyster Cult',
+ highlight: 'Blue Ö',
+ expected: '<span class="highlight">Blue</span> <span class="highlight">Ö</span>yster Cult'
+ },
+ {
+ desc: 'Test 004',
+ text: 'Blue Öyster Cult',
+ highlight: 'Blue Öy',
+ expected: '<span class="highlight">Blue</span> <span class="highlight">Öy</span>ster Cult'
+ },
+ {
+ desc: 'Test 005',
+ text: 'Blue Öyster Cult',
+ highlight: ' Blue',
+ expected: '<span class="highlight">Blue</span> Öyster Cult'
+ },
+ {
+ desc: 'Test 006',
+ text: 'Blue Öyster Cult',
+ highlight: ' Blue ',
+ expected: '<span class="highlight">Blue</span> Öyster Cult'
+ },
+ {
+ desc: 'Test 007',
+ text: 'Blue Öyster Cult',
+ highlight: ' Blue Ö',
+ expected: '<span class="highlight">Blue</span> <span class="highlight">Ö</span>yster Cult'
+ },
+ {
+ desc: 'Test 008',
+ text: 'Blue Öyster Cult',
+ highlight: ' Blue Öy',
+ expected: '<span class="highlight">Blue</span> <span class="highlight">Öy</span>ster Cult'
+ },
+ {
+ desc: 'Test 009: Highlighter broken on starting Umlaut?',
+ text: 'Österreich',
+ highlight: 'Österreich',
+ expected: '<span class="highlight">Österreich</span>'
+ },
+ {
+ desc: 'Test 010: Highlighter broken on starting Umlaut?',
+ text: 'Österreich',
+ highlight: 'Ö',
+ expected: '<span class="highlight">Ö</span>sterreich'
+ },
+ {
+ desc: 'Test 011: Highlighter broken on starting Umlaut?',
+ text: 'Österreich',
+ highlight: 'Öst',
+ expected: '<span class="highlight">Öst</span>erreich'
+ },
+ {
+ desc: 'Test 012: Highlighter broken on starting Umlaut?',
+ text: 'Österreich',
+ highlight: 'Oe',
+ expected: 'Österreich'
+ },
+ {
+ desc: 'Test 013: Highlighter broken on punctuation mark?',
+ text: 'So good. To be there',
+ highlight: 'good',
+ expected: 'So <span class="highlight">good</span>. To be there'
+ },
+ {
+ desc: 'Test 014: Highlighter broken on space?',
+ text: 'So good. To be there',
+ highlight: 'be',
+ expected: 'So good. To <span class="highlight">be</span> there'
+ },
+ {
+ desc: 'Test 015: Highlighter broken on space?',
+ text: 'So good. To be there',
+ highlight: ' be',
+ expected: 'So good. To <span class="highlight">be</span> there'
+ },
+ {
+ desc: 'Test 016: Highlighter broken on space?',
+ text: 'So good. To be there',
+ highlight: 'be ',
+ expected: 'So good. To <span class="highlight">be</span> there'
+ },
+ {
+ desc: 'Test 017: Highlighter broken on space?',
+ text: 'So good. To be there',
+ highlight: ' be ',
+ expected: 'So good. To <span class="highlight">be</span> there'
+ },
+ {
+ desc: 'Test 018: en de Highlighter broken on special character at the end?',
+ text: 'So good. xbß',
+ highlight: 'xbß',
+ expected: 'So good. <span class="highlight">xbß</span>'
+ },
+ {
+ desc: 'Test 019: en de Highlighter broken on special character at the end?',
+ text: 'So good. xbß.',
+ highlight: 'xbß.',
+ expected: 'So good. <span class="highlight">xbß.</span>'
+ },
+ {
+ desc: 'Test 020: RTL he Hebrew',
+ text: 'חסיד אומות העולם',
+ highlight: 'חסיד אומות העולם',
+ expected: '<span class="highlight">חסיד</span> <span class="highlight">אומות</span> <span class="highlight">העולם</span>'
+ },
+ {
+ desc: 'Test 021: RTL he Hebrew',
+ text: 'חסיד אומות העולם',
+ highlight: 'חסי',
+ expected: '<span class="highlight">חסי</span>ד אומות העולם'
+ },
+ {
+ desc: 'Test 022: ja Japanese',
+ text: '諸国民の中の正義の人',
+ highlight: '諸国民の中の正義の人',
+ expected: '<span class="highlight">諸国民の中の正義の人</span>'
+ },
+ {
+ desc: 'Test 023: ja Japanese',
+ text: '諸国民の中の正義の人',
+ highlight: '諸国',
+ expected: '<span class="highlight">諸国</span>民の中の正義の人'
+ },
+ {
+ desc: 'Test 024: fr French text and « french quotes » (guillemets)',
+ text: '« L\'oiseau est sur l’île »',
+ highlight: '« L\'oiseau est sur l’île »',
+ expected: '<span class="highlight">«</span> <span class="highlight">L\'oiseau</span> <span class="highlight">est</span> <span class="highlight">sur</span> <span class="highlight">l’île</span> <span class="highlight">»</span>'
+ },
+ {
+ desc: 'Test 025: fr French text and « french quotes » (guillemets)',
+ text: '« L\'oiseau est sur l’île »',
+ highlight: '« L\'oise',
+ expected: '<span class="highlight">«</span> <span class="highlight">L\'oise</span>au est sur l’île »'
+ },
+ {
+ desc: 'Test 025a: fr French text and « french quotes » (guillemets) - does it match the single strings "«" and "L" separately?',
+ text: '« L\'oiseau est sur l’île »',
+ highlight: '« L',
+ expected: '<span class="highlight">«</span> <span class="highlight">L</span>\'oiseau est sur <span class="highlight">l</span>’île »'
+ },
+ {
+ desc: 'Test 026: ru Russian',
+ text: 'Праведники мира',
+ highlight: 'Праведники мира',
+ expected: '<span class="highlight">Праведники</span> <span class="highlight">мира</span>'
+ },
+ {
+ desc: 'Test 027: ru Russian',
+ text: 'Праведники мира',
+ highlight: 'Праве',
+ expected: '<span class="highlight">Праве</span>дники мира'
+ },
+ {
+ desc: 'Test 028 ka Georgian',
+ text: 'მთავარი გვერდი',
+ highlight: 'მთავარი გვერდი',
+ expected: '<span class="highlight">მთავარი</span> <span class="highlight">გვერდი</span>'
+ },
+ {
+ desc: 'Test 029 ka Georgian',
+ text: 'მთავარი გვერდი',
+ highlight: 'მთა',
+ expected: '<span class="highlight">მთა</span>ვარი გვერდი'
+ },
+ {
+ desc: 'Test 030 hy Armenian',
+ text: 'Նոնա Գափրինդաշվիլի',
+ highlight: 'Նոնա Գափրինդաշվիլի',
+ expected: '<span class="highlight">Նոնա</span> <span class="highlight">Գափրինդաշվիլի</span>'
+ },
+ {
+ desc: 'Test 031 hy Armenian',
+ text: 'Նոնա Գափրինդաշվիլի',
+ highlight: 'Նոն',
+ expected: '<span class="highlight">Նոն</span>ա Գափրինդաշվիլի'
+ },
+ {
+ desc: 'Test 032: th Thai',
+ text: 'พอล แอร์ดิช',
+ highlight: 'พอล แอร์ดิช',
+ expected: '<span class="highlight">พอล</span> <span class="highlight">แอร์ดิช</span>'
+ },
+ {
+ desc: 'Test 033: th Thai',
+ text: 'พอล แอร์ดิช',
+ highlight: 'พอ',
+ expected: '<span class="highlight">พอ</span>ล แอร์ดิช'
+ },
+ {
+ desc: 'Test 034: RTL ar Arabic',
+ text: 'بول إيردوس',
+ highlight: 'بول إيردوس',
+ expected: '<span class="highlight">بول</span> <span class="highlight">إيردوس</span>'
+ },
+ {
+ desc: 'Test 035: RTL ar Arabic',
+ text: 'بول إيردوس',
+ highlight: 'بو',
+ expected: '<span class="highlight">بو</span>ل إيردوس'
+ }
+ ];
$.each( cases, function ( i, item ) {
$fixture = $( '<p>' ).text( item.text ).highlightText( item.highlight );
} );
QUnit.test( 'Options', function ( assert ) {
+ var html, $lc, x, sitename = 'Wikipedia';
mw.messages.set( {
'foo-lorem': 'Lorem',
'foo-ipsum': 'Ipsum',
'foo-bazz-label': 'The Bazz ($1)',
'foo-welcome': 'Welcome to $1! (last visit: $2)'
} );
- var html, $lc, x, sitename = 'Wikipedia';
// Message key prefix
html = '<div><span title-msg="lorem"><html:msg key="ipsum" /></span></div>';
// This test is first because if it fails, then almost all of the latter tests are meaningless.
QUnit.test( 'testing hooks/triggers', function ( assert ) {
- var test = this,
- $collapsible = prepareCollapsible(
+ var $collapsible = prepareCollapsible(
'<div class="mw-collapsible">' + loremIpsum + '</div>'
),
$content = $collapsible.find( '.mw-collapsible-content' ),
} );
QUnit.test( 'basic operation (<div>)', function ( assert ) {
- var test = this,
- $collapsible = prepareCollapsible(
+ var $collapsible = prepareCollapsible(
'<div class="mw-collapsible">' + loremIpsum + '</div>'
),
$content = $collapsible.find( '.mw-collapsible-content' ),
} );
QUnit.test( 'basic operation (<table>)', function ( assert ) {
- var test = this,
- $collapsible = prepareCollapsible(
+ var $collapsible = prepareCollapsible(
'<table class="mw-collapsible">' +
'<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
'<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
} );
QUnit.test( 'cloned collapsibles can be made collapsible again', function ( assert ) {
- var test = this,
- $collapsible = prepareCollapsible(
+ var $collapsible = prepareCollapsible(
'<div class="mw-collapsible">' + loremIpsum + '</div>'
),
$clone = $collapsible.clone() // clone without data and events
( function ( $ ) {
+ var html, testElement;
QUnit.module( 'jquery.placeholder', QUnit.newMwEnvironment() );
return;
}
- var html = '<form>' +
- '<input id="input-type-search" type="search" placeholder="Search this site...">' +
- '<input id="input-type-text" type="text" placeholder="e.g. John Doe">' +
- '<input id="input-type-email" type="email" placeholder="e.g. address@example.ext">' +
- '<input id="input-type-url" type="url" placeholder="e.g. http://mathiasbynens.be/">' +
- '<input id="input-type-tel" type="tel" placeholder="e.g. +32 472 77 69 88">' +
- '<input id="input-type-password" type="password" placeholder="e.g. hunter2">' +
- '<textarea id="textarea" name="message" placeholder="Your message goes here"></textarea>' +
- '</form>',
+ html = '<form>' +
+ '<input id="input-type-search" type="search" placeholder="Search this site...">' +
+ '<input id="input-type-text" type="text" placeholder="e.g. John Doe">' +
+ '<input id="input-type-email" type="email" placeholder="e.g. address@example.ext">' +
+ '<input id="input-type-url" type="url" placeholder="e.g. http://mathiasbynens.be/">' +
+ '<input id="input-type-tel" type="tel" placeholder="e.g. +32 472 77 69 88">' +
+ '<input id="input-type-password" type="password" placeholder="e.g. hunter2">' +
+ '<textarea id="textarea" name="message" placeholder="Your message goes here"></textarea>' +
+ '</form>';
testElement = function ( $el, assert ) {
-
var el = $el[ 0 ],
placeholder = el.getAttribute( 'placeholder' );
} );
QUnit.test( 'emulates placeholder for <input type=password>', function ( assert ) {
+ var $el, el, placeholder, selector = '#input-type-password';
+
$( '<div>' ).html( html ).appendTo( $( '#qunit-fixture' ) );
- var selector = '#input-type-password',
- $el = $( selector ),
- el = $el[ 0 ],
- placeholder = el.getAttribute( 'placeholder' );
+ $el = $( selector );
+ el = $el[ 0 ];
+ placeholder = el.getAttribute( 'placeholder' );
assert.strictEqual( $el.placeholder(), $el, 'should be chainable' );
} );
- QUnit.test( 'emulates placeholder for <textarea></textarea>', function ( assert ) {
+ QUnit.test( 'emulates placeholder for <textarea>', function ( assert ) {
$( '<div>' ).html( html ).appendTo( $( '#qunit-fixture' ) );
testElement( $( '#textarea' ), assert );
} );
'jul', 'aug', 'sep', 'oct', 'nov', 'dec' ]
},
names: [ 'January', 'February', 'March', 'April', 'May', 'June',
- 'July', 'August', 'September', 'October', 'November', 'December' ],
+ 'July', 'August', 'September', 'October', 'November', 'December' ],
genitive: [ 'January', 'February', 'March', 'April', 'May', 'June',
- 'July', 'August', 'September', 'October', 'November', 'December' ],
+ 'July', 'August', 'September', 'October', 'November', 'December' ],
abbrev: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
+ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
};
},
teardown: function () {
'jul', 'aug', 'sep', 'oct', 'nov', 'dec' ]
},
names: [ 'January', 'February', 'March', 'April', 'May', 'June',
- 'July', 'August', 'September', 'October', 'November', 'December' ],
+ 'July', 'August', 'September', 'October', 'November', 'December' ],
genitive: [ 'January', 'February', 'March', 'April', 'May', 'June',
- 'July', 'August', 'September', 'October', 'November', 'December' ],
+ 'July', 'August', 'September', 'October', 'November', 'December' ],
abbrev: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
+ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
};
},
teardown: function () {
$tr.appendTo( $thead );
for ( i = 0; i < data.length; i++ ) {
- /*jshint loopfunc: true */
$tr = $( '<tr>' );
+ // eslint-disable-next-line no-loop-func
$.each( data[ i ], function ( j, str ) {
var $td = $( '<td>' );
$td.text( str ).appendTo( $tr );
simple,
simpleAsc,
function ( $table ) {
+ var event;
$table.tablesorter(
{ sortList: [ { 0: 'desc' }, { 1: 'desc' } ] }
);
$table.find( '.headerSort:eq(0)' ).click();
// Pretend to click while pressing the multi-sort key
- var event = $.Event( 'click' );
+ event = $.Event( 'click' );
event[ $table.data( 'tablesorter' ).config.sortMultiSortKey ] = true;
$table.find( '.headerSort:eq(1)' ).trigger( event );
}
( function ( $ ) {
+ var caretSample,
+ sig = {
+ pre: '--~~~~'
+ },
+ bold = {
+ pre: '\'\'\'',
+ peri: 'Bold text',
+ post: '\'\'\''
+ },
+ h2 = {
+ pre: '== ',
+ peri: 'Heading 2',
+ post: ' ==',
+ regex: /^(\s*)(={1,6})(.*?)\2(\s*)$/,
+ regexReplace: '$1==$3==$4',
+ ownline: true
+ },
+ ulist = {
+ pre: '* ',
+ peri: 'Bulleted list item',
+ post: '',
+ ownline: true,
+ splitlines: true
+ };
QUnit.module( 'jquery.textSelection', QUnit.newMwEnvironment() );
} );
}
- var caretSample,
- sig = {
- pre: '--~~~~'
- },
- bold = {
- pre: '\'\'\'',
- peri: 'Bold text',
- post: '\'\'\''
- },
- h2 = {
- pre: '== ',
- peri: 'Heading 2',
- post: ' ==',
- regex: /^(\s*)(={1,6})(.*?)\2(\s*)$/,
- regexReplace: '$1==$3==$4',
- ownline: true
- },
- ulist = {
- pre: '* ',
- peri: 'Bulleted list item',
- post: '',
- ownline: true,
- splitlines: true
- };
-
encapsulateTest( {
description: 'Adding sig to end of text',
before: {
pages: [ {
pageid: 1,
ns: 0,
- title: 'Sandbox',
+ title: 'Sandbox',
revisions: [ {
timestamp: '2016-01-01T12:00:00Z',
contentformat: 'text/x-wiki',
pages: [ {
pageid: 4,
ns: 0,
- title: 'Async',
+ title: 'Async',
revisions: [ {
timestamp: '2016-02-01T12:00:00Z',
contentformat: 'text/x-wiki',
pages: [ {
pageid: 3,
ns: 0,
- title: 'Param',
+ title: 'Param',
revisions: [ {
timestamp: '2016-03-01T12:00:00Z',
contentformat: 'text/x-wiki',
if ( /edit.+text=Sand/.test( req.requestBody ) ) {
req.respond( 200, { 'Content-Type': 'application/json' }, JSON.stringify( {
edit: {
- 'new': true,
+ new: true,
result: 'Success',
newrevid: 41,
newtimestamp: '2016-04-01T12:00:00Z'
// Requests are POST, match requestBody instead of url
this.server.respond( function ( request ) {
- switch ( request.requestBody ) {
+ if ( $.inArray( request.requestBody, [
// simple
- case 'action=options&format=json&formatversion=2&change=foo%3Dbar&token=%2B%5C':
+ 'action=options&format=json&formatversion=2&change=foo%3Dbar&token=%2B%5C',
// two options
- case 'action=options&format=json&formatversion=2&change=foo%3Dbar%7Cbaz%3Dquux&token=%2B%5C':
+ 'action=options&format=json&formatversion=2&change=foo%3Dbar%7Cbaz%3Dquux&token=%2B%5C',
// not bundleable
- case 'action=options&format=json&formatversion=2&optionname=foo&optionvalue=bar%7Cquux&token=%2B%5C':
- case 'action=options&format=json&formatversion=2&optionname=bar&optionvalue=a%7Cb%7Cc&token=%2B%5C':
- case 'action=options&format=json&formatversion=2&change=baz%3Dquux&token=%2B%5C':
+ 'action=options&format=json&formatversion=2&optionname=foo&optionvalue=bar%7Cquux&token=%2B%5C',
+ 'action=options&format=json&formatversion=2&optionname=bar&optionvalue=a%7Cb%7Cc&token=%2B%5C',
+ 'action=options&format=json&formatversion=2&change=baz%3Dquux&token=%2B%5C',
// reset an option
- case 'action=options&format=json&formatversion=2&change=foo&token=%2B%5C':
+ 'action=options&format=json&formatversion=2&change=foo&token=%2B%5C',
// reset an option, not bundleable
- case 'action=options&format=json&formatversion=2&optionname=foo%7Cbar%3Dquux&token=%2B%5C':
- assert.ok( true, 'Repond to ' + request.requestBody );
- request.respond( 200, { 'Content-Type': 'application/json' },
- '{ "options": "success" }' );
- break;
- default:
- assert.ok( false, 'Unexpected request: ' + request.requestBody );
+ 'action=options&format=json&formatversion=2&optionname=foo%7Cbar%3Dquux&token=%2B%5C'
+ ] ) !== -1 ) {
+ assert.ok( true, 'Repond to ' + request.requestBody );
+ request.respond( 200, { 'Content-Type': 'application/json' },
+ '{ "options": "success" }' );
+ } else {
+ assert.ok( false, 'Unexpected request: ' + request.requestBody );
}
} );
// Requests are POST, match requestBody instead of url
this.server.respond( function ( request ) {
- switch ( request.requestBody ) {
+ if ( $.inArray( request.requestBody, [
// simple
- case 'action=options&format=json&formatversion=2&change=foo%3Dbar&token=%2B%5C':
+ 'action=options&format=json&formatversion=2&change=foo%3Dbar&token=%2B%5C',
// two options
- case 'action=options&format=json&formatversion=2&change=foo%3Dbar%7Cbaz%3Dquux&token=%2B%5C':
+ 'action=options&format=json&formatversion=2&change=foo%3Dbar%7Cbaz%3Dquux&token=%2B%5C',
// bundleable with unit separator
- case 'action=options&format=json&formatversion=2&change=%1Ffoo%3Dbar%7Cquux%1Fbar%3Da%7Cb%7Cc%1Fbaz%3Dquux&token=%2B%5C':
+ 'action=options&format=json&formatversion=2&change=%1Ffoo%3Dbar%7Cquux%1Fbar%3Da%7Cb%7Cc%1Fbaz%3Dquux&token=%2B%5C',
// not bundleable with unit separator
- case 'action=options&format=json&formatversion=2&optionname=baz%3Dbaz&optionvalue=quux&token=%2B%5C':
- case 'action=options&format=json&formatversion=2&change=%1Ffoo%3Dbar%7Cquux%1Fbar%3Da%7Cb%7Cc&token=%2B%5C':
+ 'action=options&format=json&formatversion=2&optionname=baz%3Dbaz&optionvalue=quux&token=%2B%5C',
+ 'action=options&format=json&formatversion=2&change=%1Ffoo%3Dbar%7Cquux%1Fbar%3Da%7Cb%7Cc&token=%2B%5C',
// reset an option
- case 'action=options&format=json&formatversion=2&change=foo&token=%2B%5C':
+ 'action=options&format=json&formatversion=2&change=foo&token=%2B%5C',
// reset an option, not bundleable
- case 'action=options&format=json&formatversion=2&optionname=foo%7Cbar%3Dquux&token=%2B%5C':
- assert.ok( true, 'Repond to ' + request.requestBody );
- request.respond( 200, { 'Content-Type': 'application/json' },
+ 'action=options&format=json&formatversion=2&optionname=foo%7Cbar%3Dquux&token=%2B%5C'
+ ] ) !== -1 ) {
+ assert.ok( true, 'Repond to ' + request.requestBody );
+ request.respond( 200, { 'Content-Type': 'application/json' },
'{ "options": "success" }' );
- break;
- default:
- assert.ok( false, 'Unexpected request: ' + request.requestBody );
+ } else {
+ assert.ok( false, 'Unexpected request: ' + request.requestBody );
}
} );
] );
return new mw.Api().parse( new mw.Title( 'Earth' ) ).done( function ( html ) {
- assert.equal( html, '<p><b>Earth</b> is a planet.</p>', 'Parse page by Title object' );
+ assert.equal( html, '<p><b>Earth</b> is a planet.</p>', 'Parse page by Title object' );
} );
} );
}( mediaWiki ) );
return api.postWithToken( 'testassertpost', { action: 'example', key: 'foo', assert: 'user' } )
// Cast error to success and vice versa
- .then( function ( ) {
+ .then( function () {
return $.Deferred().reject( 'Unexpected success' );
}, function ( errorCode ) {
assert.equal( errorCode, 'assertuserfailed', 'getToken fails assert' );
this.server.respond( [ 200, { 'Content-Type': 'application/json' }, '{ "example": "quux" }' ] );
return api.postWithToken( 'csrf',
- { action: 'example' },
- {
- headers: {
- 'X-Foo': 'Bar'
- }
+ { action: 'example' },
+ {
+ headers: {
+ 'X-Foo': 'Bar'
}
- )
- .then( function () {
- assert.equal( test.server.requests[ 0 ].requestHeaders[ 'X-Foo' ], 'Bar', 'Header sent' );
+ }
+ )
+ .then( function () {
+ assert.equal( test.server.requests[ 0 ].requestHeaders[ 'X-Foo' ], 'Bar', 'Header sent' );
- return api.postWithToken( 'csrf',
- { action: 'example' },
- function () {
- assert.ok( false, 'This parameter cannot be a callback' );
- }
- );
- } )
- .then( function ( data ) {
- assert.equal( data.example, 'quux' );
+ return api.postWithToken( 'csrf',
+ { action: 'example' },
+ function () {
+ assert.ok( false, 'This parameter cannot be a callback' );
+ }
+ );
+ } )
+ .then( function ( data ) {
+ assert.equal( data.example, 'quux' );
- assert.equal( test.server.requests.length, 2, 'Request made' );
- } );
+ assert.equal( test.server.requests.length, 2, 'Request made' );
+ } );
} );
QUnit.test( 'postWithToken() - badtoken', function ( assert ) {
hidefilter4: 0,
hidefilter5: 0,
hidefilter6: 0,
- group3: 'all',
+ group3: 'all'
},
'Unselected filters return all parameters falsey or \'all\'.'
);
filters: [
{ name: 'filter1' },
{ name: 'filter2' },
- { name: 'filter3' },
+ { name: 'filter3' }
]
},
group2: {
filters: [
{ name: 'filter4' },
{ name: 'filter5' },
- { name: 'filter6' },
+ { name: 'filter6' }
]
}
},
+ model = new mw.rcfilters.dm.FiltersViewModel(),
isCapsuleItemMuted = function ( filterName ) {
var itemModel = model.getItemByName( filterName ),
groupModel = itemModel.getGroupModel();
filter4: false,
filter5: false,
filter6: false
- },
- model = new mw.rcfilters.dm.FiltersViewModel();
+ };
model.initializeFilters( definition );
conflicts: [ 'filter3' ]
},
{
- name: 'filter6',
+ name: 'filter6'
}
]
}
$.extend( true, {}, baseFullState, {
filter1: { selected: true },
filter2: { conflicted: true },
- filter4: { conflicted: true },
+ filter4: { conflicted: true }
} ),
'Selecting a filter set its conflicts list as "conflicted".'
);
$.extend( true, {}, baseFullState, {
filter1: { selected: true, conflicted: true },
filter2: { conflicted: true },
- filter4: { selected: true, conflicted: true },
+ filter4: { selected: true, conflicted: true }
} ),
'Selecting a conflicting filter sets both sides to conflicted and selected.'
);
( function ( mw, $ ) {
+ /* eslint-disable camelcase */
var repeat = function ( input, multiplier ) {
- return new Array( multiplier + 1 ).join( input );
- },
- cases = {
+ return new Array( multiplier + 1 ).join( input );
+ },
// See also TitleTest.php#testSecureAndSplit
- valid: [
- 'Sandbox',
- 'A "B"',
- 'A \'B\'',
- '.com',
- '~',
- '"',
- '\'',
- 'Talk:Sandbox',
- 'Talk:Foo:Sandbox',
- 'File:Example.svg',
- 'File_talk:Example.svg',
- 'Foo/.../Sandbox',
- 'Sandbox/...',
- 'A~~',
- ':A',
- // Length is 256 total, but only title part matters
- 'Category:' + repeat( 'x', 248 ),
- repeat( 'x', 252 )
- ],
- invalid: [
- '',
- ':',
- '__ __',
- ' __ ',
- // Bad characters forbidden regardless of wgLegalTitleChars
- 'A [ B',
- 'A ] B',
- 'A { B',
- 'A } B',
- 'A < B',
- 'A > B',
- 'A | B',
- 'A \t B',
- 'A \n B',
- // URL encoding
- 'A%20B',
- 'A%23B',
- 'A%2523B',
- // XML/HTML character entity references
- // Note: The ones with # are commented out as those are interpreted as fragment and
- // as such end up being valid.
- 'A é B',
- // 'A é B',
- // 'A é B',
- // Subject of NS_TALK does not roundtrip to NS_MAIN
- 'Talk:File:Example.svg',
- // Directory navigation
- '.',
- '..',
- './Sandbox',
- '../Sandbox',
- 'Foo/./Sandbox',
- 'Foo/../Sandbox',
- 'Sandbox/.',
- 'Sandbox/..',
- // Tilde
- 'A ~~~ Name',
- 'A ~~~~ Signature',
- 'A ~~~~~ Timestamp',
- repeat( 'x', 256 ),
- // Extension separation is a js invention, for length
- // purposes it is part of the title
- repeat( 'x', 252 ) + '.json',
- // Namespace prefix without actual title
- 'Talk:',
- 'Category: ',
- 'Category: #bar'
- ]
- };
+ cases = {
+ valid: [
+ 'Sandbox',
+ 'A "B"',
+ 'A \'B\'',
+ '.com',
+ '~',
+ '"',
+ '\'',
+ 'Talk:Sandbox',
+ 'Talk:Foo:Sandbox',
+ 'File:Example.svg',
+ 'File_talk:Example.svg',
+ 'Foo/.../Sandbox',
+ 'Sandbox/...',
+ 'A~~',
+ ':A',
+ // Length is 256 total, but only title part matters
+ 'Category:' + repeat( 'x', 248 ),
+ repeat( 'x', 252 )
+ ],
+ invalid: [
+ '',
+ ':',
+ '__ __',
+ ' __ ',
+ // Bad characters forbidden regardless of wgLegalTitleChars
+ 'A [ B',
+ 'A ] B',
+ 'A { B',
+ 'A } B',
+ 'A < B',
+ 'A > B',
+ 'A | B',
+ 'A \t B',
+ 'A \n B',
+ // URL encoding
+ 'A%20B',
+ 'A%23B',
+ 'A%2523B',
+ // XML/HTML character entity references
+ // Note: The ones with # are commented out as those are interpreted as fragment and
+ // as such end up being valid.
+ 'A é B',
+ // 'A é B',
+ // 'A é B',
+ // Subject of NS_TALK does not roundtrip to NS_MAIN
+ 'Talk:File:Example.svg',
+ // Directory navigation
+ '.',
+ '..',
+ './Sandbox',
+ '../Sandbox',
+ 'Foo/./Sandbox',
+ 'Foo/../Sandbox',
+ 'Sandbox/.',
+ 'Sandbox/..',
+ // Tilde
+ 'A ~~~ Name',
+ 'A ~~~~ Signature',
+ 'A ~~~~~ Timestamp',
+ repeat( 'x', 256 ),
+ // Extension separation is a js invention, for length
+ // purposes it is part of the title
+ repeat( 'x', 252 ) + '.json',
+ // Namespace prefix without actual title
+ 'Talk:',
+ 'Category: ',
+ 'Category: #bar'
+ ]
+ };
QUnit.module( 'mediawiki.Title', QUnit.newMwEnvironment( {
// mw.Title relies on these three config vars
// testing custom / localized namespace
100: 'Penguins'
},
- // jscs: disable requireCamelCaseOrUpperCaseIdentifiers
wgNamespaceIds: {
media: -2,
special: -1,
penguins: 100,
antarctic_waterfowl: 100
},
- // jscs: enable requireCamelCaseOrUpperCaseIdentifiers
wgCaseSensitiveNamespaces: []
}
} ) );
title = new mw.Title( cases.valid[ i ] );
}
for ( i = 0; i < cases.invalid.length; i++ ) {
- /*jshint loopfunc:true */
title = cases.invalid[ i ];
+ // eslint-disable-next-line no-loop-func
assert.throws( function () {
return new mw.Title( title );
}, cases.invalid[ i ] );
} );
assert.equal( uri.toString(), 'http://example.com/bar/baz', 'normalize URI without protocol or // in loose mode' );
- /*jshint -W001 */
uri = new mw.Uri( 'http://example.com/index.php?key=key&hasOwnProperty=hasOwnProperty&constructor=constructor&watch=watch' );
assert.deepEqual(
uri.query,
},
'Keys in query strings support names of Object prototypes (bug T114344)'
);
- /*jshint +W001 */
} );
QUnit.test( 'Constructor( Object )', function ( assert ) {
( function ( mw, $ ) {
- QUnit.module( 'mediawiki.cldr', QUnit.newMwEnvironment() );
-
var pluralTestcases = {
/*
* Sample:
]
};
+ QUnit.module( 'mediawiki.cldr', QUnit.newMwEnvironment() );
+
function pluralTest( langCode, tests ) {
QUnit.test( 'Plural Test for ' + langCode, function ( assert ) {
- for ( var i = 0; i < tests.length; i++ ) {
+ var i;
+ for ( i = 0; i < tests.length; i++ ) {
assert.equal(
mw.language.convertPlural( tests[ i ][ 0 ], tests[ i ][ 1 ] ),
tests[ i ][ 2 ],
w.onerror( errorMessage, errorUrl, errorLine, errorColumn, errorObject );
sinon.assert.calledWithExactly( mw.track, 'global.error',
sinon.match( { errorMessage: errorMessage, url: errorUrl, lineNumber: errorLine,
- columnNumber: errorColumn, errorObject: errorObject } ) );
+ columnNumber: errorColumn, errorObject: errorObject } ) );
w = { onerror: oldHandler };
( function ( mw, $ ) {
+ /* eslint-disable camelcase */
var formatText, formatParse, formatnumTests, specialCharactersPageName, expectedListUsers,
expectedListUsersSitename, expectedLinkPagenamee, expectedEntrypoints,
mwLanguageCache = {},
},
config: {
wgArticlePath: '/wiki/$1',
- // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
wgNamespaceIds: {
template: 10,
template_talk: 11,
szablon: 10,
dyskusja_szablonu: 11
},
- // jscs:enable requireCamelCaseOrUpperCaseIdentifiers
wgFormattedNamespaces: {
// Localised
10: 'Szablon',
* that may be asynchronous. Invoke the callback parameter when done.
*/
function process( tasks ) {
- /*jshint latedef:false */
function abort() {
tasks.splice( 0, tasks.length );
+ // eslint-disable-next-line no-use-before-define
next();
}
function next() {
+ var task;
if ( !tasks ) {
// This happens if after the process is completed, one of our callbacks is
// invoked. This can happen if a test timed out but the process was still
// running. In that case, ignore it. Don't invoke complete() a second time.
return;
}
- var task = tasks.shift();
+ task = tasks.shift();
if ( task ) {
task( next, abort );
} else {
} );
QUnit.test( 'Match PHP parser', function ( assert ) {
+ var tasks;
mw.messages.set( mw.libs.phpParserData.messages );
- var tasks = $.map( mw.libs.phpParserData.tests, function ( test ) {
+ tasks = $.map( mw.libs.phpParserData.tests, function ( test ) {
var done = assert.async();
return function ( next, abort ) {
getMwLanguage( test.lang )
.then( function ( langClass ) {
+ var parser;
mw.config.set( 'wgUserLanguage', test.lang );
- var parser = new mw.jqueryMsg.parser( { language: langClass } );
+ // eslint-disable-next-line new-cap
+ parser = new mw.jqueryMsg.parser( { language: langClass } );
assert.equal(
parser.parse( test.key, test.args ).html(),
test.result,
];
QUnit.test( 'formatnum', function ( assert ) {
+ var queue;
mw.messages.set( 'formatnum-msg', '{{formatnum:$1}}' );
mw.messages.set( 'formatnum-msg-int', '{{formatnum:$1|R}}' );
- var queue = $.map( formatnumTests, function ( test ) {
+ queue = $.map( formatnumTests, function ( test ) {
var done = assert.async();
return function ( next, abort ) {
getMwLanguage( test.lang )
.then( function ( langClass ) {
+ var parser;
mw.config.set( 'wgUserLanguage', test.lang );
- var parser = new mw.jqueryMsg.parser( { language: langClass } );
+ // eslint-disable-next-line new-cap
+ parser = new mw.jqueryMsg.parser( { language: langClass } );
assert.equal(
parser.parse( test.integer ? 'formatnum-msg-int' : 'formatnum-msg',
[ test.number ] ).html(),
} );
QUnit.test( 'Behavior in case of invalid wikitext', function ( assert ) {
+ var logSpy;
mw.messages.set( 'invalid-wikitext', '<b>{{FAIL}}</b>' );
this.suppressWarnings();
- var logSpy = this.sandbox.spy( mw.log, 'warn' );
+ logSpy = this.sandbox.spy( mw.log, 'warn' );
assert.equal(
formatParse( 'invalid-wikitext' ),
( function ( mw, $ ) {
'use strict';
+ var grammarTests;
+
QUnit.module( 'mediawiki.language', QUnit.newMwEnvironment( {
setup: function () {
this.liveLangData = mw.language.data;
// The test works only if the content language is opt.language
// because it requires [lang].js to be loaded.
QUnit.test( 'Grammar test for lang=' + langCode, function ( assert ) {
-
- for ( var i = 0; i < test.length; i++ ) {
+ var i;
+ for ( i = 0; i < test.length; i++ ) {
assert.equal(
mw.language.convertGrammar( test[ i ].word, test[ i ].grammarForm ),
test[ i ].expected,
}
// These tests run only for the current UI language.
- var grammarTests = {
+ grammarTests = {
bs: [
{
word: 'word',
function isCssImportApplied() {
// Trigger reflow, repaint, redraw, whatever (cross-browser)
- var x = $element.css( 'height' );
- x = el.innerHTML;
+ $element.css( 'height' );
+ el.innerHTML;
el.className = el.className;
- x = document.documentElement.clientHeight;
+ document.documentElement.clientHeight;
return $element.css( prop ) === val;
}
[ false, ':::' ],
[ false, '::0:', 'IPv6 ending in a lone ":"' ],
- [ true, '::', 'IPv6 zero address' ],
+ [ true, '::', 'IPv6 zero address' ],
[ false, '::fc:100:a:d:1:e:ac:0', 'IPv6 with "::" and 8 words' ],
[ false, '::fc:100:a:d:1:e:ac:0:1', 'IPv6 with 9 words' ],
[ false, 'fc::100:', 'IPv6 ending with lone ":"' ],
[ false, 'fc:::100', 'IPv6 with ":::" in the middle' ],
- [ true, 'fc::100', 'IPv6 with "::" and 2 words' ],
- [ true, 'fc::100:a', 'IPv6 with "::" and 3 words' ],
- [ true, 'fc::100:a:d', 'IPv6 with "::" and 4 words' ],
- [ true, 'fc::100:a:d:1', 'IPv6 with "::" and 5 words' ],
- [ true, 'fc::100:a:d:1:e', 'IPv6 with "::" and 6 words' ],
- [ true, 'fc::100:a:d:1:e:ac', 'IPv6 with "::" and 7 words' ],
- [ true, '2001::df', 'IPv6 with "::" and 2 words' ],
- [ true, '2001:5c0:1400:a::df', 'IPv6 with "::" and 5 words' ],
- [ true, '2001:5c0:1400:a::df:2', 'IPv6 with "::" and 6 words' ],
+ [ true, 'fc::100', 'IPv6 with "::" and 2 words' ],
+ [ true, 'fc::100:a', 'IPv6 with "::" and 3 words' ],
+ [ true, 'fc::100:a:d', 'IPv6 with "::" and 4 words' ],
+ [ true, 'fc::100:a:d:1', 'IPv6 with "::" and 5 words' ],
+ [ true, 'fc::100:a:d:1:e', 'IPv6 with "::" and 6 words' ],
+ [ true, 'fc::100:a:d:1:e:ac', 'IPv6 with "::" and 7 words' ],
+ [ true, '2001::df', 'IPv6 with "::" and 2 words' ],
+ [ true, '2001:5c0:1400:a::df', 'IPv6 with "::" and 5 words' ],
+ [ true, '2001:5c0:1400:a::df:2', 'IPv6 with "::" and 6 words' ],
[ false, 'fc::100:a:d:1:e:ac:0', 'IPv6 with "::" and 8 words' ],
[ false, 'fc::100:a:d:1:e:ac:0:1', 'IPv6 with 9 words' ]
-/*global isCompatible: true */
+/* global isCompatible: true */
( function ( $ ) {
var testcases = {
tested: [
QUnit.test( 'isCompatible( featureTestable )', function ( assert ) {
$.each( testcases.tested, function ( i, ua ) {
- assert.strictEqual( isCompatible( ua ), true, ua );
- }
- );
+ assert.strictEqual( isCompatible( ua ), true, ua );
+ } );
} );
QUnit.test( 'isCompatible( blacklisted )', function ( assert ) {
$.each( testcases.blacklisted, function ( i, ua ) {
- assert.strictEqual( isCompatible( ua ), false, ua );
- }
- );
+ assert.strictEqual( isCompatible( ua ), false, ua );
+ } );
} );
}( jQuery ) );