LocalSettings.php
StartProfiler.php
+# Building & testing
+node_modules/
+
# Operating systems
## Mac OS X
.DS_Store
-# upstream libs
+# third-party libs
+extensions/
+node_modules/
resources/jquery/jquery.appear.js
resources/jquery/jquery.async.js
resources/jquery/jquery.cycle.all.js
resources/jquery/jquery.qunit.js
resources/jquery/jquery.validate.js
resources/jquery/jquery.xmldom.js
-resources/jquery.effects
-resources/jquery.tipsy
-resources/jquery.ui
-resources/mediawiki.libs
-tests/jasmine/lib/jasmine-1.0.1/jasmine-html.js
-tests/jasmine/lib/jasmine-1.0.1/jasmine.js
+resources/jquery.effects/
+resources/jquery.tipsy/
+resources/jquery.ui/
+resources/mediawiki.libs/
+
+# legacy scripts
+skins/common/
+
+# github.com/jshint/jshint/issues/729
+tests/qunit/suites/resources/mediawiki/mediawiki.jscompat.test.js
{
"predef": [
"mediaWiki",
+ "jQuery",
"QUnit"
],
"bitwise": true,
+ "camelcase": true,
"curly": true,
"eqeqeq": true,
+ "forin": false,
"immed": true,
"latedef": true,
"newcap": true,
"noarg": true,
"noempty": true,
"nonew": true,
+ "quotmark": "single",
"regexp": false,
"undef": true,
+ "unused": true,
"strict": false,
"trailing": true,
"multistr": true,
"browser": true,
- "jquery": true,
"nomen": true,
"onevar": true
== MediaWiki 1.20 ==
-THIS IS NOT A RELEASE YET
-
-MediaWiki 1.20 is an alpha-quality branch and is not recommended for use in
-production.
+MediaWiki 1.20 is a stable release.
=== PHP 5.3 now required ===
Since 1.20, the lowest supported version of PHP is now 5.3.2. Please
* (bug 40448) mediawiki.legacy.mwsuggest has been replaced with a new module,
mediawiki.searchSuggest, based on SimpleSeach from Extension:Vector.
+=== Known issues in 1.20.0 ===
+These are issues that we're targeting to be fixed in a later release
+in the 1.20 series. Issues may be added or removed from this list as
+we see fit. For now, it is comprised of those bugs on the 1.20.0
+milestone in Bugzilla.
+
+* (bug 35894): Reports of secret key generation "hanging" on windows
+ This is probably a bug that has been fixed in PHP. If you run
+ into this, try upgrading your PHP.
+* (bug 38334): PHP Notice: Undefined index: href in /www/w/skins/Vector.php on line 416
+ We think this is a problem in some extension. If you see this,
+ try disabling your extensions and check out the logging patch on
+ this bug. Or try this patch:
+ <https://gerrit.wikimedia.org/r/#/c/27937/1/skins/Vector.php>
+* (bug 39268): [Regression] Toolbar inserts in main textarea only (instead of the focussed textarea)
+ This should only be an issue if you are using the ProofreadPage
+ extension.
+* (bug 40641): Clicking "others" in Special:Version asks to download a file
+ If you encounter this, you can tell your webserver to serve the
+ CREDITS file with text/plain MIME type to fix it.
+
=== Bug fixes in 1.20 ===
+* (bug 40939): [Regression] InfoAction: Call to a member function getUserText() on a non-object
+* (bug 40780): searchsuggest-containing line ("containing...") doesn't include the entered text
+* (bug 37714): [Regression] Incomplete log entries
+* (bug 27202): API: Add timestamp sort to list=allimages
* (bug 30245) Use the correct way to construct a log page title.
* (bug 34237) Regenerate an empty user_token and save to the database
when we try to set the user's cookies for login.
caught during API execution.
* (bug 37963) Fixed loading process for user options
* (bug 26995) Update filename field on Upload page after having sanitized it.
+* (bug 41793) Contribution links to users with 0 edits on Special:ListUsers didn't
+ show up red.
+* (bug 41899) A PHP notice no longer occurs when using the "rvcontinue" API parameter.
=== API changes in 1.21 ===
* prop=revisions can now report the contentmodel and contentformat, see docs/contenthandler.txt
<simpleType name="ContentModelType">
<restriction base="string">
- <pattern value="[a-zA-Z][-+./a-zA-Z0-9]*"/>
+ <pattern value="[a-zA-Z][-+./a-zA-Z0-9]*" />
</restriction>
</simpleType>
<simpleType name="ContentFormatType">
<restriction base="string">
- <pattern value='[a-zA-Z][-+.a-zA-Z0-9]*\/[a-zA-Z][-+.a-zA-Z0-9]*'/>
+ <pattern value="[a-zA-Z][-+.a-zA-Z0-9]*/[a-zA-Z][-+.a-zA-Z0-9]*" />
</restriction>
</simpleType>
-<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.7/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.7/ http://www.mediawiki.org/xml/export-0.7.xsd" version="0.7" xml:lang="en">
+<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.8/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.8/ http://www.mediawiki.org/xml/export-0.8.xsd" version="0.8" xml:lang="en">
<!-- Optional global configuration info -->
<siteinfo>
</contributor>
<minor />
<comment>I have just one thing to say!</comment>
- <sha1>5x0ux8iwjrbmfzgv6pkketxgkcnpr7h</sha1>
<text xml:space="preserve" bytes="25">A bunch of [[text]] here.</text>
+ <sha1>5x0ux8iwjrbmfzgv6pkketxgkcnpr7h</sha1>
+ <model>wikitext</model>
+ <format>text/x-wiki</format>
</revision>
<revision>
<ip>10.0.0.2</ip>
</contributor>
<comment>new!</comment>
- <sha1>etaxt3shcge6igz1biwy3d4um2pnle4</sha1>
<text xml:space="preserve" bytes="24">An earlier [[revision]].</text>
+ <sha1>etaxt3shcge6igz1biwy3d4um2pnle4</sha1>
+ <model>wikitext</model>
+ <format>text/x-wiki</format>
</revision>
</page>
<timestamp>2001-01-15T14:03:00Z</timestamp>
<contributor><ip>10.0.0.2</ip></contributor>
<comment>hey</comment>
- <sha1>ml80vmyjlixdstnywwihx003exfzq9j</sha1>
<text xml:space="preserve" bytes="47">WHYD YOU LOCK PAGE??!!! i was editing that jerk</text>
+ <sha1>ml80vmyjlixdstnywwihx003exfzq9j</sha1>
+ <model>wikitext</model>
+ <format>text/x-wiki</format>
</revision>
</page>
<timestamp>2001-01-15T20:34:12Z</timestamp>
<contributor><username>Foobar</username><id>42</id></contributor>
<comment>My awesomeest image!</comment>
- <sha1>mehom37npwkpzhaiwu3wyr0egalumki</sha1>
<text xml:space="preserve" bytes="52">This is an awesome little imgae. I lurves it. {{PD}}</text>
+ <sha1>mehom37npwkpzhaiwu3wyr0egalumki</sha1>
+ <model>wikitext</model>
+ <format>text/x-wiki</format>
</revision>
<upload>
<timestamp>2001-01-15T20:34:12Z</timestamp>
$modeName: the requested content model name
&$handler: set this to a ContentHandler object, if desired.
+'ConvertContent': Called by AbstractContent::convert when a conversion to another
+content model is requested.
+$content: The Content object to be converted.
+$toModel: The ID of the content model to convert to.
+$lossy: boolean indicating whether lossy conversion is allowed.
+&$result: Output parameter, in case the handler function wants to provide a
+converted Content object. Note that $result->getContentModel() must return $toModel.
+Handler functions that modify $result should generally return false to further
+attempts at conversion.
+
'ContribsPager::getQueryInfo': Before the contributions query is about to run
&$pager: Pager object for contributions
&$queryInfo: The query for the contribs Pager
$terms: The search terms entered
$page: The SpecialSearch object.
+'ShowSearchHit': Customize display of search hit.
+$searchPage: The SpecialSearch instance.
+$result: The SearchResult to show
+$terms: Search terms, for highlighting
+&$link: HTML of link to the matching page. May be modified.
+&$redirect: HTML of redirect info. May be modified.
+&$section: HTML of matching section. May be modified.
+&$extract: HTML of content extract. May be modified.
+&$score: HTML of score. May be modified.
+&$size: HTML of page size. May be modified.
+&$date: HTML of of page modification date. May be modified.
+&$related: HTML of additional info for the matching page. May be modified.
+&$html: May be set to the full HTML that should be used to represent the search hit. Must include
+the <li> ... </li> tags. Will only be used if the hook function returned false.
+
'SiteNoticeBefore': Before the sitenotice/anonnotice is composed
&$siteNotice: HTML returned as the sitenotice
$skin: Skin object
Allows overriding default behaviour for determining if a page exists.
If $isKnown is kept as null, regular checks happen. If it's a boolean, this value is returned by the isKnown method.
$title: Title object that is being checked
-$result: Boolean|null; whether MediaWiki currently thinks this page is known
+&$isKnown: Boolean|null; whether MediaWiki currently thinks this page is known
'TitleIsMovable': Called when determining if it is possible to move a page.
Note that this hook is not called for interwiki pages or pages in immovable namespaces: for these, isMovable() always returns false.
wfProfileIn( 'img_auth.php' );
# Set action base paths so that WebRequest::getPathInfo()
-# recognizes the "X" as the 'title' in ../image_auth/X urls.
+# recognizes the "X" as the 'title' in ../img_auth.php/X urls.
$wgArticlePath = false; # Don't let a "/*" article path clober our action path
$wgActionPaths = array( "$wgUploadPath/" );
$outputDone = true;
} else {
$content = $this->getContentObject();
- $rt = $content->getRedirectChain();
+ $rt = $content ? $content->getRedirectChain() : null;
if ( $rt ) {
wfDebug( __METHOD__ . ": showing redirect=no page\n" );
# Viewing a redirect page (e.g. with parameter redirect=no)
# Run the parse, protected by a pool counter
wfDebug( __METHOD__ . ": doing uncached parse\n" );
- // @todo: shouldn't we be passing $this->getPage() to PoolWorkArticleView instead of plain $this?
- $poolArticleView = new PoolWorkArticleView( $this, $parserOptions,
- $this->getRevIdFetched(), $useParserCache, $this->getContentObject(), $this->getContext() );
+ $poolArticleView = new PoolWorkArticleView( $this->getPage(), $parserOptions,
+ $this->getRevIdFetched(), $useParserCache, $this->getContentObject() );
if ( !$poolArticleView->execute() ) {
$error = $poolArticleView->getError();
'clearyourcache' );
}
- // Give hooks a chance to customise the output
- if ( ContentHandler::runLegacyHooks( 'ShowRawCssJs', array( $this->fetchContentObject(), $this->getTitle(), $outputPage ) ) ) {
- $po = $this->mContentObject->getParserOutput( $this->getTitle() );
- $outputPage->addHTML( $po->getText() );
+ $this->fetchContentObject();
+
+ if ( $this->mContentObject ) {
+ // Give hooks a chance to customise the output
+ if ( ContentHandler::runLegacyHooks( 'ShowRawCssJs', array( $this->mContentObject, $this->getTitle(), $outputPage ) ) ) {
+ $po = $this->mContentObject->getParserOutput( $this->getTitle() );
+ $outputPage->addHTML( $po->getText() );
+ }
}
}
'IndexPager' => 'includes/Pager.php',
'Interwiki' => 'includes/interwiki/Interwiki.php',
'IP' => 'includes/IP.php',
+ 'LCStore' => 'includes/LocalisationCache.php',
'LCStore_Accel' => 'includes/LocalisationCache.php',
'LCStore_CDB' => 'includes/LocalisationCache.php',
'LCStore_DB' => 'includes/LocalisationCache.php',
'RdfMetaData' => 'includes/Metadata.php',
'ReadOnlyError' => 'includes/Exception.php',
'RecentChange' => 'includes/RecentChange.php',
+ 'RedirectSpecialArticle' => 'includes/SpecialPage.php',
'RedirectSpecialPage' => 'includes/SpecialPage.php',
'RegexlikeReplacer' => 'includes/StringUtils.php',
'ReplacementArray' => 'includes/StringUtils.php',
'UnlistedSpecialPage' => 'includes/SpecialPage.php',
'UploadSourceAdapter' => 'includes/Import.php',
'UppercaseCollation' => 'includes/Collation.php',
- 'Uri' => 'includes/Uri.php',
'User' => 'includes/User.php',
'UserArray' => 'includes/UserArray.php',
'UserArrayFromResult' => 'includes/UserArray.php',
'JavaScriptContentHandler' => 'includes/content/JavaScriptContentHandler.php',
'JavaScriptContent' => 'includes/content/JavaScriptContent.php',
'MessageContent' => 'includes/content/MessageContent.php',
+ 'MWContentSerializationException' => 'includes/content/ContentHandler.php',
'TextContentHandler' => 'includes/content/TextContentHandler.php',
'TextContent' => 'includes/content/TextContent.php',
'WikitextContentHandler' => 'includes/content/WikitextContentHandler.php',
'CopyFileOp' => 'includes/filebackend/FileOp.php',
'MoveFileOp' => 'includes/filebackend/FileOp.php',
'DeleteFileOp' => 'includes/filebackend/FileOp.php',
- 'ConcatenateFileOp' => 'includes/filebackend/FileOp.php',
'CreateFileOp' => 'includes/filebackend/FileOp.php',
'NullFileOp' => 'includes/filebackend/FileOp.php',
'Ibm_db2Updater' => 'includes/installer/Ibm_db2Updater.php',
'InstallDocFormatter' => 'includes/installer/InstallDocFormatter.php',
'Installer' => 'includes/installer/Installer.php',
- 'LBFactory_InstallerFake' => 'includes/installer/Installer.php',
'LocalSettingsGenerator' => 'includes/installer/LocalSettingsGenerator.php',
'MysqlInstaller' => 'includes/installer/MysqlInstaller.php',
'MysqlUpdater' => 'includes/installer/MysqlUpdater.php',
'RevDel_LogList' => 'includes/revisiondelete/RevisionDelete.php',
'RevDel_RevisionItem' => 'includes/revisiondelete/RevisionDelete.php',
'RevDel_RevisionList' => 'includes/revisiondelete/RevisionDelete.php',
- 'RevisionDelete' => 'includes/revisiondelete/RevisionDelete.php',
'RevisionDeleter' => 'includes/revisiondelete/RevisionDeleter.php',
'RevisionDeleteUser' => 'includes/revisiondelete/RevisionDeleteUser.php',
'BrokenRedirectsPage' => 'includes/specials/SpecialBrokenRedirects.php',
'CategoryPager' => 'includes/specials/SpecialCategories.php',
'ContribsPager' => 'includes/specials/SpecialContributions.php',
- 'DBLockForm' => 'includes/specials/SpecialLockdb.php',
- 'DBUnlockForm' => 'includes/specials/SpecialUnlockdb.php',
'DeadendPagesPage' => 'includes/specials/SpecialDeadendpages.php',
'DeletedContribsPager' => 'includes/specials/SpecialDeletedContributions.php',
'DeletedContributionsPage' => 'includes/specials/SpecialDeletedContributions.php',
'SpecialLockdb' => 'includes/specials/SpecialLockdb.php',
'SpecialLog' => 'includes/specials/SpecialLog.php',
'SpecialMergeHistory' => 'includes/specials/SpecialMergeHistory.php',
- 'SpecialMostlinkedtemplates' => 'includes/specials/SpecialMostlinkedtemplates.php',
'SpecialNewFiles' => 'includes/specials/SpecialNewimages.php',
'SpecialNewpages' => 'includes/specials/SpecialNewpages.php',
'SpecialPasswordReset' => 'includes/specials/SpecialPasswordReset.php',
'UploadFromUrl' => 'includes/upload/UploadFromUrl.php',
'UploadStash' => 'includes/upload/UploadStash.php',
'UploadStashBadPathException' => 'includes/upload/UploadStash.php',
- 'UploadStashBadVersionException' => 'includes/upload/UploadStash.php',
'UploadStashFile' => 'includes/upload/UploadStash.php',
'UploadStashFileException' => 'includes/upload/UploadStash.php',
'UploadStashFileNotFoundException' => 'includes/upload/UploadStash.php',
'CLDRPluralRuleError' => 'languages/utils/CLDRPluralRuleEvaluator.php',
# maintenance
+ 'BackupDumper' => 'maintenance/backup.inc',
'ConvertLinks' => 'maintenance/convertLinks.php',
'DeleteArchivedFilesImplementation' => 'maintenance/deleteArchivedFiles.inc',
'DeleteArchivedRevisionsImplementation' => 'maintenance/deleteArchivedRevisions.inc',
'DeleteDefaultMessages' => 'maintenance/deleteDefaultMessages.php',
+ 'DumpDBZip2Output' => 'maintenance/backup.inc',
+ 'ExportProgressFilter' => 'maintenance/backup.inc',
'FakeMaintenance' => 'maintenance/Maintenance.php',
+ 'FixExtLinksProtocolRelative' => 'maintenance/fixExtLinksProtocolRelative.php',
'LoggedUpdateMaintenance' => 'maintenance/Maintenance.php',
'Maintenance' => 'maintenance/Maintenance.php',
- 'FixExtLinksProtocolRelative' => 'maintenance/fixExtLinksProtocolRelative.php',
'PopulateCategory' => 'maintenance/populateCategory.php',
'PopulateImageSha1' => 'maintenance/populateImageSha1.php',
'PopulateFilearchiveSha1' => 'maintenance/populateFilearchiveSha1.php',
'InstallerOverrides' => 'mw-config/overrides.php',
'MyLocalSettingsGenerator' => 'mw-config/overrides.php',
- # tests
- 'DbTestPreviewer' => 'tests/testHelpers.inc',
- 'DbTestRecorder' => 'tests/testHelpers.inc',
- 'DelayedParserTest' => 'tests/testHelpers.inc',
- 'TestFileIterator' => 'tests/testHelpers.inc',
- 'TestRecorder' => 'tests/testHelpers.inc',
-
- # tests/phpunit
- 'RevisionStorageTest' => 'tests/phpunit/includes/RevisionStorageTest.php',
- 'WikiPageTest' => 'tests/phpunit/includes/WikiPageTest.php',
-
- # tests/phpunit/content
- 'DummyContentHandlerForTesting' => 'tests/phpunit/includes/content/ContentHandlerTest.php',
- 'DummyContentForTesting' => 'tests/phpunit/includes/content/ContentHandlerTest.php',
- 'JavascriptContentTest' => 'tests/phpunit/includes/content/JavascriptContentTest.php',
- 'TextContentTest' => 'tests/phpunit/includes/content/TextContentTest.php',
-
- # tests/phpunit/includes
- 'GenericArrayObjectTest' => 'tests/phpunit/includes/libs/GenericArrayObjectTest.php',
-
- # tests/phpunit/includes/db
- 'ORMRowTest' => 'tests/phpunit/includes/db/ORMRowTest.php',
-
- # tests/phpunit/includes/site
- 'SiteObjectTest' => 'tests/phpunit/includes/site/SiteObjectTest.php',
- 'TestSites' => 'tests/phpunit/includes/site/TestSites.php',
-
- # tests/parser
- 'ParserTest' => 'tests/parser/parserTest.inc',
- 'ParserTestParserHook' => 'tests/parser/parserTestsParserHook.php',
-
- # tests/selenium
- 'Selenium' => 'tests/selenium/Selenium.php',
- 'SeleniumLoader' => 'tests/selenium/SeleniumLoader.php',
- 'SeleniumTestCase' => 'tests/selenium/SeleniumTestCase.php',
- 'SeleniumTestConsoleLogger' => 'tests/selenium/SeleniumTestConsoleLogger.php',
- 'SeleniumTestHTMLLogger' => 'tests/selenium/SeleniumTestHTMLLogger.php',
- 'SeleniumTestListener' => 'tests/selenium/SeleniumTestListener.php',
- 'SeleniumTestSuite' => 'tests/selenium/SeleniumTestSuite.php',
- 'SeleniumConfig' => 'tests/selenium/SeleniumConfig.php',
-
# skins
'CologneBlueTemplate' => 'skins/CologneBlue.php',
'ModernTemplate' => 'skins/Modern.php',
# Already initialized
return true;
}
+
+ wfProfileIn( __METHOD__ );
+
$dbr = wfGetDB( DB_SLAVE );
$row = $dbr->selectRow(
'category',
__METHOD__
);
+ wfProfileOut( __METHOD__ );
+
if ( !$row ) {
# Okay, there were no contents. Nothing to initialize.
if ( $this->mTitle ) {
}
/** @return mixed DB key name, or false on failure */
- public function getName() { return $this->getX( 'mName' ); }
+ public function getName() {
+ return $this->getX( 'mName' );
+ }
/** @return mixed Category ID, or false on failure */
- public function getID() { return $this->getX( 'mID' ); }
+ public function getID() {
+ return $this->getX( 'mID' );
+ }
/** @return mixed Total number of member pages, or false on failure */
- public function getPageCount() { return $this->getX( 'mPages' ); }
+ public function getPageCount() {
+ return $this->getX( 'mPages' );
+ }
/** @return mixed Number of subcategories, or false on failure */
- public function getSubcatCount() { return $this->getX( 'mSubcats' ); }
+ public function getSubcatCount() {
+ return $this->getX( 'mSubcats' );
+ }
/** @return mixed Number of member files, or false on failure */
- public function getFileCount() { return $this->getX( 'mFiles' ); }
+ public function getFileCount() {
+ return $this->getX( 'mFiles' );
+ }
/**
* @return Title|bool Title for this category, or false on failure.
*/
public function getTitle() {
- if ( $this->mTitle ) return $this->mTitle;
+ if ( $this->mTitle ) {
+ return $this->mTitle;
+ }
if ( !$this->initialize() ) {
return false;
* @return TitleArray object for category members.
*/
public function getMembers( $limit = false, $offset = '' ) {
+ wfProfileIn( __METHOD__ );
+
$dbr = wfGetDB( DB_SLAVE );
$conds = array( 'cl_to' => $this->getName(), 'cl_from = page_id' );
$options = array( 'ORDER BY' => 'cl_sortkey' );
if ( $limit ) {
- $options[ 'LIMIT' ] = $limit;
+ $options['LIMIT'] = $limit;
}
if ( $offset !== '' ) {
$conds[] = 'cl_sortkey > ' . $dbr->addQuotes( $offset );
}
- return TitleArray::newFromResult(
+ $result = TitleArray::newFromResult(
$dbr->select(
array( 'page', 'categorylinks' ),
array( 'page_id', 'page_namespace', 'page_title', 'page_len',
$options
)
);
+
+ wfProfileOut( __METHOD__ );
+
+ return $result;
}
/**
if ( !$this->initialize() ) {
return false;
}
- return $this-> { $key } ;
+ return $this->{$key};
}
/**
}
}
+ wfProfileIn( __METHOD__ );
+
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin( __METHOD__ );
+ $dbw->begin( __METHOD__ );
# Insert the row if it doesn't exist yet (e.g., this is being run via
# update.php from a pre-1.16 schema). TODO: This will cause lots and
$result = $dbw->selectRow(
array( 'categorylinks', 'page' ),
array( 'pages' => 'COUNT(*)',
- 'subcats' => "COUNT($cond1)",
- 'files' => "COUNT($cond2)"
+ 'subcats' => "COUNT($cond1)",
+ 'files' => "COUNT($cond2)"
),
array( 'cl_to' => $this->mName, 'page_id = cl_from' ),
__METHOD__,
);
$dbw->commit( __METHOD__ );
+ wfProfileOut( __METHOD__ );
+
# Now we should update our local counts.
$this->mPages = $result->pages;
$this->mSubcats = $result->subcats;
/**
* Add a subcategory to the internal lists, using a title object
- * @deprecated since 1.17 kept for compatibility, please use addSubcategoryObject instead
+ * @deprecated since 1.17 kept for compatibility, use addSubcategoryObject instead
*/
function addSubcategory( Title $title, $sortkey, $pageLength ) {
wfDeprecated( __METHOD__, '1.17' );
}
/**
- * Get the character to be used for sorting subcategories.
- * If there's a link from Category:A to Category:B, the sortkey of the resulting
- * entry in the categorylinks table is Category:A, not A, which it SHOULD be.
- * Workaround: If sortkey == "Category:".$title, than use $title for sorting,
- * else use sortkey...
- *
- * @param Title $title
- * @param string $sortkey The human-readable sortkey (before transforming to icu or whatever).
+ * Get the character to be used for sorting subcategories.
+ * If there's a link from Category:A to Category:B, the sortkey of the resulting
+ * entry in the categorylinks table is Category:A, not A, which it SHOULD be.
+ * Workaround: If sortkey == "Category:".$title, than use $title for sorting,
+ * else use sortkey...
+ *
+ * @param Title $title
+ * @param string $sortkey The human-readable sortkey (before transforming to icu or whatever).
* @return string
*/
function getSubcategorySortChar( $title, $sortkey ) {
function finaliseCategoryState() {
if ( $this->flip['subcat'] ) {
- $this->children = array_reverse( $this->children );
+ $this->children = array_reverse( $this->children );
$this->children_start_char = array_reverse( $this->children_start_char );
}
if ( $this->flip['page'] ) {
- $this->articles = array_reverse( $this->articles );
+ $this->articles = array_reverse( $this->articles );
$this->articles_start_char = array_reverse( $this->articles_start_char );
}
if ( !$this->showGallery && $this->flip['file'] ) {
- $this->imgsNoGallery = array_reverse( $this->imgsNoGallery );
+ $this->imgsNoGallery = array_reverse( $this->imgsNoGallery );
$this->imgsNoGallery_start_char = array_reverse( $this->imgsNoGallery_start_char );
}
}
'page_is_redirect', 'cl_sortkey', 'cat_id', 'cat_title',
'cat_subcats', 'cat_pages', 'cat_files',
'cl_sortkey_prefix', 'cl_collation' ),
- array_merge( array( 'cl_to' => $this->title->getDBkey() ), $extraConds ),
+ array_merge( array( 'cl_to' => $this->title->getDBkey() ), $extraConds ),
__METHOD__,
array(
'USE INDEX' => array( 'categorylinks' => 'cl_sortkey' ),
'ORDER BY' => $this->flip[$type] ? 'cl_sortkey DESC' : 'cl_sortkey',
),
array(
- 'categorylinks' => array( 'INNER JOIN', 'cl_from = page_id' ),
+ 'categorylinks' => array( 'INNER JOIN', 'cl_from = page_id' ),
'category' => array( 'LEFT JOIN', 'cat_title = page_title AND page_namespace = ' . NS_CATEGORY )
)
);
*/
function formatList( $articles, $articles_start_char, $cutoff = 6 ) {
$list = '';
- if ( count ( $articles ) > $cutoff ) {
+ if ( count( $articles ) > $cutoff ) {
$list = self::columnList( $articles, $articles_start_char );
} elseif ( count( $articles ) > 0 ) {
// for short lists of articles in categories.
$pageLang = $this->title->getPageLanguage();
$attribs = array( 'lang' => $pageLang->getCode(), 'dir' => $pageLang->getDir(),
- 'class' => 'mw-content-'.$pageLang->getDir() );
+ 'class' => 'mw-content-' . $pageLang->getDir() );
$list = Html::rawElement( 'div', $attribs, $list );
return $list;
);
}
- return $this->msg('categoryviewer-pagedlinks')->rawParams($prevLink, $nextLink)->escaped();
+ return $this->msg( 'categoryviewer-pagedlinks' )->rawParams( $prevLink, $nextLink )->escaped();
}
/**
return Title::makeTitle( $title->getNamespace(),
$title->getDBkey(), $fragment );
}
+
/**
* What to do if the category table conflicts with the number of results
* returned? This function says what. Each type is considered independently
$fromOrUntil = true;
}
- if ( $dbcnt == $rescnt || ( ( $rescnt == $this->limit || $fromOrUntil )
- && $dbcnt > $rescnt ) ) {
+ if ( $dbcnt == $rescnt ||
+ ( ( $rescnt == $this->limit || $fromOrUntil ) && $dbcnt > $rescnt )
+ ) {
# Case 1: seems sane.
$totalcnt = $dbcnt;
} elseif ( $rescnt < $this->limit && !$fromOrUntil ) {
*
* Example use :
* <code>
- * # Determines whether the article with the page_id 12345 is in both
- * # "Category 1" and "Category 2" or their subcategories, respectively
+ * # Determines whether the article with the page_id 12345 is in both
+ * # "Category 1" and "Category 2" or their subcategories, respectively
*
- * $cf = new Categoryfinder;
- * $cf->seed(
- * array( 12345 ),
- * array( 'Category 1', 'Category 2' ),
- * 'AND'
- * );
- * $a = $cf->run();
- * print implode( ',' , $a );
+ * $cf = new Categoryfinder;
+ * $cf->seed(
+ * array( 12345 ),
+ * array( 'Category 1', 'Category 2' ),
+ * 'AND'
+ * );
+ * $a = $cf->run();
+ * print implode( ',' , $a );
* </code>
*
*/
# iterate through the parents
foreach ( $this->parents[$id] as $p ) {
- $pname = $p->cl_to ;
+ $pname = $p->cl_to;
# Is this a condition?
if ( isset( $conds[$pname] ) ) {
* Scans a "parent layer" of the articles/categories in $this->next
*/
function scan_next_layer() {
+ wfProfileIn( __METHOD__ );
+
# Find all parents of the article currently in $this->next
$layer = array();
$res = $this->dbr->select(
foreach ( $layer as $v ) {
$this->deadend[$v] = $v;
}
- }
+ wfProfileOut( __METHOD__ );
+ }
}
* container : backend container name the zone is in
* directory : root path within container for the zone
* url : base URL to the root of the zone
- * handlerUrl : base script handled URL to the root of the zone
+ * urlsByExt : map of file extension types to base URLs
+ * (useful for using a different cache for videos)
+ * handlerUrl : base script-handled URL to the root of the zone
* (see FileRepo::getZoneHandlerUrl() function)
* Zones default to using "<repo name>-<zone name>" as the container name
* and default to using the container root as the zone's root directory.
*/
$wgUseCombinedLoginLink = false;
+/**
+ * Appearance of user page and talk page labels in personal tools.
+ * - true = combine links into a single label
+ * - false = keep links in separate labels
+ */
+$wgVectorCombineUserTalk = false;
+
/**
* Search form look for Vector skin only.
* - true = use an icon search button
$this->isConflict = true;
$content = $textbox_content; // do not try to merge here!
} elseif ( $this->isConflict ) {
- $contentObj = $content;
# Attempt merge
- if ( $this->mergeChangesInto( $content ) ) {
+ if ( $this->mergeChangesIntoContent( $content ) ) {
// Successful merge! Maybe we should tell the user the good news?
$this->isConflict = false;
- $content = $this->toEditContent( $content );
wfDebug( __METHOD__ . ": Suppressing edit conflict, successful merge.\n" );
} else {
$this->section = '';
- $this->textbox1 = ContentHandler::getContentText( $contentObj );
+ $this->textbox1 = ContentHandler::getContentText( $content );
wfDebug( __METHOD__ . ": Keeping edit conflict, failed merge.\n" );
}
}
function mergeChangesInto( &$editText ){
ContentHandler::deprecated( __METHOD__, "1.21" );
- wfProfileIn( __METHOD__ );
-
- $db = wfGetDB( DB_MASTER );
-
- // This is the revision the editor started from
- $baseRevision = $this->getBaseRevision();
- if ( is_null( $baseRevision ) ) {
- wfProfileOut( __METHOD__ );
- return false;
- }
- $baseText = $baseRevision->getText();
-
- // The current state, we want to merge updates into it
- $currentRevision = Revision::loadFromTitle( $db, $this->mTitle );
- if ( is_null( $currentRevision ) ) {
- wfProfileOut( __METHOD__ );
- return false;
- }
- $currentText = $currentRevision->getText();
+ $editContent = $this->toEditContent( $editText );
- $result = '';
- $editText = $this->toEditText( $editText );
+ $ok = $this->mergeChangesIntoContent( $editContent );
- if ( wfMerge( $baseText, $editText, $currentText, $result ) ) {
- $editText = $result;
- wfProfileOut( __METHOD__ );
+ if ( $ok ) {
+ $editText = $this->toEditText( $editContent );
return true;
- } else {
- wfProfileOut( __METHOD__ );
- return false;
}
+ return false;
}
/**
$mytextFile = fopen( $mytextName = tempnam( $td, 'merge-mine-' ), 'w' );
$yourtextFile = fopen( $yourtextName = tempnam( $td, 'merge-your-' ), 'w' );
- fwrite( $oldtextFile, $old );
+ # NOTE: diff3 issues a warning to stderr if any of the files does not end with
+ # a newline character. To avoid this, we normalize the trailing whitespace before
+ # creating the diff.
+
+ fwrite( $oldtextFile, rtrim( $old ) . "\n" );
fclose( $oldtextFile );
- fwrite( $mytextFile, $mine );
+ fwrite( $mytextFile, rtrim( $mine ) . "\n" );
fclose( $mytextFile );
- fwrite( $yourtextFile, $yours );
+ fwrite( $yourtextFile, rtrim( $yours ) . "\n" );
fclose( $yourtextFile );
# Check for a conflict
* @since 1.16
*/
class Html {
- # List of void elements from HTML5, section 8.1.2 as of 2011-08-12
+ // List of void elements from HTML5, section 8.1.2 as of 2011-08-12
private static $voidElements = array(
'area',
'base',
'wbr',
);
- # Boolean attributes, which may have the value omitted entirely. Manually
- # collected from the HTML5 spec as of 2011-08-12.
+ // Boolean attributes, which may have the value omitted entirely. Manually
+ // collected from the HTML5 spec as of 2011-08-12.
private static $boolAttribs = array(
'async',
'autofocus',
'selected',
'truespeed',
'typemustmatch',
- # HTML5 Microdata
+ // HTML5 Microdata
'itemscope',
);
$start = self::openElement( $element, $attribs );
if ( in_array( $element, self::$voidElements ) ) {
if ( $wgWellFormedXml ) {
- # Silly XML.
+ // Silly XML.
return substr( $start, 0, -1 ) . ' />';
}
return $start;
*/
public static function element( $element, $attribs = array(), $contents = '' ) {
return self::rawElement( $element, $attribs, strtr( $contents, array(
- # There's no point in escaping quotes, >, etc. in the contents of
- # elements.
+ // There's no point in escaping quotes, >, etc. in the contents of
+ // elements.
'&' => '&',
'<' => '<'
) ) );
public static function openElement( $element, $attribs = array() ) {
global $wgHtml5, $wgWellFormedXml;
$attribs = (array)$attribs;
- # This is not required in HTML5, but let's do it anyway, for
- # consistency and better compression.
+ // This is not required in HTML5, but let's do it anyway, for
+ // consistency and better compression.
$element = strtolower( $element );
- # In text/html, initial <html> and <head> tags can be omitted under
- # pretty much any sane circumstances, if they have no attributes. See:
- # <http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#optional-tags>
+ // In text/html, initial <html> and <head> tags can be omitted under
+ // pretty much any sane circumstances, if they have no attributes. See:
+ // <http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#optional-tags>
if ( !$wgWellFormedXml && !$attribs
&& in_array( $element, array( 'html', 'head' ) ) ) {
return '';
}
- # Remove invalid input types
+ // Remove invalid input types
if ( $element == 'input' ) {
$validTypes = array(
'hidden',
'button',
);
- # Allow more input types in HTML5 mode
+ // Allow more input types in HTML5 mode
if( $wgHtml5 ) {
$validTypes = array_merge( $validTypes, array(
'datetime',
$element = strtolower( $element );
- # Reference:
- # http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#optional-tags
+ // Reference:
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#optional-tags
if ( !$wgWellFormedXml && in_array( $element, array(
'html',
'head',
* @return array An array of attributes functionally identical to $attribs
*/
private static function dropDefaults( $element, $attribs ) {
- # Don't bother doing anything if we aren't outputting HTML5; it's too
- # much of a pain to maintain two sets of defaults.
+ // Don't bother doing anything if we aren't outputting HTML5; it's too
+ // much of a pain to maintain two sets of defaults.
global $wgHtml5;
if ( !$wgHtml5 ) {
return $attribs;
}
- # Whenever altering this array, please provide a covering test case
- # in HtmlTest::provideElementsWithAttributesHavingDefaultValues
+ // Whenever altering this array, please provide a covering test case
+ // in HtmlTest::provideElementsWithAttributesHavingDefaultValues
static $attribDefaults = array(
'area' => array( 'shape' => 'rect' ),
'button' => array(
'keygen' => array( 'keytype' => 'rsa' ),
'link' => array( 'media' => 'all' ),
'menu' => array( 'type' => 'list' ),
- # Note: the use of text/javascript here instead of other JavaScript
- # MIME types follows the HTML5 spec.
+ // Note: the use of text/javascript here instead of other JavaScript
+ // MIME types follows the HTML5 spec.
'script' => array( 'type' => 'text/javascript' ),
'style' => array(
'media' => 'all',
$value = strval( $value );
}
- # Simple checks using $attribDefaults
+ // Simple checks using $attribDefaults
if ( isset( $attribDefaults[$element][$lcattrib] ) &&
$attribDefaults[$element][$lcattrib] == $value ) {
unset( $attribs[$attrib] );
}
}
- # More subtle checks
+ // More subtle checks
if ( $element === 'link' && isset( $attribs['type'] )
&& strval( $attribs['type'] ) == 'text/css' ) {
unset( $attribs['type'] );
if ( in_array( 'multiple', $attribs )
|| ( isset( $attribs['multiple'] ) && $attribs['multiple'] !== false )
) {
- # A multi-select
+ // A multi-select
if ( strval( $attribs['size'] ) == '4' ) {
unset( $attribs['size'] );
}
} else {
- # Single select
+ // Single select
if ( strval( $attribs['size'] ) == '1' ) {
unset( $attribs['size'] );
}
continue;
}
- # For boolean attributes, support array( 'foo' ) instead of
- # requiring array( 'foo' => 'meaningless' ).
+ // For boolean attributes, support array( 'foo' ) instead of
+ // requiring array( 'foo' => 'meaningless' ).
if ( is_int( $key )
&& in_array( strtolower( $value ), self::$boolAttribs ) ) {
$key = $value;
}
- # Not technically required in HTML5, but required in XHTML 1.0,
- # and we'd like consistency and better compression anyway.
+ // Not technically required in HTML5, but required in XHTML 1.0,
+ // and we'd like consistency and better compression anyway.
$key = strtolower( $key );
- # Here we're blacklisting some HTML5-only attributes...
+ // Here we're blacklisting some HTML5-only attributes...
if ( !$wgHtml5 && in_array( $key, self::$HTMLFiveOnlyAttribs )
) {
continue;
}
- # Bug 23769: Blacklist all form validation attributes for now. Current
- # (June 2010) WebKit has no UI, so the form just refuses to submit
- # without telling the user why, which is much worse than failing
- # server-side validation. Opera is the only other implementation at
- # this time, and has ugly UI, so just kill the feature entirely until
- # we have at least one good implementation.
+ // Bug 23769: Blacklist all form validation attributes for now. Current
+ // (June 2010) WebKit has no UI, so the form just refuses to submit
+ // without telling the user why, which is much worse than failing
+ // server-side validation. Opera is the only other implementation at
+ // this time, and has ugly UI, so just kill the feature entirely until
+ // we have at least one good implementation.
if ( in_array( $key, array( 'max', 'min', 'pattern', 'required', 'step' ) ) ) {
continue;
}
'rel',
);
- # Specific features for attributes that allow a list of space-separated values
+ // Specific features for attributes that allow a list of space-separated values
if ( in_array( $key, $spaceSeparatedListAttributes ) ) {
// Apply some normalization and remove duplicates
$value = implode( ' ', array_unique( $value ) );
}
- # See the "Attributes" section in the HTML syntax part of HTML5,
- # 9.1.2.3 as of 2009-08-10. Most attributes can have quotation
- # marks omitted, but not all. (Although a literal " is not
- # permitted, we don't check for that, since it will be escaped
- # anyway.)
+ // See the "Attributes" section in the HTML syntax part of HTML5,
+ // 9.1.2.3 as of 2009-08-10. Most attributes can have quotation
+ // marks omitted, but not all. (Although a literal " is not
+ // permitted, we don't check for that, since it will be escaped
+ // anyway.)
#
- # See also research done on further characters that need to be
- # escaped: http://code.google.com/p/html5lib/issues/detail?id=93
+ // See also research done on further characters that need to be
+ // escaped: http://code.google.com/p/html5lib/issues/detail?id=93
$badChars = "\\x00- '=<>`/\x{00a0}\x{1680}\x{180e}\x{180F}\x{2000}\x{2001}"
. "\x{2002}\x{2003}\x{2004}\x{2005}\x{2006}\x{2007}\x{2008}\x{2009}"
. "\x{200A}\x{2028}\x{2029}\x{202F}\x{205F}\x{3000}";
}
if ( in_array( $key, self::$boolAttribs ) ) {
- # In XHTML 1.0 Transitional, the value needs to be equal to the
- # key. In HTML5, we can leave the value empty instead. If we
- # don't need well-formed XML, we can omit the = entirely.
+ // In XHTML 1.0 Transitional, the value needs to be equal to the
+ // key. In HTML5, we can leave the value empty instead. If we
+ // don't need well-formed XML, we can omit the = entirely.
if ( !$wgWellFormedXml ) {
$ret .= " $key";
} elseif ( $wgHtml5 ) {
$ret .= " $key=\"$key\"";
}
} else {
- # Apparently we need to entity-encode \n, \r, \t, although the
- # spec doesn't mention that. Since we're doing strtr() anyway,
- # and we don't need <> escaped here, we may as well not call
- # htmlspecialchars().
- # @todo FIXME: Verify that we actually need to
- # escape \n\r\t here, and explain why, exactly.
+ // Apparently we need to entity-encode \n, \r, \t, although the
+ // spec doesn't mention that. Since we're doing strtr() anyway,
+ // and we don't need <> escaped here, we may as well not call
+ // htmlspecialchars().
+ // @todo FIXME: Verify that we actually need to
+ // escape \n\r\t here, and explain why, exactly.
#
- # We could call Sanitizer::encodeAttribute() for this, but we
- # don't because we're stubborn and like our marginal savings on
- # byte size from not having to encode unnecessary quotes.
+ // We could call Sanitizer::encodeAttribute() for this, but we
+ // don't because we're stubborn and like our marginal savings on
+ // byte size from not having to encode unnecessary quotes.
$map = array(
'&' => '&',
'"' => '"',
"\t" => '	'
);
if ( $wgWellFormedXml ) {
- # This is allowed per spec: <http://www.w3.org/TR/xml/#NT-AttValue>
- # But reportedly it breaks some XML tools?
- # @todo FIXME: Is this really true?
+ // This is allowed per spec: <http://www.w3.org/TR/xml/#NT-AttValue>
+ // But reportedly it breaks some XML tools?
+ // @todo FIXME: Is this really true?
$map['<'] = '<';
}
$ret .= " $key=$quote" . strtr( $value, $map ) . $quote;
*/
public static function newFromConds( $conds, $fname = __METHOD__ ) {
$dbr = wfGetDB( DB_SLAVE );
- $row = $dbr->selectRow( 'recentchanges', '*', $conds, $fname );
+ $row = $dbr->selectRow( 'recentchanges', self::selectFields(), $conds, $fname );
if ( $row !== false ) {
return self::newFromRow( $row );
} else {
}
}
+ /**
+ * Return the list of recentchanges fields that should be selected to create
+ * a new recentchanges object.
+ * @return array
+ */
+ public static function selectFields() {
+ return array(
+ 'rc_id',
+ 'rc_timestamp',
+ 'rc_cur_time',
+ 'rc_user',
+ 'rc_user_text',
+ 'rc_namespace',
+ 'rc_title',
+ 'rc_comment',
+ 'rc_minor',
+ 'rc_bot',
+ 'rc_new',
+ 'rc_cur_id',
+ 'rc_this_oldid',
+ 'rc_last_oldid',
+ 'rc_type',
+ 'rc_patrolled',
+ 'rc_ip',
+ 'rc_old_len',
+ 'rc_new_len',
+ 'rc_deleted',
+ 'rc_logid',
+ 'rc_log_type',
+ 'rc_log_action',
+ 'rc_params',
+ );
+ }
+
# Accessors
/**
protected $mContentFormat;
/**
- * @var Content
+ * @var Content|null|bool
*/
protected $mContent;
* Returns null if no such revision can be found.
*
* $flags include:
- * Revision::READ_LATEST : Select the data from the master
+ * Revision::READ_LATEST : Select the data from the master (since 1.20)
* Revision::READ_LOCKING : Select & lock the data from the master
*
* @param $revId Integer
}
/**
- * Gets the content object for the revision
+ * Gets the content object for the revision (or null on failure).
+ *
+ * Note that for mutable Content objects, each call to this method will return a
+ * fresh clone.
*
* @since 1.21
- * @return Content
+ * @return Content|null the Revision's content, or null on failure.
*/
protected function getContentInternal() {
if( is_null( $this->mContent ) ) {
// Revision is immutable. Load on demand:
-
- $handler = $this->getContentHandler();
- $format = $this->getContentFormat();
-
if( is_null( $this->mText ) ) {
- // Load text on demand:
$this->mText = $this->loadText();
}
- $this->mContent = is_null( $this->mText ) ? null : $handler->unserializeContent( $this->mText, $format );
+ if ( $this->mText !== null && $this->mText !== false ) {
+ // Unserialize content
+ $handler = $this->getContentHandler();
+ $format = $this->getContentFormat();
+
+ $this->mContent = $handler->unserializeContent( $this->mText, $format );
+ } else {
+ $this->mContent = false; // negative caching!
+ }
}
- return $this->mContent->copy(); // NOTE: copy() will return $this for immutable content objects
+ // NOTE: copy() will return $this for immutable content objects
+ return $this->mContent ? $this->mContent->copy() : null;
}
/**
$content = $this->getContent( Revision::RAW );
- if ( !$content->isValid() ) {
+ if ( !$content || !$content->isValid() ) {
$t = $title->getPrefixedDBkey();
throw new MWException( "Content of $t is not valid! Content model is $model" );
* Lazy-load the revision's text.
* Currently hardcoded to the 'text' table storage engine.
*
- * @return String
+<<<<<<< HEAD
+ * @return String|boolean the revision text, or false on failure
+=======
+ * @return String|bool the revision's text, or false on failure
+>>>>>>> (Bug 41244) Gracefully handle failure to load text blob.
*/
protected function loadText() {
wfProfileIn( __METHOD__ );
return false;
}
+ /**
+ * Is this page cached?
+ * Expensive pages are cached or disabled in miser mode.
+ * Used by QueryPage and subclasses, moved here so that
+ * Special:SpecialPages can safely call it for all special pages.
+ *
+ * @return Boolean
+ * @since 1.21
+ */
+ public function isCached() {
+ return false;
+ }
+
/**
* Can be overridden by subclasses with more complicated permissions
* schemes.
$content = $rev->getContent();
# Does the redirect point to the source?
# Or is it a broken self-redirect, usually caused by namespace collisions?
- $redirTitle = $content->getRedirectTarget();
+ $redirTitle = $content ? $content->getRedirectTarget() : null;
if ( $redirTitle ) {
if ( $redirTitle->getPrefixedDBkey() != $this->getPrefixedDBkey() &&
}
if ( is_array( $data ) ) {
- if ( is_array( $data['user_groups'] ) ) {
+ if ( isset( $data['user_groups'] ) && is_array( $data['user_groups'] ) ) {
$this->mGroups = $data['user_groups'];
}
- if ( is_array( $data['user_properties'] ) ) {
+ if ( isset( $data['user_properties'] ) && is_array( $data['user_properties'] ) ) {
$this->loadOptions( $data['user_properties'] );
}
}
$this->mRights = self::getGroupPermissions( $this->getEffectiveGroups() );
wfRunHooks( 'UserGetRights', array( $this, &$this->mRights ) );
// Force reindexation of rights when a hook has unset one of them
- $this->mRights = array_values( $this->mRights );
+ $this->mRights = array_values( array_unique( $this->mRights ) );
}
return $this->mRights;
}
) );
# Hook for additional groups
wfRunHooks( 'UserEffectiveGroups', array( &$this, &$this->mEffectiveGroups ) );
+ // Force reindexation of groups when a hook has unset one of them
+ $this->mEffectiveGroups = array_values( array_unique( $this->mEffectiveGroups ) );
wfProfileOut( __METHOD__ );
}
return $this->mEffectiveGroups;
$count = $this->initEditCount();
}
wfProfileOut( __METHOD__ );
- $this->mEditCount = $count;
+ $this->mEditCount = intval( $count );
}
return $this->mEditCount;
} else {
// Pull from a slave to be less cruel to servers
// Accuracy isn't the point anyway here
$dbr = wfGetDB( DB_SLAVE );
- $count = $dbr->selectField(
+ $count = (int) $dbr->selectField(
'revision',
'COUNT(rev_user)',
array( 'rev_user' => $this->getId() ),
wfProfileIn( __METHOD__ );
$content = $revision->getContent();
- $len = $content->getSize();
- $rt = $content->getUltimateRedirectTarget();
+ $len = $content ? $content->getSize() : 0;
+ $rt = $content ? $content->getUltimateRedirectTarget() : null;
$conditions = array( 'page_id' => $this->getId() );
// Bug 30711: always use current version when adding a new section
if ( is_null( $edittime ) || $section == 'new' ) {
$oldContent = $this->getContent();
- if ( ! $oldContent ) {
- wfDebug( __METHOD__ . ": no page text\n" );
- wfProfileOut( __METHOD__ );
- return null;
- }
} else {
$dbw = wfGetDB( DB_MASTER );
$rev = Revision::loadFromTimestamp( $dbw, $this->mTitle, $edittime );
$oldContent = $rev->getContent();
}
+ if ( ! $oldContent ) {
+ wfDebug( __METHOD__ . ": no page text\n" );
+ wfProfileOut( __METHOD__ );
+ return null;
+ }
+
+ //FIXME: $oldContent might be null?
$newContent = $oldContent->replaceSection( $section, $sectionContent, $sectionTitle );
}
# Bug 37225: use accessor to get the text as Revision may trim it
$content = $revision->getContent(); // sanity; get normalized version
+ if ( $content ) {
+ $newsize = $content->getSize();
+ }
+
# Update the page record with revision data
$this->updateRevisionOn( $dbw, $revision, 0 );
$this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
# Add RC row to the DB
$rc = RecentChange::notifyNew( $now, $this->mTitle, $isminor, $user, $summary, $bot,
- '', $content->getSize(), $revisionId, $patrolled );
+ '', $newsize, $revisionId, $patrolled );
# Log auto-patrolled edits
if ( $patrolled ) {
* @since 1.21
*/
public function prepareContentForEdit( Content $content, $revid = null, User $user = null, $serialization_format = null ) {
- global $wgParser, $wgContLang, $wgUser;
+ global $wgContLang, $wgUser;
$user = is_null( $user ) ? $wgUser : $user;
//XXX: check $user->getId() here???
$edit = (object)array();
$edit->revid = $revid;
- $edit->pstContent = $content->preSaveTransform( $this->mTitle, $user, $popts );
- $edit->pst = $edit->pstContent->serialize( $serialization_format ); #XXX: do we need this??
- $edit->format = $serialization_format;
+ $edit->pstContent = $content ? $content->preSaveTransform( $this->mTitle, $user, $popts ) : null;
+ $edit->format = $serialization_format;
$edit->popts = $this->makeParserOptions( 'canonical' );
-
- $edit->output = $edit->pstContent->getParserOutput( $this->mTitle, $revid, $edit->popts );
+ $edit->output = $edit->pstContent ? $edit->pstContent->getParserOutput( $this->mTitle, $revid, $edit->popts ) : null;
$edit->newContent = $content;
$edit->oldContent = $this->getContent( Revision::RAW );
#NOTE: B/C for hooks! don't use these fields!
- $edit->newText = ContentHandler::getContentText( $edit->newContent );
+ $edit->newText = $edit->newContent ? ContentHandler::getContentText( $edit->newContent ) : '';
$edit->oldText = $edit->oldContent ? ContentHandler::getContentText( $edit->oldContent ) : '';
+ $edit->pst = $edit->pstContent ? $edit->pstContent->serialize( $serialization_format ) : '';
$this->mPreparedEdit = $edit;
-
return $edit;
}
}
# Update the links tables and other secondary data
- $updates = $content->getSecondaryDataUpdates( $this->getTitle(), null, true, $editInfo->output );
- DataUpdate::runUpdates( $updates );
+ if ( $content ) {
+ $updates = $content->getSecondaryDataUpdates( $this->getTitle(), null, true, $editInfo->output );
+ DataUpdate::runUpdates( $updates );
+ }
wfRunHooks( 'ArticleEditUpdates', array( &$this, &$editInfo, $options['changed'] ) );
if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
#XXX: could skip pseudo-messages like js/css here, based on content model.
- $msgtext = $content->getWikitextForTransclusion();
+ $msgtext = $content ? $content->getWikitextForTransclusion() : null;
if ( $msgtext === false || $msgtext === null ) $msgtext = '';
MessageCache::singleton()->replace( $shortTitle, $msgtext );
// rvstart and rvstartid when that is supplied.
if ( !is_null( $params['continue'] ) ) {
$params['startid'] = $params['continue'];
- unset( $params['start'] );
+ $params['start'] = null;
}
// This code makes an assumption that sorting by rev_id and rev_timestamp produces
if ( !isset( $userGroups ) ) {
$user = User::newFromRow( $row );
} else {
- if ( !is_array( $userGroups[$row->user_name] ) ) {
+ if ( !isset( $userGroups[$row->user_name] ) || !is_array( $userGroups[$row->user_name] ) ) {
$userGroups[$row->user_name] = array();
}
$user = User::newFromRow( $row, array( 'user_groups' => $userGroups[$row->user_name] ) );
public function matchMagicWord( MagicWord $word ) {
return false;
}
+
+ /**
+ * @see Content::convert()
+ *
+ * This base implementation calls the hook ConvertContent to enable custom conversions.
+ * Subclasses may override this to implement conversion for "their" content model.
+ *
+ * @param String $toModel the desired content model, use the CONTENT_MODEL_XXX flags.
+ * @param String $lossy flag, set to "lossy" to allow lossy conversion. If lossy conversion is
+ * not allowed, full round-trip conversion is expected to work without losing information.
+ *
+ * @return Content|bool A content object with the content model $toModel, or false if
+ * that conversion is not supported.
+ */
+ public function convert( $toModel, $lossy = '' ) {
+ if ( $this->getModel() === $toModel ) {
+ //nothing to do, shorten out.
+ return $this;
+ }
+
+ $lossy = ( $lossy === 'lossy' ); // string flag, convert to boolean for convenience
+ $result = false;
+
+ wfRunHooks( 'ConvertContent', array( $this, $toModel, $lossy, &$result ) );
+ return $result;
+ }
}
/**
* @since 1.21
*
- * @return string The wikitext to include when another page includes this
+ * @return string|false The wikitext to include when another page includes this
* content, or false if the content is not includable in a wikitext page.
*
* @todo allow native handling, bypassing wikitext representation, like
*/
public function matchMagicWord( MagicWord $word );
- // TODO: ImagePage and CategoryPage interfere with per-content action handlers
+ /**
+ * Converts this content object into another content object with the given content model,
+ * if that is possible.
+ *
+ * @param String $toModel the desired content model, use the CONTENT_MODEL_XXX flags.
+ * @param String $lossy flag, set to "lossy" to allow lossy conversion. If lossy conversion is
+ * not allowed, full round-trip conversion is expected to work without losing information.
+ *
+ * @return Content|bool A content object with the content model $toModel, or false if
+ * that conversion is not supported.
+ */
+ public function convert( $toModel, $lossy = '' );
+
+ // TODO: ImagePage and CategoryPage interfere with per-content action handlers
// TODO: nice&sane integration of GeSHi syntax highlighting
// [11:59] <vvv> Hooks are ugly; make CodeHighlighter interface and a
// config to set the class which handles syntax highlighting
$rcid = 0, # FIXME: use everywhere!
$refreshCache = false, $unhide = false
) {
- $this->checkModelID( $context->getTitle()->getContentModel() );
-
$diffEngineClass = $this->getDiffEngineClass();
return new $diffEngineClass( $context, $old, $new, $rcid, $refreshCache, $unhide );
}
/**
- * Returns the text represented by this Content object, as a string.
+ * Returns attempts to convert this content object to wikitext,
+ * and then returns the text string. The conversion may be lossy.
*
- * @return string: the raw text
+ * @note: this allows any text-based content to be transcluded as if it was wikitext.
+ *
+ * @return string|false: the raw text, or null if the conversion failed
*/
public function getWikitextForTransclusion( ) {
- return $this->getNativeData();
+ $wikitext = $this->convert( CONTENT_MODEL_WIKITEXT, 'lossy' );
+
+ if ( $wikitext ) {
+ return $wikitext->getNativeData();
+ } else {
+ return false;
+ }
}
/**
# TODO: make Highlighter interface, use highlighter here, if available
return htmlspecialchars( $this->getNativeData() );
}
+
+ /**
+ * @see Content::convert()
+ *
+ * This implementation provides lossless conversion between content models based
+ * on TextContent.
+ *
+ * @param String $toModel the desired content model, use the CONTENT_MODEL_XXX flags.
+ * @param String $lossy flag, set to "lossy" to allow lossy conversion. If lossy conversion is
+ * not allowed, full round-trip conversion is expected to work without losing information.
+ *
+ * @return Content|bool A content object with the content model $toModel, or false if
+ * that conversion is not supported.
+ */
+ public function convert( $toModel, $lossy = '' ) {
+ $converted = parent::convert( $toModel, $lossy );
+
+ if ( $converted !== false ) {
+ return $converted;
+ }
+
+ $toHandler = ContentHandler::getForModelID( $toModel );
+
+ if ( $toHandler instanceof TextContentHandler ) {
+ //NOTE: ignore content serialization format - it's just text anyway.
+ $text = $this->getNativeData();
+ $converted = $toHandler->unserializeContent( $text );
+ }
+
+ return $converted;
+ }
}
*/
public function setTitle( Title $t ) {
$this->title = $t;
+ // Erase the WikiPage so a new one with the new title gets created.
+ $this->wikipage = null;
}
/**
* @param $p WikiPage object
*/
public function setWikiPage( WikiPage $p ) {
+ $contextTitle = $this->getTitle();
+ $pageTitle = $p->getTitle();
+ if ( !$contextTitle || !$pageTitle->equals( $contextTitle ) ) {
+ $this->setTitle( $pageTitle );
+ }
+ // Defer this to the end since setTitle sets it to null.
$this->wikipage = $p;
}
switch ( $type ) {
case 'array':
$value = (array)$value;
+ // fall-through!
case 'blob':
$value = serialize( $value );
+ // fall-through!
}
$values[$this->table->getPrefixedField( $name )] = $value;
* @return boolean Success indicator
*/
protected function saveExisting( $functionName = null ) {
- $dbw = wfGetDB( DB_MASTER );
+ $dbw = $this->table->getWriteDbConnection();
$success = $dbw->update(
$this->table->getName(),
is_null( $functionName ) ? __METHOD__ : $functionName
);
+ $this->table->releaseConnection( $dbw );
+
// DatabaseBase::update does not always return true for success as documented...
return $success !== false;
}
* @return boolean Success indicator
*/
protected function insert( $functionName = null, array $options = null ) {
- $dbw = wfGetDB( DB_MASTER );
+ $dbw = $this->table->getWriteDbConnection();
$success = $dbw->insert(
$this->table->getName(),
$this->getWriteValues(),
is_null( $functionName ) ? __METHOD__ : $functionName,
- is_null( $options ) ? array( 'IGNORE' ) : $options
+ $options
);
// DatabaseBase::insert does not always return true for success as documented...
$this->setField( 'id', $dbw->insertId() );
}
+ $this->table->releaseConnection( $dbw );
+
return $success;
}
$absoluteAmount = abs( $amount );
$isNegative = $amount < 0;
- $dbw = wfGetDB( DB_MASTER );
+ $dbw = $this->table->getWriteDbConnection();
$fullField = $this->table->getPrefixedField( $field );
$this->setField( $field, $this->getField( $field ) + $amount );
}
+ $this->table->releaseConnection( $dbw );
+
return $success;
}
if ( ContentHandler::runLegacyHooks( 'ShowRawCssJs', array( $this->mNewContent, $this->mNewPage, $out ) ) ) {
// NOTE: deprecated hook, B/C only
// use the content object's own rendering
- $po = $this->mNewRev->getContent()->getParserOutput( $this->mNewRev->getTitle(), $this->mNewRev->getId() );
- $out->addHTML( $po->getText() );
+ $cnt = $this->mNewRev->getContent();
+ $po = $cnt ? $cnt->getParserOutput( $this->mNewRev->getTitle(), $this->mNewRev->getId() ) : null;
+ $txt = $po ? $po->getText() : '';
+ $out->addHTML( $txt );
}
} elseif( !wfRunHooks( 'ArticleContentViewCustom', array( $this->mNewContent, $this->mNewPage, $out ) ) ) {
// Handled by extension
$parserOutput = $this->getParserOutput( $wikiPage, $this->mNewRev );
# Also try to load it as a redirect
- $rt = $this->mNewContent->getRedirectTarget();
+ $rt = $this->mNewContent ? $this->mNewContent->getRedirectTarget() : null;
if ( $rt ) {
$article = Article::newFromTitle( $this->mNewPage, $this->getContext() );
}
if ( $this->mOldRev ) {
$this->mOldContent = $this->mOldRev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
- if ( $this->mOldContent === false ) {
+ if ( $this->mOldContent === null ) {
return false;
}
}
if ( $this->mNewRev ) {
$this->mNewContent = $this->mNewRev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
- if ( $this->mNewContent === false ) {
+ if ( $this->mNewContent === null ) {
return false;
}
}
return $status;
}
- if ( file_exists( $dest ) ) {
- $ok = unlink( $dest );
- if ( !$ok ) {
- $status->fatal( 'backend-fail-delete', $params['dst'] );
- return $status;
- }
- }
-
if ( !empty( $params['async'] ) ) { // deferred
- $cmd = implode( ' ', array( wfIsWindows() ? 'COPY' : 'cp',
+ $cmd = implode( ' ', array(
+ wfIsWindows() ? 'COPY /B /Y' : 'cp', // (binary, overwrite)
wfEscapeShellArg( $this->cleanPathSlashes( $params['src'] ) ),
wfEscapeShellArg( $this->cleanPathSlashes( $dest ) )
) );
return $status; // do nothing; either OK or bad status
}
- if ( file_exists( $dest ) ) {
- $ok = unlink( $dest );
- if ( !$ok ) {
- $status->fatal( 'backend-fail-delete', $params['dst'] );
- return $status;
- }
- }
-
if ( !empty( $params['async'] ) ) { // deferred
- $cmd = implode( ' ', array( wfIsWindows() ? 'COPY' : 'cp',
+ $cmd = implode( ' ', array(
+ wfIsWindows() ? 'COPY /B /Y' : 'cp', // (binary, overwrite)
wfEscapeShellArg( $this->cleanPathSlashes( $source ) ),
wfEscapeShellArg( $this->cleanPathSlashes( $dest ) )
) );
return $status; // do nothing; either OK or bad status
}
- if ( file_exists( $dest ) ) {
- // Windows does not support moving over existing files
- if ( wfIsWindows() ) {
- $ok = unlink( $dest );
- if ( !$ok ) {
- $status->fatal( 'backend-fail-delete', $params['dst'] );
- return $status;
- }
- }
- }
-
if ( !empty( $params['async'] ) ) { // deferred
- $cmd = implode( ' ', array( wfIsWindows() ? 'MOVE' : 'mv',
+ $cmd = implode( ' ', array(
+ wfIsWindows() ? 'MOVE /Y' : 'mv', // (overwrite)
wfEscapeShellArg( $this->cleanPathSlashes( $source ) ),
wfEscapeShellArg( $this->cleanPathSlashes( $dest ) )
) );
}
if ( !empty( $params['async'] ) ) { // deferred
- $cmd = implode( ' ', array( wfIsWindows() ? 'DEL' : 'unlink',
+ $cmd = implode( ' ', array(
+ wfIsWindows() ? 'DEL' : 'unlink',
wfEscapeShellArg( $this->cleanPathSlashes( $source ) )
) );
$status->value = new FSFileOpHandle( $this, $params, 'Copy', $cmd );
return $status;
}
- if ( file_exists( $dest ) ) {
- $ok = unlink( $dest );
- if ( !$ok ) {
- $status->fatal( 'backend-fail-delete', $params['dst'] );
- return $status;
- }
- }
-
if ( !empty( $params['async'] ) ) { // deferred
$tempFile = TempFSFile::factory( 'create_', 'tmp' );
if ( !$tempFile ) {
$status->fatal( 'backend-fail-create', $params['dst'] );
return $status;
}
- $cmd = implode( ' ', array( wfIsWindows() ? 'COPY' : 'cp',
+ $cmd = implode( ' ', array(
+ wfIsWindows() ? 'COPY /B /Y' : 'cp', // (binary, overwrite)
wfEscapeShellArg( $this->cleanPathSlashes( $tempFile->getPath() ) ),
wfEscapeShellArg( $this->cleanPathSlashes( $dest ) )
) );
*/
abstract public function getLocalCopyMulti( array $params );
+ /**
+ * Return an HTTP URL to a given file that requires no authentication to use.
+ * The URL may be pre-authenticated (via some token in the URL) and temporary.
+ * This will return null if the backend cannot make an HTTP URL for the file.
+ *
+ * This is useful for key/value stores when using scripts that seek around
+ * large files and those scripts (and the backend) support HTTP Range headers.
+ * Otherwise, one would need to use getLocalReference(), which involves loading
+ * the entire file on to local disk.
+ *
+ * @param $params Array
+ * $params include:
+ * - src : source storage path
+ * @return string|null
+ * @since 1.21
+ */
+ abstract public function getFileHttpUrl( array $params );
+
/**
* Check if a directory exists at a given storage path.
* Backends using key/value stores will check if the path is a
return $tempFiles;
}
+ /**
+ * @see FileBackend::getFileHttpUrl()
+ * @return string|null
+ */
+ public function getFileHttpUrl( array $params ) {
+ $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+ return $this->backends[$this->masterIndex]->getFileHttpUrl( $realParams );
+ }
+
/**
* @see FileBackend::directoryExists()
* @param $params array
*/
abstract protected function doGetLocalCopyMulti( array $params );
+ /**
+ * @see FileBackend::getFileHttpUrl()
+ * @return string|null
+ */
+ public function getFileHttpUrl( array $params ) {
+ return null; // not supported
+ }
+
/**
* @see FileBackend::streamFile()
* @return Status
/** @var CF_Authentication */
protected $auth; // Swift authentication handler
protected $authTTL; // integer seconds
+ protected $swiftTempUrlKey; // string; shared secret value for making temp urls
protected $swiftAnonUser; // string; username to handle unauthenticated requests
protected $swiftUseCDN; // boolean; whether CloudFiles CDN is enabled
protected $swiftCDNExpiry; // integer; how long to cache things in the CDN
* - swiftUser : Swift user used by MediaWiki (account:username)
* - swiftKey : Swift authentication key for the above user
* - swiftAuthTTL : Swift authentication TTL (seconds)
+ * - swiftTempUrlKey : Swift "X-Account-Meta-Temp-URL-Key" value on the account.
+ * Do not set this until it has been set in the backend.
* - swiftAnonUser : Swift user used for end-user requests (account:username).
* If set, then views of public containers are assumed to go
* through this user. If not set, then public containers are
$this->swiftAnonUser = isset( $config['swiftAnonUser'] )
? $config['swiftAnonUser']
: '';
+ $this->swiftTempUrlKey = isset( $config['swiftTempUrlKey'] )
+ ? $config['swiftTempUrlKey']
+ : '';
$this->shardViaHashLevels = isset( $config['shardViaHashLevels'] )
? $config['shardViaHashLevels']
: '';
return $tmpFiles;
}
+ /**
+ * @see FileBackendStore::getFileHttpUrl()
+ * @return string|null
+ */
+ public function getFileHttpUrl( array $params ) {
+ if ( $this->swiftTempUrlKey != '' ) { // temp urls enabled
+ list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] );
+ if ( $srcRel === null ) {
+ return null; // invalid path
+ }
+ try {
+ $sContObj = $this->getContainer( $srcCont );
+ $obj = new CF_Object( $sContObj, $srcRel, false, false ); // skip HEAD
+ return $obj->get_temp_url( $this->swiftTempUrlKey, 86400, "GET" );
+ } catch ( NoSuchContainerException $e ) {
+ } catch ( CloudFilesException $e ) { // some other exception?
+ $this->handleException( $e, null, __METHOD__, $params );
+ }
+ }
+ return null;
+ }
+
/**
* @see FileBackendStore::directoriesAreVirtual()
* @return bool
try {
$dbw->insert( 'filejournal', $data, __METHOD__ );
+ if ( mt_rand( 0, 99 ) == 0 ) {
+ $this->purgeOldLogs(); // occasionally delete old logs
+ }
} catch ( DBError $e ) {
$status->fatal( 'filejournal-fail-dbquery', $this->backend );
return $status;
if ( !isset( $this->zones[$zone]['directory'] ) ) {
$this->zones[$zone]['directory'] = '';
}
+ if ( !isset( $this->zones[$zone]['urlsByExt'] ) ) {
+ $this->zones[$zone]['urlsByExt'] = array();
+ }
}
}
/**
* Get the URL corresponding to one of the four basic zones
*
- * @param $zone String: one of: public, deleted, temp, thumb
+ * @param $zone String One of: public, deleted, temp, thumb
+ * @param $ext String|null Optional file extension
* @return String or false
*/
- public function getZoneUrl( $zone ) {
- if ( isset( $this->zones[$zone]['url'] )
- && in_array( $zone, array( 'public', 'temp', 'thumb' ) ) )
- {
- return $this->zones[$zone]['url']; // custom URL
+ public function getZoneUrl( $zone, $ext = null ) {
+ if ( in_array( $zone, array( 'public', 'temp', 'thumb' ) ) ) { // standard public zones
+ if ( $ext !== null && isset( $this->zones[$zone]['urlsByExt'][$ext] ) ) {
+ return $this->zones[$zone]['urlsByExt'][$ext]; // custom URL for extension/zone
+ } elseif ( isset( $this->zones[$zone]['url'] ) ) {
+ return $this->zones[$zone]['url']; // custom URL for zone
+ }
}
switch ( $zone ) {
case 'public':
}
if( !$this->title || $this->title->getNamespace() == NS_FILE ) {
+ $this->dataLoaded = true; // set it here, to have also true on miss
$dbr = wfGetDB( DB_SLAVE );
- $res = $dbr->select( 'filearchive',
+ $row = $dbr->selectRow( 'filearchive',
array(
'fa_id',
'fa_name',
'fa_sha1' ),
$conds,
__METHOD__,
- array( 'ORDER BY' => 'fa_timestamp DESC' ) );
- if ( $res == false || $dbr->numRows( $res ) == 0 ) {
- // this revision does not exist?
+ array( 'ORDER BY' => 'fa_timestamp DESC')
+ );
+ if ( !$row ) {
+ // this revision does not exist?
return null;
}
- $ret = $dbr->resultObject( $res );
- $row = $ret->fetchObject();
// initialize fields for filestore image object
$this->loadFromRow( $row );
} else {
throw new MWException( 'This title does not correspond to an image page.' );
}
- $this->dataLoaded = true;
$this->exists = true;
return true;
public function getUrl() {
if ( !isset( $this->url ) ) {
$this->assertRepoDefined();
- $this->url = $this->repo->getZoneUrl( 'public' ) . '/' . $this->getUrlRel();
+ $ext = $this->getExtension();
+ $this->url = $this->repo->getZoneUrl( 'public', $ext ) . '/' . $this->getUrlRel();
}
return $this->url;
}
*/
function getArchiveUrl( $suffix = false ) {
$this->assertRepoDefined();
- $path = $this->repo->getZoneUrl( 'public' ) . '/archive/' . $this->getHashPath();
+ $ext = $this->getExtension();
+ $path = $this->repo->getZoneUrl( 'public', $ext ) . '/archive/' . $this->getHashPath();
if ( $suffix === false ) {
$path = substr( $path, 0, -1 );
} else {
*/
function getArchiveThumbUrl( $archiveName, $suffix = false ) {
$this->assertRepoDefined();
- $path = $this->repo->getZoneUrl( 'thumb' ) . '/archive/' .
+ $ext = $this->getExtension();
+ $path = $this->repo->getZoneUrl( 'thumb', $ext ) . '/archive/' .
$this->getHashPath() . rawurlencode( $archiveName ) . "/";
if ( $suffix === false ) {
$path = substr( $path, 0, -1 );
*/
function getThumbUrl( $suffix = false ) {
$this->assertRepoDefined();
- $path = $this->repo->getZoneUrl( 'thumb' ) . '/' . $this->getUrlRel();
+ $ext = $this->getExtension();
+ $path = $this->repo->getZoneUrl( 'thumb', $ext ) . '/' . $this->getUrlRel();
if ( $suffix !== false ) {
$path .= '/' . rawurlencode( $suffix );
}
* @author Beta16
* @author Darth Kule
* @author F. Cosoleto
+ * @author Gianfranco
* @author Karika
*/
$messages['it'] = array(
'config-using-server' => 'Nome server in uso "<nowiki>$1</nowiki>".',
'config-using-uri' => 'URL del server in uso "<nowiki>$1$2</nowiki>".',
'config-db-type' => 'Tipo di database:',
+ 'config-db-wiki-settings' => 'Identifica questo wiki',
'config-db-name' => 'Nome del database:',
+ 'config-db-name-oracle' => 'Schema del database:',
+ 'config-db-username' => 'Nome utente del database:',
'config-db-password-empty' => 'Inserire una password per il nuovo utente del database: $1.
Anche se può essere possibile creare utenti senza password, questo non è sicuro.',
'config-db-install-help' => "Inserire il nome utente e la password che verranno usate per la connessione al database durante il processo d'installazione.",
+ 'config-db-prefix' => 'Prefisso tabella del database:',
'config-db-charset' => 'Set di caratteri del database',
'config-charset-mysql5' => 'MySQL 4.1/5.0 UTF-8',
'config-charset-mysql4' => 'MySQL 4.0 con compatibilità UTF-8',
'config-header-oracle' => 'Impostazioni Oracle',
'config-header-ibm_db2' => 'Impostazioni IBM DB2',
'config-invalid-db-type' => 'Tipo di database non valido',
+ 'config-db-web-account' => "Account del database per l'accesso web",
'config-db-web-create' => "Crea l'account se non esiste già",
'config-mysql-engine' => 'Storage engine:',
'config-mysql-innodb' => 'InnoDB',
'config-mysql-myisam' => 'MyISAM',
'config-mysql-charset' => 'Set di caratteri del database:',
+ 'config-mysql-binary' => 'Binario',
'config-mysql-utf8' => 'UTF-8',
'config-ibm_db2-low-db-pagesize' => "Il database DB2 in uso ha una tablespace predefinita con un insufficiente pagesize, che dovrebbe essere '''32K''' o maggiore.",
'config-ns-generic' => 'Progetto',
'config-ns-site-name' => 'Stesso nome wiki: $1',
+ 'config-ns-other-default' => 'MyWiki',
'config-admin-box' => 'Account amministratore',
'config-admin-name' => 'Tuo nome:',
'config-admin-password' => 'Password:',
Inserire un indirizzo email se si desidera effettuare l'iscrizione alla mailing list.",
'config-almost-done' => 'Hai quasi finito!
Adesso puoi saltare la rimanente parte della configurazione e semplicemente installare la wiki.',
+ 'config-optional-continue' => 'Fammi altre domande.',
+ 'config-profile-wiki' => 'Wiki tradizionale',
+ 'config-profile-no-anon' => 'Creazione utenza obbligatoria',
+ 'config-profile-fishbowl' => 'Solo editori autorizzati',
+ 'config-profile-private' => 'Wiki privata',
'config-license' => 'Copyright e licenza:',
+ 'config-license-none' => 'Nessun piè di pagina per la licenza',
'config-license-cc-by-sa' => 'Creative Commons Attribuzione-Condividi allo stesso modo',
'config-license-cc-by' => 'Creative Commons Attribuzione',
'config-license-cc-by-nc-sa' => 'Creative Commons Attribuzione-Non commerciale-Condividi allo stesso modo',
'config-license-cc-0' => 'Creative Commons Zero (pubblico dominio)',
'config-license-gfdl' => 'GNU Free Documentation License 1.3 o versioni successive',
'config-license-pd' => 'Pubblico dominio',
+ 'config-license-cc-choose' => 'Seleziona una delle licenze Creative Commons',
+ 'config-license-help' => "Molti wiki pubblici rilasciano i loro contributi con una [http://freedomdefined.org/Definition licenza libera]. Questo aiuta a creare un senso di proprietà condivisa nella comunità e incoraggia a contribuire a lungo termine. Non è generalmente necessario per un wiki privato o aziendale.
+
+Se vuoi usare testi da Wikipedia, o desideri che Wikipedia possa essere in grado di accettare testi copiati dal tuo wiki, dovresti scegliere '''Creative Commons Attribution Share Alike'''.
+
+In precedenza Wikipedia ha utilizzato la GNU Free Documentation License. La GFDL è una licenza valida, ma è di difficile comprensione e complica il riutilizzo dei contenuti.",
'config-email-settings' => 'Impostazioni email',
+ 'config-email-user' => 'Abilita invio email fra utenti',
'config-email-auth' => 'Abilita autenticazione via email',
+ 'config-upload-enable' => 'Consentire il caricamento di file',
'config-upload-deleted' => 'Directory per i file cancellati:',
'config-logo' => 'URL del logo:',
+ 'config-instantcommons' => 'Abilita Instant Commons',
'config-cc-again' => 'Seleziona di nuovo...',
'config-cc-not-chosen' => 'Scegliere quale licenza Creative Commons si desidera e cliccare su "procedi".',
'config-advanced-settings' => 'Configurazione avanzata',
+ 'config-memcache-needservers' => 'È stato selezionato il tipo di caching Memcached, ma non è stato impostato alcun server.',
'config-memcache-badip' => 'È stato inserito un indirizzo IP non valido per Memcached: $1.',
'config-extensions' => 'Estensioni',
+ 'config-install-step-done' => 'fatto',
+ 'config-install-step-failed' => 'non riuscito',
+ 'config-install-schema' => 'Creazione dello schema',
+ 'config-install-user' => 'Creazione di utente del database',
'config-install-user-alreadyexists' => 'L\'utente "$1" è già presente',
'config-install-user-create-failed' => 'Creazione dell\'utente "$1" non riuscita: $2',
'config-install-user-missing' => 'L\'utente indicato "$1" non esiste.',
'config-install-tables-failed' => "'''Errore''': La creazione della tabella non è riuscita: $1",
+ 'config-install-interwiki' => 'Riempimento della tabella interwiki predefinita',
'config-install-interwiki-list' => 'Impossibile leggere il file <code>interwiki.list</code>.',
'config-install-stats' => 'Inizializzazione delle statistiche',
'config-install-keys' => 'Generazione delle chiavi segrete',
'config-page-copying' => '전문',
'config-page-upgradedoc' => '업그레이드하기',
'config-page-existingwiki' => '기존 위키',
- 'config-help-restart' => '당신이 입력한 모든 저장된 데이터를 지우고 설치 과정을 다시 시작하겠습니까?',
+ 'config-help-restart' => '입력한 모든 저장된 데이터를 지우고 설치 과정을 다시 시작하겠습니까?',
'config-restart' => '예, 다시 시작합니다',
'config-welcome' => '=== 사용 환경 검사 ===
이 환경이 미디어위키 설치에 적합한지 기본 검사를 실행합니다.
'config-db-host' => '데이터베이스 호스트:',
'config-db-host-help' => '데이터베이스 서버가 다른 서버에 있을 경우 여기에 호스트 이름이나 IP 주소를 입력하세요.
-웹 호스팅을 공유하여 사용하는 경우 호스팅 공급자는 당신에게 이들 설명서의 올바른 호스트 이름을 표기해야 합니다.
+공유된 웹 호스팅을 사용하는 경우 호스팅 공급자는 올바른 호스트 이름을 설명해야 합니다.
윈도 서버에 설치하고 MySQL을 사용할 경우 "localhost"는 서버 이름으로 작동하지 않을 수 있습니다. 그렇지 않으면 로컬 IP 주소로 "127.0.0.1"를 시도하세요.
'config-db-name-help' => '위키를 식별하기 위한 이름을 선택하세요.
공백이 없어야 합니다.
-웹 호스팅을 공유해 사용하는 경우 호스팅 제공 업체도 당신에게 제어판을 통해 데이터베이스를 사용하거나 만들 수 있도록 특정 데이터베이스 이름을 제공합니다.',
+공유된 웹 호스팅 사용하는 경우 호스팅 제공 업체가 특정 데이터베이스 이름을 제공하거나 제어판에서 데이터베이스를 만들 수 있도록 합니다.',
'config-db-name-oracle' => '데이터베이스 스키마:',
'config-db-account-oracle-warn' => '데이터베이스 백엔드로 오라클을 설치하기 위해 지원하는 세 가지 시나리오가 있습니다:
$1
-데이터베이스 시스템이 표시되지 않을 때 아래에 나열된 다음 지원을 활성화하려면 당신은 위의 링크된 지시에 따라 사용해볼 수도 있습니다.',
+데이터베이스 시스템이 표시되지 않을 때 아래에 나열된 다음 지원을 활성화하려면 위의 링크된 지시에 따라 설치해볼 수 있습니다.',
'config-support-mysql' => '* $1은 미디어위키의 기본 대상으로 가장 잘 지원합니다. ([http://www.php.net/manual/en/mysql.installation.php MySQL을 지원하여 PHP를 컴파일하는 방법])',
'config-support-postgres' => '* $1은 MySQL의 대안으로 인기있는 오픈 소스 데이터베이스 시스템입니다. ([http://www.php.net/manual/en/pgsql.installation.php PostgreSQL을 지원하여 PHP를 컴파일하는 방법]) 몇가지 사소한 해결하지 못한 버그가 있을 수 있으며, 이를 제작 환경에서 사용하지 않는 것이 좋습니다.',
'config-support-sqlite' => '* $1는 매우 잘 지원하는 가벼운 데이터베이스 시스템입니다. ([http://www.php.net/manual/en/pdo.installation.php SQLite를 지원하여 PHP를 컴파일하는 방법], PDO 사용)',
MySQL의 UTF-8 모드를 보다 더 효율적이고 유니코드 문자의 전체 범위를 사용할 수 있습니다.
'''UTF-8 모드'''에서는 MySQL은 데이터를 설정하는 어떤 문자열인지를 알 것이며, 표현하고 적절하게 그것을 변환할 수 있지만
[//en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes 기본 다국어 범위] 상의 문자를 저장하지 못하게 될 수 있습니다.",
- 'config-ibm_db2-low-db-pagesize' => "당신의 DB2 데이터베이스에 부족한 페이지 크기가 기본 테이블 공간에 있습니다. 페이지 크기는 '''32K''' 이상이어야 합니다.",
+ 'config-ibm_db2-low-db-pagesize' => "DB2 데이터베이스에 부족한 페이지 크기가 기본 테이블 공간에 있습니다. 페이지 크기는 '''32K''' 이상이어야 합니다.",
'config-site-name' => '위키 이름:',
'config-site-name-help' => '브라우저 제목 표시줄과 다른 여러 곳에 나타납니다.',
'config-site-name-blank' => '사이트 이름을 입력하세요.',
'config-admin-error-bademail' => '이메일 주소를 잘못 입력하였습니다.',
'config-subscribe' => '[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce 배포 발표 메일링 리스트]에 가입합니다.',
'config-subscribe-help' => '중요한 보안 알림을 포함한 배포 알림에 대해 사용되는 로우 볼륨 메일링 리스트입니다.
-ë\8b¹ì\8b ì\9d´ ì\9d´ë¥¼ 구ë\8f\85í\95\98ê³ ë\82\98ì\84\9c ì\83\88 ë²\84ì \84ì\9d´ ë\82\98ì\98¬ ë\95\8c 미ë\94\94ì\96´ì\9c\84í\82¤ ì\84¤ì¹\98를 ì\97\85ë\8d°ì\9d´í\8a¸í\95´ì\95¼í\95©ë\8b\88ë\8b¤.',
+ì\9d´ 리ì\8a¤í\8a¸ë¥¼ 구ë\8f\85í\95\98ê³ ë\82\98ì\84\9c ì\83\88 ë²\84ì \84ì\9d´ ë\82\98ì\98¬ ë\95\8c 미ë\94\94ì\96´ì\9c\84í\82¤ ì\84¤ì¹\98를 ì\97\85ë\8d°ì\9d´í\8a¸í\95\98ì\8bì\8b\9cì\98¤.',
'config-subscribe-noemail' => '이메일 주소를 제공하지 않고 배포 발표 메일링 리스트에 가입하려 합니다.
메일링 리스트에 가입하고자 할 경우 이메일 주소를 제공하세요.',
'config-almost-done' => '거의 다 완료했습니다!
'config-profile-no-anon' => '계정 만들기 필요',
'config-profile-fishbowl' => '승인된 편집자만 이용 가능',
'config-profile-private' => '비공개 위키',
- 'config-profile-help' => "ì\9c\84í\82¤ë\8a\94 ë\8b¹ì\8b ì\9d´ ê°\80ë\8a¥í\95\9c í\95\9c ë§\8eì\9d\80 ì\82¬ë\9e\8cë\93¤ì\9d´ í\8e¸ì§\91í\95\98ë\8f\84ë¡\9d í\95 ë\95\8c ìµ\9cê³ ë¡\9c ì \81í\95©합니다.
-미ë\94\94ì\96´ì\9c\84í\82¤ì\97\90ì\84\9cë\8a\94 ìµ\9cê·¼ ë°\94ë\80\9cì\9d\84 ê²\80í\86 í\95\98ê³ , ì\84 í\95\98ê±°ë\82\98 ì\95\85ì\9d\98ì \81ì\9d¸ ì\82¬ì\9a©ì\9e\90ì\97\90 ì\9d\98í\95´ ì\88\98í\96\89ë\90\98ë\8a\94 모든 손실을 되돌리는 것이 쉽습니다.
+ 'config-profile-help' => "ì\9c\84í\82¤ë\8a\94 ë§\8eì\9d\80 ì\82¬ë\9e\8cë\93¤ì\9d´ ê°\80ë\8a¥í\95\9c í\95\9c í\95´ë\8b¹ ì\9c\84í\82¤ë¥¼ í\8e¸ì§\91í\95 ë\95\8c ê°\80ì\9e¥ ë\9b°ì\96´ë\82\9c ì\97í\95 ì\9d\84 합니다.
+미ë\94\94ì\96´ì\9c\84í\82¤ì\97\90ì\84\9cë\8a\94 ìµ\9cê·¼ ë°\94ë\80\9cì\9d\84 ê²\80í\86 í\95\98ê³ , ì\84 í\95\98ê±°ë\82\98 ì\95\85ì\9d\98ì \81ì\9d¸ ì\82¬ì\9a©ì\9e\90ì\9d\98 모든 손실을 되돌리는 것이 쉽습니다.
-그러나 많은 사람들이 미디어위키가 다양한 역할의 유용하지만, 때로는 그것이 위키 방식의 장점을 모두 설득하기 쉽지 않음을 발견했습니다.
+그러나 많은 사람들이 미디어위키가 다양한 역할로 유용하지만, 때로는 모든 사람에게 위키 방식의 장점을 모두 설득하기 쉽지 않을 지도 모릅니다.
그래서 선택할 수 있습니다.
'''{{int:config-profile-wiki}}'''는 로그인하지 않고도 누구나 편집할 수 있습니다.
-'''{{int:config-profile-no-anon}}'''는 ì¶\94ê°\80ì \81ì\9c¼ë¡\9c í\95\84ì\9a\94í\95\9c ì±\85ì\9e\84ì\9d\84 ì \9cê³µí\95\98ì§\80ë§\8c, 기존ì\9d\98 기ì\97¬ì\9e\90를 ë§\9dì¹ ì\88\98ë\8f\84 ì\9e\88ì\8aµë\8b\88ë\8b¤.
+'''{{int:config-profile-no-anon}}'''는 ê°\81 í\8e¸ì§\91ì\97\90 ì¶\94ê°\80ì \81ì\9c¼ë¡\9c ê°\95í\95\9c ì±\85ì\9e\84ì\84±ì\9d\84 ì \9cê³µí\95\98ì§\80ë§\8c, ë¶\80ë\8b´ ì\97\86ë\8a\94 기ì\97¬ë¥¼ ì \80í\95´í\95 ì\88\98ë\8f\84 ì\9e\88ì\8aµë\8b\88ë\8b¤.
-'''{{int:config-profile-fishbowl}}''' 같은 경우는 승인된 사용자만 편집할 수 있지만, 대중은 역사를 포함하여 페이지를 볼 수 있습니다. '''{{int:config-profile-private}}'''는 승인된 사용자만 같은 그룹에서 편집할 수 있고 볼 수 있습니다.
+'''{{int:config-profile-fishbowl}}''' 같은 경우는 승인된 사용자만 편집할 수 있지만, 대중은 역사를 포함하여 페이지를 볼 수 있습니다.
+'''{{int:config-profile-private}}'''는 승인된 사용자만 같은 그룹에서 편집할 수 있고 볼 수 있습니다.
더 복잡한 사용자 권한을 설정하여 설치한 후 사용할 수 있도록 하려면 [//www.mediawiki.org/wiki/Manual:User_rights 관련 매뉴얼 항목]을 참고하세요.",
'config-license' => '저작권 및 라이선스:',
'config-extensions-help' => '위에 나열된 확장 기능이 <code>./extensions</code>에서 발견되었습니다.
추가적인 설정이 필요할 수 있습니다만 지금 활성화시킬 수 있습니다.',
- 'config-install-alreadydone' => "'''경고:''' 당신은 이미 미디어위키를 설치하였고 다시 설치하려고 합니다.
+ 'config-install-alreadydone' => "'''경고:''' 이미 미디어위키를 설치했고 다시 설치하려고 합니다.
다음 페이지에서 진행하세요.",
'config-install-begin' => '"{{int:config-continue}}"을 누르면 미디어위키의 설치를 시작합니다.
그래도 바꾸는 것을 원한다면 뒤로를 누릅니다.',
$dir = self::realpath( $dir );
$this->setVar( 'wgSQLiteDataDir', $dir );
}
+ # Table prefix is not used on SQLite, keep it empty
+ $this->setVar( 'wgDBprefix', '' );
return $result;
}
* Class to handle enqueueing and running of background jobs
*
* @ingroup JobQueue
- * @since 1.20
+ * @since 1.21
*/
abstract class JobQueue {
protected $wiki; // string; wiki ID
}
/**
- * @return bool Quickly check if the queue is empty
+ * Quickly check if the queue is empty.
+ * Queue classes should use caching if they are any slower without memcached.
+ *
+ * @return bool
*/
final public function isEmpty() {
wfProfileIn( __METHOD__ );
* Class to handle job queues stored in the DB
*
* @ingroup JobQueue
- * @since 1.20
+ * @since 1.21
*/
class JobQueueDB extends JobQueue {
- const CACHE_TTL = 30; // integer; seconds
+ const CACHE_TTL = 300; // integer; seconds
const MAX_JOB_RANDOM = 2147483647; // 2^31 - 1; used for job_random
/**
$dbw->setFlag( $autoTrx ? DBO_TRX : 0 ); // restore automatic begin()
}
- $wgMemc->set( $key, 'false', $ttl );
+ $wgMemc->set( $key, 'false', $ttl ); // queue is not empty
} );
}
* Class to handle enqueueing of background jobs
*
* @ingroup JobQueue
- * @since 1.20
+ * @since 1.21
*/
class JobQueueGroup {
/** @var Array */
return array_diff( $this->getQueueTypes(), $wgJobTypesExcludedFromDefaultQueue );
}
+
+ /**
+ * @return Array List of job types that have non-empty queues
+ */
+ public function getQueuesWithJobs() {
+ $types = array();
+ foreach ( $this->getQueueTypes() as $type ) {
+ if ( !$this->get( $type )->isEmpty() ) {
+ $types[] = $type;
+ }
+ }
+ return $types;
+ }
}
return true;
}
$content = $targetRev->getContent();
- $currentDest = $content->getRedirectTarget();
+ $currentDest = $content ? $content->getRedirectTarget() : null;
if ( !$currentDest || !$currentDest->equals( $this->redirTitle ) ) {
wfDebug( __METHOD__.": Redirect has changed since the job was queued\n" );
return true;
}
public static function runForTitleInternal( Title $title, Revision $revision, $fname ) {
- global $wgContLang;
+ wfProfileIn( $fname );
+ $content = $revision->getContent( Revision::RAW );
- wfProfileIn( $fname . '-parse' );
- $options = ParserOptions::newFromUserAndLang( new User, $wgContLang );
- $content = $revision->getContent();
- $parserOutput = $content->getParserOutput( $title, $revision->getId(), $options, false );
- wfProfileOut( $fname . '-parse' );
+ if ( !$content ) {
+ // if there is no content, pretend the content is empty
+ $content = $revision->getContentHandler()->makeEmptyContent();
+ }
- wfProfileIn( $fname . '-update' );
- $updates = $content->getSecondaryDataUpdates( $title, null, false, $parserOutput );
+ $updates = $content->getSecondaryDataUpdates( $title, null, false );
DataUpdate::runUpdates( $updates );
- wfProfileOut( $fname . '-update' );
+ wfProfileOut( $fname );
}
}
* @return Mixed
*/
public function get( $key ) {
+ wfProfileIn( __METHOD__ );
$this->debugLog( "get($key)" );
- return $this->checkResult( $key, parent::get( $key ) );
+ $value = $this->checkResult( $key, parent::get( $key ) );
+ wfProfileOut( __METHOD__ );
+ return $value;
}
/**
* @return Array
*/
public function getMulti( array $keys ) {
+ wfProfileIn( __METHOD__ );
$this->debugLog( 'getMulti(' . implode( ', ', $keys ) . ')' );
$callback = array( $this, 'encodeKey' );
$result = $this->client->getMulti( array_map( $callback, $keys ) );
+ wfProfileOut( __METHOD__ );
return $this->checkResult( false, $result );
}
if ( $rev ) {
$content = $rev->getContent();
- $text = $content->getWikitextForTransclusion();
+ $text = $content ? $content->getWikitextForTransclusion() : null;
if ( $text === false || $text === null ) {
$text = false;
}
$content = $revision->getContent( Revision::RAW );
+
+ if ( !$content ) {
+ wfDebug( __METHOD__ . "failed to load content of JS/CSS page!\n" );
+ return null;
+ }
+
$model = $content->getModel();
if ( $model !== CONTENT_MODEL_CSS && $model !== CONTENT_MODEL_JAVASCRIPT ) {
- wfDebug( __METHOD__ . "bad content model #$model for JS/CSS page!\n" );
+ wfDebug( __METHOD__ . "bad content model $model for JS/CSS page!\n" );
return null;
}
//TODO: if we could plug in some code that knows about special content models *and* about
// special features of the search engine, the search could benefit.
$content = $this->mRevision->getContent();
- $this->mText = $content->getTextForSearchIndex();
+ $this->mText = $content ? $content->getTextForSearchIndex() : '';
} else { // TODO: can we fetch raw wikitext for commons images?
$this->mText = '';
}
$protocol = parse_url( $path, PHP_URL_SCHEME );
- if ( $protocol === false ) { // malformed URL
+ // Malformed URL
+ if ( $protocol === false ) {
throw new MWException( "failed to parse URL $path" );
}
- if ( $protocol === null ) { // no schema
- $protocol = ''; // used for protocol relative URLs
+ // No schema
+ if ( $protocol === null ) {
+ // Used for protocol relative URLs
+ $protocol = '';
}
return $protocol;
'forward' => false,
'config' => array(),
+ 'language' => 'en', // XXX: can we default to '' instead?
);
}
* @ingroup SpecialPage
*/
class SpecialChangePassword extends UnlistedSpecialPage {
+
+ protected $mUserName, $mOldpass, $mNewpass, $mRetype, $mDomain;
+
public function __construct() {
parent::__construct( 'ChangePassword' );
}
$this->getOutput()->redirect( $titleObj->getFullURL() );
}
+ /**
+ * @param $msg string
+ */
function error( $msg ) {
$this->getOutput()->addHTML( Xml::element('p', array( 'class' => 'error' ), $msg ) );
}
);
}
+ /**
+ * @param $fields array
+ * @return string
+ */
function pretty( $fields ) {
$out = '';
foreach ( $fields as $list ) {
try {
$user->setPassword( $this->mNewpass );
wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'success' ) );
- $this->mNewpass = $this->mOldpass = $this->mRetypePass = '';
+ $this->mNewpass = $this->mOldpass = $this->mRetype = '';
} catch( PasswordError $e ) {
wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'error' ) );
throw new PasswordError( $e->getMessage() );
$userName = $row->user_name;
$ulinks = Linker::userLink( $row->user_id, $userName );
- $ulinks .= Linker::userToolLinks( $row->user_id, $userName );
+ $ulinks .= Linker::userToolLinksRedContribs( $row->user_id, $userName, intval( $row->edits ) );
$lang = $this->getLanguage();
DoubleRedirectJob::fixRedirects( 'move', $ot, $nt );
}
- wfRunHooks( 'SpecialMovepageAfterMove', array( &$this, &$ot, &$nt ) );
-
$out = $this->getOutput();
$out->setPageTitle( $this->msg( 'pagemovedsub' ) );
$newLink )->params( $oldText, $newText )->parseAsBlock() );
$out->addWikiMsg( $msgName );
+ wfRunHooks( 'SpecialMovepageAfterMove', array( &$this, &$ot, &$nt ) );
+
# Now we move extra pages we've been asked to move: subpages and talk
# pages. First, if the old page or the new page is a talk page, we
# can't move any talk pages: cancel that.
$invert = $opts['invert'];
$associated = $opts['associated'];
- $fields = array( $dbr->tableName( 'recentchanges' ) . '.*' ); // all rc columns
+ $fields = RecentChange::selectFields();
// JOIN on watchlist for users
if ( $uid ) {
$tables[] = 'watchlist';
$dbkey = $title->getDBkey();
$tables = array( 'recentchanges' );
- $select = array( $dbr->tableName( 'recentchanges' ) . '.*' );
+ $select = RecentChange::selectFields();
$join_conds = array();
$query_options = array();
}
}
- wfProfileOut( __METHOD__ );
- return "<li><div class='mw-search-result-heading'>{$link} {$redirect} {$section}</div> {$extract}\n" .
- "<div class='mw-search-result-data'>{$score}{$size} - {$date}{$related}</div>" .
- "</li>\n";
+ $html = null;
+
+ if ( wfRunHooks( 'ShowSearchHit', array (
+ $this, $result, $terms,
+ &$link, &$redirect, &$section, &$extract,
+ &$score, &$size, &$date, &$related,
+ &$html
+ ) ) ) {
+ $html = "<li><div class='mw-search-result-heading'>{$link} {$redirect} {$section}</div> {$extract}\n" .
+ "<div class='mw-search-result-data'>{$score}{$size} - {$date}{$related}</div>" .
+ "</li>\n";
+ }
+ wfProfileOut( __METHOD__ );
+ return $html;
}
/**
if( !isset( $groups[$group] ) ) {
$groups[$group] = array();
}
- $groups[$group][$page->getDescription()] = array( $page->getTitle(), $page->isRestricted(), $page->isExpensive() );
+ $groups[$group][$page->getDescription()] = array(
+ $page->getTitle(),
+ $page->isRestricted(),
+ $page->isCached()
+ );
}
}
}
private function outputPageList( $groups ) {
- global $wgMiserMode;
$out = $this->getOutput();
$includesRestrictedPages = false;
$includesCachedPages = false;
foreach ( $groups as $group => $sortedPages ) {
- $middle = ceil( count( $sortedPages )/2 );
$total = count( $sortedPages );
+ $middle = ceil( $total / 2 );
$count = 0;
$out->wrapWikiMsg( "<h2 class=\"mw-specialpagesgroup\" id=\"mw-specialpagesgroup-$group\">$1</h2>\n", "specialpages-group-$group" );
Html::openElement( 'ul' ) . "\n"
);
foreach( $sortedPages as $desc => $specialpage ) {
- list( $title, $restricted, $expensive) = $specialpage;
+ list( $title, $restricted, $cached ) = $specialpage;
$pageClasses = array();
- if ( $expensive && $wgMiserMode ){
+ if ( $cached ) {
$includesCachedPages = true;
$pageClasses[] = 'mw-specialpagecached';
}
$form .= '<hr />';
$tables = array( 'recentchanges', 'watchlist' );
- $fields = array( $dbr->tableName( 'recentchanges' ) . '.*' );
+ $fields = RecentChange::selectFields();
$join_conds = array(
'watchlist' => array(
'INNER JOIN',
switch ( $case ) {
case 'prefixed':
case 'תחילית':
- # Duplicate the "Waw" if prefixed
- if ( substr( $word, 0, 2 ) == "ו" && substr( $word, 0, 4 ) != "וו" ) {
+ # Duplicate the "Waw" if prefixed, but not if it is already double.
+ if ( substr( $word, 0, 2 ) === "ו" && substr( $word, 0, 4 ) !== "וו" ) {
$word = "ו" . $word;
}
- # Remove the "He" if prefixed
- if ( substr( $word, 0, 2 ) == "ה" ) {
+ # Remove the "He" article if prefixed.
+ if ( substr( $word, 0, 2 ) === "ה" ) {
$word = substr( $word, 2 );
}
- # Add a hyphen (maqaf) if non-Hebrew letters
+ # Add a hyphen (maqaf) before non-Hebrew letters.
if ( substr( $word, 0, 2 ) < "א" || substr( $word, 0, 2 ) > "ת" ) {
$word = "־" . $word;
}
return $word;
}
-
}
'underline-always' => 'Siempre',
'underline-never' => 'Nunca',
-'underline-default' => 'Restolador por defeutu',
+'underline-default' => 'Predeterminao del aspeutu o del restolador',
# Font style option in Special:Preferences
'editfont-style' => "Estilu de fonte de l'área d'edición:",
'newwindow' => '(ábrese nuna ventana nueva)',
'cancel' => 'Encaboxar',
'moredotdotdot' => 'Más...',
-'mypage' => 'La mio páxina',
-'mytalk' => 'El mio alderique',
+'mypage' => 'Páxina',
+'mytalk' => 'Alderique',
'anontalk' => 'Alderique pa esta IP',
'navigation' => 'Navegación',
'and' => ' y',
'note' => "'''Nota:'''",
'previewnote' => "'''Alcuerdate de qu'esto ye sólo una vista previa.'''
¡Los cambios entá nun se guardaron!",
-'continue-editing' => 'Siguir editando',
+'continue-editing' => "Dir al área d'edición",
'previewconflict' => "Esta vista previa amuesa'l testu del área d'edición d'arriba tal como apaecerá si escueyes guardar.",
'session_fail_preview' => "'''¡Sentímoslo muncho! Nun se pudo procesar la to edición porque hebo una perda de datos de la sesión.
Inténtalo otra vuelta. Si nun se t'arregla, intenta salir y volver a rexistrate.'''",
# Preferences page
'preferences' => 'Preferencies',
-'mypreferences' => 'Les mios preferencies',
+'mypreferences' => 'Preferencies',
'prefs-edits' => "Númberu d'ediciones:",
'prefsnologin' => 'Non identificáu',
'prefsnologintext' => 'Necesites tar <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} identificáu]</span> pa camudar les preferencies d\'usuariu.',
'rightslogtext' => "Esti ye un rexistru de los cambeos de los perfiles d'usuariu.",
'rightslogentry' => 'camudó la pertenencia de grupu del usuariu $1 dende $2 a $3',
'rightslogentry-autopromote' => 'promocionó automáticamente de $2 a $3',
+'logentry-rights-rights' => '$1 camudó la pertenencia a grupos de $3 dende $4 a $5',
+'logentry-rights-rights-legacy' => '$1 camudó la pertenencia a grupos de $3',
+'logentry-rights-autopromote' => '$1 promocionó automáticamente de $4 a $5',
'rightsnone' => '(nengún)',
# Associated actions - in the sentence "You do not have permission to X"
'linksearch-ok' => 'Guetar',
'linksearch-text' => 'Se puen usar comodinos como "*.wikipedia.org".
Necesita polo menos un dominiu de primer nivel, como "*.org".<br />
-Protocolos almitíos: <code>$1</code> (nun amiestes dengún d\'estos na to gueta).',
+Protocolos almitíos: <code>$1</code> (el predetermináu ye http:// si nun se conseña dengún protocolu).',
'linksearch-line' => '$1 enllaciáu dende $2',
'linksearch-error' => 'Los comodinos namái puen apaecer al entamu del nome del güéspede.',
'emailuser-title-target' => 'Unviar un corréu electrónicu a {{GENDER:$1|esti usuariu|esta usuaria}}',
'emailuser-title-notarget' => 'Unviar un corréu electrónicu a un usuariu',
'emailpage' => 'Envigar un corréu electrónicu a un usuariu',
-'emailpagetext' => "Pues usar el formulariu d'embaxo pa unviar un corréu electrónicu a esti usuariu.
-La direición de corréu electrónicu qu'especificasti nes [[Special:Preferences|tos preferencies d'usuariu]] va apaecer como la direición \"Dende\" del corréu, pa que'l que lo recibe seya quien a respondete direutamente a ti.",
+'emailpagetext' => 'Pues usar el formulariu de más abaxo pa unviar un corréu electrónicu a {{GENDER:$1|esti usuariu|esta usuaria}}.
+La direición de corréu electrónicu qu\'especificasti nes [[Special:Preferences|tos preferencies d\'usuariu]] va apaecer como la direición "Dende" del corréu, pa que\'l que lo recibe seya quien a respondete direutamente a ti.',
'usermailererror' => "L'operador de corréu devolvió un error:",
'defemailsubject' => 'Corréu electrónicu del usuariu «$1» de {{SITENAME}}',
'usermaildisabled' => 'Corréu del usuariu desactiváu',
# Watchlist
'watchlist' => 'La mio páxina de vixilancia',
-'mywatchlist' => 'La mio llista de vixilancia',
+'mywatchlist' => 'Llista de vixilancia',
'watchlistfor2' => 'Pa $1 $2',
'nowatchlist' => 'La to llista de vixilancia ta vacia.',
'watchlistanontext' => 'Por favor $1 pa ver o editar entraes na to llista de vixilancia.',
# Contributions
'contributions' => 'Collaboraciones del usuariu',
'contributions-title' => "Contribuciones d'usuariu pa $1",
-'mycontris' => 'Les mios collaboraciones',
+'mycontris' => 'Collaboraciones',
'contribsub2' => 'De $1 ($2)',
'nocontribs' => "Nun s'atoparon cambeos que coincidan con esi criteriu.",
'uctop' => '(actual)',
'whatlinkshere-hideredirs' => '$1 redireiciones',
'whatlinkshere-hidetrans' => '$1 tresclusiones',
'whatlinkshere-hidelinks' => '$1 enllaces',
-'whatlinkshere-hideimages' => "$1 enllaces d'imaxe",
+'whatlinkshere-hideimages' => '$1 los enllaces al ficheru',
'whatlinkshere-filters' => 'Peñeres',
# Block/unblock
# Info page
'pageinfo-title' => 'Información sobro "$1"',
-'pageinfo-not-current' => 'Namái se pue amosar la información pa la revisión actual.',
+'pageinfo-not-current' => 'Sentimoslo, ye imposible dar esta información de les revisiones antigües.',
'pageinfo-header-basic' => 'Información básica',
'pageinfo-header-edits' => "Historial d'ediciones",
'pageinfo-header-restrictions' => 'Proteición de páxina',
'pageinfo-default-sort' => "Clave d'ordenación predeterminada",
'pageinfo-length' => 'Llonxitú de la páxina (en bytes)',
'pageinfo-article-id' => 'ID de la páxina',
+'pageinfo-language' => 'Llingua del conteníu de la páxina',
'pageinfo-robot-policy' => 'Estáu del motor de gueta',
'pageinfo-robot-index' => 'Pue ser índiz',
'pageinfo-robot-noindex' => 'Nun pue ser índiz',
'version-license' => 'Llicencia',
'version-poweredby-credits' => "Esta wiki funciona con '''[//www.mediawiki.org/ MediaWiki]''', copyright © 2001-$1 $2.",
'version-poweredby-others' => 'otros',
+'version-credits-summary' => 'Nos prestaría dar reconocimientu a les siguientes persones pola so contribución a [[Special:Version|MediaWiki]].',
'version-license-info' => "MediaWiki ye software llibre; pues redistribuilu y/o camudalu baxo los términos de la Llicencia Pública Xeneral GNU tal como ta asoleyada pola Free Software Foundation; o la versión 2 de la Llicencia, o (como prefieras) cualesquier versión posterior.
MediaWiki se distribúi col envís de que seya afayadiza, pero ENSIN GARANTÍA DALA; ensin siquiera garantía implícita de COMERCIALIDÁ o ADAUTACIÓN A UN DETERMINÁU PROPÓSITU. Llee la Llicencia Pública Xeneral GNU pa más detalles.
*
* @author Cekli829
* @author Don Alessandro
+ * @author E THP
* @author Emperyan
* @author Erdemaslancan
* @author Gulmammad
# Preferences page
'preferences' => 'Nizamlamalar',
-'mypreferences' => 'Nizamlamalarım',
+'mypreferences' => 'Nizamlamalar',
'prefs-edits' => 'Redaktələrin sayı:',
'prefsnologin' => 'Daxil olmamısınız',
'prefsnologintext' => 'Nizamlamaları dəyişmək üçün <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} daxil olmaq]</span> zəruridir.',
'confirmemail_loggedin' => 'Һеҙҙең электрон почта адресығыҙ раҫланды.',
'confirmemail_error' => 'Электрон почта адресын раҫлаған ваҡытта хата килеп сыҡты.',
'confirmemail_subject' => '{{SITENAME}} электрон почта адресын раҫлау',
-'confirmemail_body' => 'Кемдер, бәлки һеҙҙер, $1 IP адресынан
-{{SITENAME}} проектында ошо электрон почта адресы менән "$2" иҫәп яҙмаһын теркәгән.
+'confirmemail_body' => 'Кемдер, бәлки һеҙҙер, $1 IP адресынан {{SITENAME}} проектында
+ошо электрон почта адресы менән "$2" иҫәп яҙмаһын теркәгән.
-Был иҫәп яҙмаһы ысынлап та һеҙҙеке икәнен раҫлау өсөн һәм
-{{SITENAME}} проектында элетрон почта мөмкинлектәрен тоҡандырыу өсөн, браузерығыҙҙа түбәндәге һылтанманы асығыҙ:
+Был иҫәп яҙмаһы ысынлап та һеҙҙеке икәнен раҫлау өсөн һәм {{SITENAME}} проектында электрон почта
+мөмкинлектәрен тоҡандырыу өсөн, браузерығыҙҙа түбәндәге һылтанманы асығыҙ:
$3
-Әгәр һеҙ иҫәп яҙмаһын *булдырмағанһығыҙ* икән,
-электрон почта адресын раҫлауҙы үтҡәрмәү өсөн т үбәндәге һылтанманы асығыҙ:
+Әгәр һеҙ иҫәп яҙмаһын *булдырмағанһығыҙ* икән, электрон почта
+адресын раҫлауҙы үткәрмәү өсөн түбәндәге һылтанманы асығыҙ:
$5
{{SITENAME}} проектында "$2" иҫәп яҙмаһының электрон почта адресын ошо адресҡа үҙгәрткән.
Был иҫәп яҙмаһы ысынлап та һеҙҙеке икәнен раҫлау өсөн һәм
-{{SITENAME}} проектында элетрон почта мөмкинлектәрен яңынан тоҡандырыу өсөн, браузерығыҙҙа түбәндәге һылтанманы асығыҙ:
+{{SITENAME}} проектында электрон почта мөмкинлектәрен яңынан тоҡандырыу өсөн, браузерығыҙҙа түбәндәге һылтанманы асығыҙ:
$3
Әгәр һеҙ иҫәп яҙмаһын *булдырмағанһығыҙ* икән,
-электрон почта адресын раҫлауҙы үтҡәрмәү өсөн т үбәндәге һылтанманы асығыҙ:
+электрон почта адресын раҫлауҙы үткәрмәү өсөн түбәндәге һылтанманы асығыҙ:
$5
{{SITENAME}} проектында "$2" иҫәп яҙмаһының электрон почта адресын ошо адрес итеп билдәләгән.
Был иҫәп яҙмаһы ысынлап та һеҙҙеке икәнен раҫлау өсөн һәм
-{{SITENAME}} проектында элетрон почта мөмкинлектәрен яңынан тоҡандырыу өсөн, браузерығыҙҙа түбәндәге һылтанманы асығыҙ:
+{{SITENAME}} проектында электрон почта мөмкинлектәрен яңынан тоҡандырыу өсөн, браузерығыҙҙа түбәндәге һылтанманы асығыҙ:
$3
Әгәр иҫәп яҙмаһы һеҙҙеке *түгел* икән,
-электрон почта адресын раҫлауҙы үтҡәрмәү өсөн т үбәндәге һылтанманы асығыҙ:
+электрон почта адресын раҫлауҙы үткәрмәү өсөн түбәндәге һылтанманы асығыҙ:
$5
* @file
*
* @author Als-Holder
+ * @author Bua333
* @author Malafaya
* @author Man77
* @author Merlissimo
'fri' => 'Fr',
'sat' => 'Så',
'january' => 'Jänner',
-'february' => 'Feewer',
+'february' => 'Feba',
'march' => 'März',
'april' => 'Aprü',
'may_long' => 'Mai',
'july' => 'Juli',
'august' => 'August',
'september' => 'September',
-'october' => 'Óktówer',
-'november' => 'Nóvember',
+'october' => 'Oktoba',
+'november' => 'Novemba',
'december' => 'Dezember',
'january-gen' => 'Jänner',
'february-gen' => 'Feewer',
'noindex-category' => 'Néd-indizirde Seiten',
'broken-file-category' => 'Seiten mid kaputte Daateilinks',
-'about' => 'Ywer',
+'about' => 'Iba',
'article' => 'Artike',
'newwindow' => '(werd in am neichen Fenster aufgmocht)',
'cancel' => 'Obbrecher',
'moredotdotdot' => 'Merer',
'mypage' => 'Eigerne Seiten',
-'mytalk' => 'Eigerne Diskussión',
+'mytalk' => 'Mei Dischkurs',
'anontalk' => 'Dischkrirseiten voh derer IP-Adress',
'navigation' => 'Navigazión',
'and' => ' und',
'vector-action-addsection' => 'Obschnit dazuafyng',
'vector-action-delete' => 'Leschen',
'vector-action-move' => 'Vaschiam',
-'vector-action-protect' => 'Schytzen',
+'vector-action-protect' => 'Schitzn',
'vector-action-undelete' => 'Wiederherstön',
'vector-action-unprotect' => 'freigeem',
'vector-simplesearch-preference' => 'Daweiterte Suachvurschläg aktivirn (netter Vector)',
'vector-view-edit' => 'Werkeln',
'vector-view-history' => 'Versiónsgschicht',
'vector-view-view' => 'Leesen',
-'vector-view-viewsource' => 'Quötext åzong',
+'vector-view-viewsource' => 'Quejtext ozoagn',
'actions' => 'Akziónen',
-'namespaces' => 'Nåmensraim',
+'namespaces' => 'Namasramm',
'variants' => 'Varianten',
'errorpagetitle' => 'Feeler',
'history' => 'Versiónen',
'history_short' => 'Versionen/Autorn',
'updatedmarker' => '(gänderd)',
-'printableversion' => 'Versión zum Ausdrucken',
+'printableversion' => 'Druckversion',
'permalink' => 'Permanenter Link',
'print' => 'Drucken',
'view' => 'Leesen',
'unprotectthispage' => 'Seitenschutz ändern',
'newpage' => 'Neiche Seiten',
'talkpage' => 'De Seiten bsprecher',
-'talkpagelinktext' => 'Diskussión',
+'talkpagelinktext' => 'Dischkrian',
'specialpage' => 'Speziaalseiten',
'personaltools' => 'Persénlichs Werkzeig',
'postcomment' => 'Neicher Obschnit',
'articlepage' => 'Seiteninhoid åzoang',
-'talk' => 'Diskussión',
+'talk' => 'Dischkrian',
'views' => 'Åsichten',
'toolbox' => 'Werkzeigkisten',
'userpage' => 'Benutzerseiten',
'pool-errorunknown' => 'Unbekånnter Feeler',
# All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage) and the disambiguation template definition (see disambiguations).
-'aboutsite' => 'Ywer {{SITENAME}}',
+'aboutsite' => 'Iba {{SITENAME}}',
'aboutpage' => 'Project:Ywer',
'copyright' => 'Da Inhoid is unter da $1 vafiagbor.',
'copyrightpage' => '{{ns:project}}:Urheewerrechte',
'edithelp' => 'Beorweitungshüfm',
'edithelppage' => 'Help:Beorweitungshüfm',
'helppage' => 'Help:Inhoidsvazeichnis',
-'mainpage' => 'Hauptseiten',
+'mainpage' => 'Hoamseitn',
'mainpage-description' => 'Hauptseiten',
'policy-url' => 'Project:Richtlinien',
'portal' => 'Autornportal',
'ok' => 'Passt',
'retrievedfrom' => 'Voh „$1“',
'youhavenewmessages' => 'Du host $1 ($2).',
-'newmessageslink' => 'neiche Noochrichten',
-'newmessagesdifflink' => 'neiche Noochrichten',
-'youhavenewmessagesmulti' => 'Du host neiche Noochrichten: $1',
-'editsection' => 'werkeln',
+'newmessageslink' => 'neiche Nochrichtn',
+'newmessagesdifflink' => 'Letzte Endarung',
+'youhavenewmessagesmulti' => 'Du host neiche Nochrichtn: $1',
+'editsection' => 'Werkln',
'editold' => 'werkeln',
'viewsourceold' => 'Quötext åzoang',
-'editlink' => 'werkeln',
+'editlink' => 'werkln',
'viewsourcelink' => 'an Quötext åschauh',
'editsectionhint' => 'Obschnit beorweiden: $1',
'toc' => 'Inhoidsvazeichnis',
'site-atom-feed' => 'Atom-Feed fyr $1',
'page-rss-feed' => 'RSS-Feed fyr „$1“',
'page-atom-feed' => 'Atom-Feed fyr „$1“',
-'red-link-title' => '$1 (dé Seiten gibts néd)',
+'red-link-title' => '$1 (de Seitn gibts ned)',
'sort-descending' => 'Obsteigend sortiern',
'sort-ascending' => 'Aufsteigend sortiern',
'nstab-main' => 'Seiten',
'nstab-user' => 'Benutzerseiten',
'nstab-media' => 'Meedienseiten',
-'nstab-special' => 'Speziaalseiten',
+'nstab-special' => 'Spezialseitn',
'nstab-project' => 'Projektseiten',
'nstab-image' => 'Daatei',
'nstab-mediawiki' => 'Systémnoochricht',
'wrong_wfQuery_params' => 'Foische Parameeter fyr wfQuery()<br />
Funkzión: $1<br />
Obfrog: $2',
-'viewsource' => 'an Quötext åschauh',
+'viewsource' => 'Quejtext ozoagn',
'viewsource-title' => 'Quöntext voh da Seiten $1 auhschauh',
'actionthrottled' => 'Akziónszoi limitird',
'actionthrottledtext' => 'Im Råmen voh ner Anti-Spam-Moossnåm kå dé Akzión do in am kurzen Zeidobstånd netter begrenzd ausgfyrd wern. Dé Grenzen host ywerschritten.
'userlogin' => 'Åmöden / Kontó erstön',
'userloginnocreate' => 'Åmöden',
'logout' => 'Obmöden',
-'userlogout' => 'Obmöden',
+'userlogout' => 'Auslogga',
'notloggedin' => 'Ned ågmödt',
'nologin' => "Du host koah Benutzerkóntó? '''$1'''.",
'nologinlink' => 'A neichs Benutzerkontó erstön',
'nocreate-loggedin' => "Du host koah Berechtigung, neiche Seiten z' erstön.",
'permissionserrors' => 'Berechtigungsfeeler',
'permissionserrorstext' => 'Du bist néd berechtigt, dé Akzión auszfyrn. {{PLURAL:$1|Grund|Grynd}}:',
-'permissionserrorstext-withaction' => "Du host de Berechtigung ned, dass d' $2.
-{{PLURAL:$1|Grund|Grynd}}:",
+'permissionserrorstext-withaction' => 'Du host koa Berechtigung ned, dass de $2.
+{{PLURAL:$1|Grund|Grind}}:',
'recreate-moveddeleted-warn' => "'''Ówocht: Du dastöst a Seiten dé schoh friarer gléschd worn is.'''
Bittscheh priaff genau, ób dé erneite Seitendastöung dé Richtlinien entsprichd.
# Preferences page
'preferences' => 'Eihstellungen',
-'mypreferences' => 'Eigerne Eihstellungen',
+'mypreferences' => 'Mei Preferenz',
'changepassword' => 'Posswort ändern',
'prefs-editing' => 'Beorweiten',
'prefs-edit-boxsize' => 'Gress vom Beorweitungsfenster',
'prefs-namespaces' => 'Nåmensraim',
'youremail' => 'E-Mail-Adress:',
'username' => 'Benutzernåm:',
-'yourrealname' => 'Da echte Nåm:',
+'yourrealname' => 'Biagalicha Nama:',
'yourlanguage' => 'Sprooch vo da Benutzerowerflächen',
'prefs-help-realname' => 'Opzionoi. Dodamid kå dai byrgerlicher Nåm daine Baiträg zuagordnet wern.',
'prefs-help-email' => "Dé Ågob voh ner E-Mail-Adressen is ópziónoi, daméglicht ower d' Zuasendung vohram Ersotzposswort, sófern du deih Posswort vagessen host.",
'rightslog' => 'Rechte-Logbiache',
# Associated actions - in the sentence "You do not have permission to X"
-'action-edit' => 'an derer Seiten duast werkeln',
+'action-edit' => 'beorbadd de Seitn',
'action-createpage' => "Seiten z' dastön",
'action-autopatrol' => 'eigerne Beorweitungen ois kontroilird markirn',
'recentchangeslinked-to' => 'Zoagt Änderrungen auf Seiten, dé do her valinken',
# Upload
-'upload' => 'Aufféloon',
+'upload' => 'Affelodn',
'uploadbtn' => 'Daatei aufféloon',
'uploadnologin' => 'Néd ågmödt',
'uploadnologintext' => 'Du muasst [[Special:UserLogin|ågmödt]] seih, wånn Du Daatein auffeloon wüst.',
'listgrouprights-group' => 'Gruppm',
'listgrouprights-rights' => 'Rechte',
'listgrouprights-helppage' => 'Help:Gruppmrechte',
-'listgrouprights-members' => '(Mitgliaderlisten)',
+'listgrouprights-members' => '(Mitgliedalistn)',
'listgrouprights-addgroup' => 'Benutzer zua {{PLURAL:$2|derer Gruppm|dé Gruppm}} dazuadoah: $1',
'listgrouprights-removegroup' => 'Benutzer aus {{PLURAL:$2|derer Gruppm|dé Gruppm}} entferner: $1',
'listgrouprights-addgroup-all' => 'Benutzer zua olle Gruppm dazuadoah',
# Watchlist
'watchlist' => 'Beówochtungslisten',
-'mywatchlist' => 'Beówochtungslisten',
+'mywatchlist' => 'Mei Beobochta',
'watchlistfor2' => 'Voh $1 $2',
'nowatchlist' => 'Es gibt koane Eihträg auf deiner Beówochtungslisten.',
'watchlistanontext' => "Du muasst dé $1, um deih Beówchtungslisten z' seeng óder Eihträg borweiten z' kenner.",
'undelete-show-file-submit' => 'Jo',
# Namespace form on various pages
-'namespace' => 'Nåmensraum:',
+'namespace' => 'Namasramm:',
'invert' => 'Auswoi umdraan',
'namespace_association' => 'Zuagordnéter Nåmensraum',
'blanknamespace' => '(Seiten)',
# Contributions
'contributions' => 'Benutzerbeiträg',
'contributions-title' => 'Benutzerbeiträg voh „$1“',
-'mycontris' => 'Eigerne Beitrég',
+'mycontris' => 'Meine Beidräg',
'contribsub2' => 'Fyr $1 ($2)',
'uctop' => '(aktuö)',
'month' => 'und Monad',
'ipusubmit' => 'Freigem',
'unblocked' => '[[User:$1|$1]] is freigem worn',
'unblocked-id' => 'Sperr-ID $1 is fraigeem worn',
-'ipblocklist' => 'Gsperrde Benutzer',
+'ipblocklist' => 'Gsperrte Nutza',
'ipblocklist-legend' => 'Suach noch am gsperrden Benytzer',
'createaccountblock' => "'s erstön voh Benutzerkóntós is gsperrd",
'emailblock' => 'E-Póst vaschicker is gsperrd',
'blocklink' => 'sperrn',
'unblocklink' => 'Freigeem',
'change-blocklink' => 'Sperr ändern',
-'contribslink' => 'Beitrég',
+'contribslink' => 'Beidräg',
'emaillink' => 'E-Póst schicker',
'autoblocker' => 'Autómaatische Sperr, wei du a gmoahsaume IP-Adress mim [[User:$1|$1]] bnutzd. Grund voh da Benutzersperrn: „$2“.',
'blocklogpage' => 'Benutzersperrlogbiaché',
'tooltip-feed-atom' => 'Atom-Feed vo derer Saiten',
'tooltip-t-contributions' => "D' Listen voh d' Beiträg voh dém Benutzer åschauh",
'tooltip-t-emailuser' => 'Dém Benutzer a E-Post schicken',
-'tooltip-t-upload' => 'Daatein aufféloon',
+'tooltip-t-upload' => 'Datein affelodn',
'tooltip-t-specialpages' => 'Listen voh olle Speziaalseiten',
'tooltip-t-print' => 'Druckåsicht voh derer Seiten',
'tooltip-t-permalink' => 'Dauerhofter Link zua derer Seitenversión',
'fileduplicatesearch-result-1' => 'Dé Daatei „$1“ hod koane identischen Duplikaate.',
# Special:SpecialPages
-'specialpages' => 'Speziaalseiten',
+'specialpages' => 'Spezialseitn',
'specialpages-note' => '----
* Reguläre Speziaalseiten
* <span class="mw-specialpagerestricted">Zuagrifsbschränkde Speziaalseiten</span>
'cancel' => 'Kanselaron',
'moredotdotdot' => 'Kadagdagan...',
'mypage' => 'An sakóng pahina',
-'mytalk' => 'An sakóng olay',
+'mytalk' => 'Orolayan',
'anontalk' => 'Olay para kaining IP address',
'navigation' => 'Nabigasyon',
'and' => ' asin',
# Preferences page
'preferences' => 'Mga kabòtan',
-'mypreferences' => 'Mga kabòtan ko',
+'mypreferences' => 'Mga Kamuyahan ko',
'prefs-edits' => 'Bilang kan mga hirá:',
'prefsnologin' => 'Dai nakalaog',
'prefsnologintext' => 'Ika dapat na magin <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} nakalaog na]</span> tanganing tuytuyon an mga kabotan nin paragamit.',
# Watchlist
'watchlist' => 'Pigbabantayan ko',
-'mywatchlist' => 'Babantáyan ko',
+'mywatchlist' => 'Bantay-listahan',
'watchlistfor2' => 'Para ki $1 $2',
'nowatchlist' => 'Mayo ka man na mga bagay saimong lista nin pigbabantayan.',
'watchlistanontext' => 'Mag $1 tabi para mahiling o maghira nin mga bagay saimong lista nin mga pigbabantayan.',
# Contributions
'contributions' => 'Mga kontribusyon kan parágamit',
'contributions-title' => 'Mga kontribusyon kan paragamit para sa $1',
-'mycontris' => 'Mga ambág ko',
+'mycontris' => 'Mga Kaarambagan',
'contribsub2' => 'Para sa $1 ($2)',
'nocontribs' => 'Mayong mga pagbabago na nahanap na kapadis sa ining mga criteria.',
'uctop' => '(alituktok)',
'whatlinkshere-hideredirs' => '$1 mga panukdong otro',
'whatlinkshere-hidetrans' => '$1 kabaling-binalyuhan',
'whatlinkshere-hidelinks' => '$1 mga kasugpon',
-'whatlinkshere-hideimages' => '$1 mga kasugpon kan imahe',
+'whatlinkshere-hideimages' => '$1 mga kasugpon nin mga sagunson',
'whatlinkshere-filters' => 'Mga pansarà',
# Block/unblock
'newwindow' => '(адкрываецца ў новым акне)',
'cancel' => 'Скасаваць',
'moredotdotdot' => 'Далей…',
-'mypage' => 'Ð\9cаÑ\8f Ñ\81таронка',
-'mytalk' => 'Ð\9cае гутаркі',
+'mypage' => 'Старонка',
+'mytalk' => 'Ð\93утаркі',
'anontalk' => 'Гутаркі для гэтага IP-адрасу',
'navigation' => 'Навігацыя',
'and' => ' і',
'rightslogtext' => 'Гэта журнал зьменаў правоў удзельнікаў.',
'rightslogentry' => 'зьменена прыналежнасьць $1 з групы $2 да $3',
'rightslogentry-autopromote' => 'быў аўтаматычна падвышаны з $2 да $3',
+'logentry-rights-rights' => '$1 {{GENDER:$1|зьмяніў|зьмяніла}} прыналежнасьць $3 да групы з $4 на $5',
+'logentry-rights-rights-legacy' => '$1 {{GENDER:$1|зьмяніў|зьмяніла}} прыналежнасьць $3 да групаў',
+'logentry-rights-autopromote' => '$1 {{GENDER:$1|быў аўтаматычна пераведзены|была аўтаматычна пераведзеная}} з групы $4 ў $5',
'rightsnone' => '(няма)',
# Associated actions - in the sentence "You do not have permission to X"
'linksearch-ok' => 'Шукаць',
'linksearch-text' => 'Можна ўжываць сымбалі падстаноўкі, напрыклад, «*.wikipedia.org».<br />
Неабходны дамэн першага ўзроўню, напрыклад, «*.org».<br />
-Ð\9fÑ\80аÑ\82аколÑ\8b, Ñ\8fкÑ\96Ñ\8f падÑ\82Ñ\80Ñ\8bмлÑ\96ваÑ\8eÑ\86Ñ\86а: <code>$1</code> (не дадавайÑ\86е Ñ\96Ñ\85 Ñ\83 Ð\92аÑ\88 поÑ\88Ñ\83к).',
+Ð\9fÑ\80аÑ\82аколÑ\8b, Ñ\8fкÑ\96Ñ\8f падÑ\82Ñ\80Ñ\8bмлÑ\96ваÑ\8eÑ\86Ñ\86а: <code>$1</code> (дапомна http://, калÑ\96 пÑ\80аÑ\82акол не пазнаÑ\87анÑ\8b).',
'linksearch-line' => 'Спасылка на $1 з $2',
'linksearch-error' => 'Сымбалі падстаноўкі могуць ужывацца толькі ў пачатку адрасоў.',
# Contributions
'contributions' => 'Унёсак',
'contributions-title' => 'Унёсак {{GENDER:$1|удзельніка|удзельніцы}} $1',
-'mycontris' => 'Ð\9cой Ñ\83нёсак',
+'mycontris' => 'Унёсак',
'contribsub2' => 'Для $1 ($2)',
'nocontribs' => 'Ня знойдзена зьменаў, якія адпавядаюць гэтым крытэрыям.',
'uctop' => ' (апошняя)',
'duration-centuries' => '$1 {{PLURAL:$1|стагодзьдзе|стагодзьдзі|стагодзьдзяў}}',
'duration-millennia' => '$1 {{PLURAL:$1|тысячагодзьдзе|тысячагодзьдзі|тысячагодзьдзяў}}',
+# Unknown messages
+'mytalk-parenthetical' => 'гутаркі',
);
'newmessagesdifflinkplural' => '$1 {{PLURAL:$1|পরিবর্তন|পরিবর্তনসমূহ}}',
'youhavenewmessagesmulti' => 'আপনার $1টি নতুন বার্তা এসেছে',
'editsection' => 'সম্পাদনা',
-'editold' => 'সম্পাদনা করুন',
+'editold' => 'সম্পাদনা',
'viewsourceold' => 'উৎস দেখাও',
'editlink' => 'সম্পাদনা',
'viewsourcelink' => 'উৎস দেখুন',
'yourdomainname' => 'আপনার ডোমেইন',
'password-change-forbidden' => 'আপনি এই উইকিতে পাসওয়ার্ড পরিবর্তন করতে পারবেন না।',
'externaldberror' => 'হয় কোন বহিঃস্থ যাচাইকরণ ডাটাবেজ ত্রুটি ঘটেছে অথবা আপনার বহিঃস্থ অ্যাকাউন্ট হালনাগাদ করার অনুমতি নেই।',
-'login' => 'প্রবেশ করুন',
+'login' => 'প্রবেশ',
'nav-login-createaccount' => 'প্রবেশ/নতুন অ্যাকাউন্ট',
'loginprompt' => '{{SITENAME}}-তে প্রবেশ করতে হলে আপনার ব্রাউজারের কুকি অবশ্যই সক্রিয় করতে হবে।',
'userlogin' => 'প্রবেশ/নতুন অ্যাকাউন্ট',
'userlogout' => 'প্রস্থান',
'notloggedin' => 'আপনি সংযুক্ত নন',
'nologin' => "আপনার কি উইকিপিডিয়াতে অ্যাকাউন্ট নেই? তাহলে '''$1'''।",
-'nologinlink' => 'নতà§\81ন à¦\85à§\8dযাà¦\95াà¦\89নà§\8dà¦\9f à¦\96à§\81লুন',
+'nologinlink' => 'à¦\85à§\8dযাà¦\95াà¦\89নà§\8dà¦\9f তà§\88রি à¦\95রুন',
'createaccount' => 'নতুন অ্যাকাউন্ট খুলুন',
'gotaccount' => "আপনার কি ইতিমধ্যে একটি অ্যাকাউন্ট তৈরি করা আছে? '''$1''' করুন।",
'gotaccountlink' => 'প্রবেশ',
'hr_tip' => 'অনুভূমিক রেখা (সংযতভাবে ব্যবহার করুন)',
# Edit pages
-'summary' => 'সমà§\8dপাদনা সারাà¦\82শ:',
+'summary' => 'সারাংশ:',
'subject' => 'বিষয়/শিরোনাম:',
'minoredit' => 'অনুল্লেখ্য',
'watchthis' => 'এই পাতাটি নজরে রাখুন',
'prefs-help-recentchangescount' => 'এতে সাম্প্রতিক পরিবর্তনসমূহ, পাতার ইতিহাস এবং লগ অন্তর্ভুক্ত।',
'prefs-help-watchlist-token' => 'এই ঘরটি একটি গোপন শব্দ চাবি দ্বারা পূরণ করলে আপনার নজর তালিকার জন্য একটি আরএসএস ফিড তৈরী হবে। যারা এই ঘরের চাবি জানবে তারা আপনার নজর তালিকা দেখতে পারবে, তাই একটি গোপন মান ব্যবহার করুন। এখানে এলোমেলোভাবে তৈরী একটি মান দেখানো হয়েছে যা আপনি ব্যবহার করতে পারেন: $1',
'savedprefs' => 'আপনার পছন্দগুলো সংরক্ষণ করা হয়েছে।',
-'timezonelegend' => 'সময় বলয়:',
+'timezonelegend' => 'সময়স্থান:',
'localtime' => 'স্থানীয় সময়:',
'timezoneuseserverdefault' => 'উইকির পূর্বনির্ধারিত সময় ব্যবহার করো ($1)',
'timezoneuseoffset' => 'অন্য (অফসেট নির্দিষ্ট করুন)',
'listusers-editsonly' => 'শুধুমাত্র এমন ব্যবহারকারীদের দেখাও যাদের অবদান আছে',
'listusers-creationsort' => 'তৈরির তারিখ অনুসারে সাজাও',
'usereditcount' => '$1 {{PLURAL:$1|সম্পাদনা|সম্পাদনা}}',
-'usercreated' => 'লিঙ্গ: $3 তৈরি হয়েছে $1 তারিখে, সময়: $2',
+'usercreated' => '{{GENDER:$3|তৈরি হয়েছে}} $1 তারিখ, সময়: $2',
'newpages' => 'নতুন পাতাসমূহ',
'newpages-username' => 'ব্যবহারকারী নাম:',
'ancientpages' => 'পুরানো নিবন্ধ',
# Special:ListUsers
'listusersfrom' => 'সেই সব ব্যবহারকারী দেখাও যাদের নাম এই অক্ষর দিয়ে শুরু:',
-'listusers-submit' => 'দà§\87à¦\96ানà§\8b হà§\8bà¦\95',
+'listusers-submit' => 'দà§\87à¦\96াà¦\93',
'listusers-noresult' => 'কোন ব্যবহারকারী খুঁজে পাওয়া যায়নি।',
'listusers-blocked' => '(ব্লককৃত)',
তথ্যসূত্র হিসেবে সাম্প্রতিক বাধাদান লগের ভুক্তিটি নিচে দেওয়া হলো:',
'sp-contributions-search' => 'অবদানসমূহের জন্য অনুসন্ধান',
'sp-contributions-username' => 'আইপি (IP) ঠিকানা অথবা ব্যবহারকারীর নাম:',
-'sp-contributions-toponly' => 'শà§\81ধà§\81মাতà§\8dর সà§\87à¦\87 সমà§\8dপাদনাà¦\97à§\81লি দà§\87à¦\96à§\87ও যেগুলো সাম্প্রতিক সংস্করণের অন্তর্ভুক্ত।',
+'sp-contributions-toponly' => 'শà§\81ধà§\81মাতà§\8dর সà§\87à¦\87 সমà§\8dপাদনাà¦\97à§\81লি দà§\87à¦\96াও যেগুলো সাম্প্রতিক সংস্করণের অন্তর্ভুক্ত।',
'sp-contributions-submit' => 'অনুসন্ধান',
# What links here
'exportnohistory' => "----
'''লক্ষ্য করুন:''' কর্মদক্ষতা-সম্পর্কিত কারণের জন্য এই ফর্মের মাধ্যমে কোন পাতার সমগ্র ইতিহাস রপ্তানি করা নিষ্ক্রিয় করা হয়েছে।",
'exportlistauthors' => 'প্রতি পাতার অবদানকারীর একটি পূর্ণাঙ্গ তালিকা যুক্ত হবে',
-'export-submit' => 'রপ্তানি করা হোক',
+'export-submit' => 'রপ্তানি',
'export-addcattext' => 'এই বিষয়শ্রেণী থেকে পাতা যোগ করা হোক:',
'export-addcat' => 'যোগ',
'export-addnstext' => 'নামস্থান থেকে পাতা যুক্ত করুন:',
'size-gigabytes' => '$1 গিগাবাইট',
# Live preview
-'livepreview-loading' => 'লোডিং…',
+'livepreview-loading' => 'লোডিং...',
'livepreview-ready' => 'লোডিং… প্রস্তুত!',
'livepreview-failed' => 'তাৎক্ষণিক প্রাকদর্শন কাজ করছে না! সাধারণ প্রাকদর্শন চেষ্টা করুন।',
'livepreview-error' => 'সংযোগ প্রদানে সম্ভব নয়: $1 "$2"। সাধারণ প্রাকদর্শন চেষ্টা করুণ।',
'underline-always' => 'Atav',
'underline-never' => 'Morse',
-'underline-default' => 'Diouzh ar merdeer',
+'underline-default' => 'Merdeer dre ziouer',
# Font style option in Special:Preferences
'editfont-style' => 'Stil font an takad skridaozañ :',
'note' => "'''Notenn :'''",
'previewnote' => "'''Diwallit mat, n'eus ken ur rakweled eus an destenn-mañ.'''
N'eo ket bet enrollet ho kemmoù evit c'hoazh !",
-'continue-editing' => "Kenderc'hel da gemmañ",
+'continue-editing' => "Mont d'an takad kemmañ",
'previewconflict' => 'Gant ar rakweled e teu testenn ar bajenn war wel evel ma vo pa vo bet enrollet.',
'session_fail_preview' => "'''Ho tigarez! N'eus ket bet tu da enrollañ ho kemmoù rak kollet eo bet roadennoù an dalc'h.'''
Klaskit en-dro mar plij.
'edit-already-exists' => "N'eus ket bet gallet krouiñ ur bajenn nevez.
Krouet e oa bet c'hoazh.",
'defaultmessagetext' => 'Testenn dre ziouer',
+'content-failed-to-parse' => "C'hwitet eo dielfennadur endalc'had $2 evit ar patrom $1: $3",
+'invalid-content-data' => "n'eo ket mat roadennoù an endalc'had",
+'content-not-allowed-here' => 'N\'eo ket aotreet an endalc\'had "$1" er bajenn [[$2]]',
# Content models
'content-model-wikitext' => 'wikitestenn',
'linksearch-ok' => 'Klask',
'linksearch-text' => 'Gallout a reer implijout arouezennoù "joker" evel, da skouer, "*.wikipedia.org".
Rekis eo dezho un domani a-us da nebeutañ evel, da skouer, "*.org".<br />
-Protokoloù skoret : <code>$1</code> (na lakait hini ebet eus ar re-se en ho klask)',
+Protokoloù skoret : <code>$1</code> (defaults to http:// na lakait hini ebet eus ar re-se en ho klask)',
'linksearch-line' => '$1 gant ul liamm adal $2',
'linksearch-error' => "N'hall an arouezennoù joker bezañ implijet nemet e deroù anv domani an ostiz.",
'whatlinkshere-hideredirs' => '$1 adkas',
'whatlinkshere-hidetrans' => '$1 treuzkluzadur',
'whatlinkshere-hidelinks' => '$1 liamm',
-'whatlinkshere-hideimages' => '$1 liamm skeudennoù',
+'whatlinkshere-hideimages' => '$1 ar restroù liammet',
'whatlinkshere-filters' => 'Siloù',
# Block/unblock
# Info page
'pageinfo-title' => 'Titouroù evit "$1"',
-'pageinfo-not-current' => "Evit an adwel bremañ e c'hall bezañ diskwelet an titouroù hepken.",
+'pageinfo-not-current' => "Hon digarezit, ne c'haller ket reiñ an titouroù-mañ evit an adweloù kozh.",
'pageinfo-header-basic' => 'Titouroù diazez',
'pageinfo-header-edits' => 'Kemmoù',
'pageinfo-header-restrictions' => 'Gwarez ar bajenn',
'pageinfo-templates' => "{{PLURAL:$1|Patrom endalc'het|Patromoù endalc'het}} ($1)",
'pageinfo-toolboxlink' => 'Titouroù ar bajenn',
'pageinfo-redirectsto' => 'Adkas a ra da',
+'pageinfo-redirectsto-info' => 'Titouroù',
'pageinfo-contentpage-yes' => 'Ya',
'pageinfo-protect-cascading-yes' => 'Ya',
'ipb-confirm' => 'Confirma el blocatge',
'badipaddress' => "L'adreça IP no té el format correcte.",
'blockipsuccesssub' => "S'ha blocat amb èxit",
-'blockipsuccesstext' => "[[Special:Contributions/$1|$1]] ha estat {{GENDER:$1|bloquejat|bloquejada|bloquejat/da}}.<br />
-Vegeu la [[Special:BlockList|llista d'IP blocades]] per revisar els bloqueigs.",
+'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] ha estat {{GENDER:$1|blocat|blocada}}.<br />
+Vegeu la [[Special:BlockList|llista de bloqueigs]] per revisar-los.',
'ipb-blockingself' => 'Esteu a punt de blocar-vos a vós mateix! Esteu segurs de voler-ho fer?',
'ipb-confirmhideuser' => "Esteu a punt de bloquejar un usuari que està marcat amb l'opció «amaga l'usuari». Això suprimirà el seu nom a totes les llistes i registres. Esteu segurs de voler-ho fer?",
'ipb-edit-dropdown' => 'Edita les raons per a blocar',
'unwatchedpages' => 'لاپەڕە چاودێرینەکراوەکان',
# List redirects
-'listredirects' => 'Ù\84Û\8cستÛ\8c ئاÚ\95استÛ\95کراÙ\88ەکان',
+'listredirects' => 'Ù¾Û\8eرستÛ\8c Ú\95Û\95Ù\88اÙ\86Û\95Ú©Û\95رەکان',
# Unused templates
'unusedtemplates' => 'داڕێژە بەکارنەھێنراوەکان',
'newwindow' => '(otevře se v novém okně)',
'cancel' => 'Storno',
'moredotdotdot' => 'Další…',
-'mypage' => 'Moje stránka',
-'mytalk' => 'Moje diskuse',
+'mypage' => 'Stránka',
+'mytalk' => 'Diskuse',
'anontalk' => 'Diskuse k této IP adrese',
'navigation' => 'Navigace',
'and' => ' a',
'linksearch-ok' => 'Hledat',
'linksearch-text' => 'Lze používat zástupné znaky, např. „*.wikipedia.org“.
Povinná je přinejmenším doména nejvyššího řádu, např. „*.org“.<br />
-Podporované protokoly: <code>$1</code> (nepřidávejte je do hledání).',
+Podporované protokoly: <code>$1</code> (pokud není protokol uveden, použije se http://).',
'linksearch-line' => '$2 odkazuje na $1',
'linksearch-error' => 'Zástupné znaky lze použít jen na začátku doménového jména.',
# Contributions
'contributions' => 'Příspěvky uživatele',
'contributions-title' => 'Příspěvky uživatele $1',
-'mycontris' => 'Mé příspěvky',
+'mycontris' => 'Příspěvky',
'contribsub2' => '$1 ($2)',
'nocontribs' => 'Nenalezeny žádné změny vyhovující kritériím.',
'uctop' => ' (aktuální)',
'logentry-move-move_redir-noredirect' => '$1 přesunul stránku $3 na $4 místo přesměrování bez založení přesměrování',
'logentry-patrol-patrol' => '$1 označil revizi $4 stránky $3 jako prověřenou',
'logentry-patrol-patrol-auto' => '$1 automaticky označil revizi $4 stránky $3 jako prověřenou',
-'logentry-newusers-newusers' => '$1 založil uživatelský účet',
-'logentry-newusers-create' => '$1 založil uživatelský účet',
+'logentry-newusers-newusers' => '$1 si založil uživatelský účet',
+'logentry-newusers-create' => '$1 si založil uživatelský účet',
'logentry-newusers-create2' => '$1 založil uživatelský účet $3',
'logentry-newusers-autocreate' => 'Automaticky byl založen účet $1',
'newuserlog-byemail' => 'heslo zasláno e-mailem',
'underline-always' => 'Bob amser',
'underline-never' => 'Byth',
-'underline-default' => 'Rhagosodyn y porwr',
+'underline-default' => "Rhagosodyn y porwr neu'r wedd",
# Font style option in Special:Preferences
'editfont-style' => 'Arddull y ffont yn y blwch golygu:',
'newwindow' => '(yn agor mewn ffenest newydd)',
'cancel' => 'Diddymu',
'moredotdotdot' => 'Rhagor...',
-'mypage' => 'Fy nhudalen',
-'mytalk' => 'Fy sgwrs',
+'mypage' => 'Tudalen defnyddiwr',
+'mytalk' => 'Sgwrs',
'anontalk' => 'Sgwrs ar gyfer y cyfeiriad IP hwn',
'navigation' => 'Panel llywio',
'and' => ' a/ac',
Mae ar gael yn barod.',
'defaultmessagetext' => 'Y testun rhagosodedig',
+# Content models
+'content-model-wikitext' => 'cystrawen wici',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
+
# Parser/template warnings
'expensive-parserfunction-warning' => "'''Rhybudd:''' Mae gormod o alwadau ar ffwythiannau dosrannu sy'n dreth ar adnoddau yn y dudalen hon.
# Preferences page
'preferences' => 'Dewisiadau',
-'mypreferences' => 'Fy newisiadau',
+'mypreferences' => 'Dewisiadau',
'prefs-edits' => 'Nifer y golygiadau:',
'prefsnologin' => 'Nid ydych wedi mewngofnodi',
'prefsnologintext' => 'Rhaid i chi <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} fewngofnodi]</span> er mwyn gosod eich dewisiadau defnyddiwr.',
# Watchlist
'watchlist' => 'Fy rhestr wylio',
-'mywatchlist' => 'Fy rhestr wylio',
+'mywatchlist' => 'Rhestr wylio',
'watchlistfor2' => 'Yn ôl gofyn $1 $2',
'nowatchlist' => "Mae eich rhestr wylio'n wag.",
'watchlistanontext' => "Rhaid $1 er mwyn gweld neu ddiwygio'ch rhestr wylio.",
# Contributions
'contributions' => "Cyfraniadau'r defnyddiwr",
'contributions-title' => "Cyfraniadau'r defnyddiwr am $1",
-'mycontris' => 'Fy nghyfraniadau',
+'mycontris' => 'Cyfraniadau',
'contribsub2' => 'Dros $1 ($2)',
'nocontribs' => "Heb ddod o hyd i newidiadau gyda'r meini prawf hyn.",
'uctop' => '(cyfredol)',
'whatlinkshere-hideredirs' => '$1 ailgyfeiriadau',
'whatlinkshere-hidetrans' => '$1 cynhwysion',
'whatlinkshere-hidelinks' => '$1 cysylltau',
-'whatlinkshere-hideimages' => '$1 cysylltau delweddau',
+'whatlinkshere-hideimages' => '$1 cysylltau ffeiliau',
'whatlinkshere-filters' => 'Hidlau',
# Block/unblock
'pageinfo-default-sort' => 'Allwedd trefnu diofyn',
'pageinfo-length' => 'Hyd y dudalen (beitiau)',
'pageinfo-article-id' => 'ID y dudalen',
+'pageinfo-language' => 'Iaith cynnwys y dudalen',
'pageinfo-robot-policy' => 'Statws i beiriannau chwilio',
'pageinfo-views' => 'Nifer yr ymweliadau',
'pageinfo-watchers' => 'Nifer gwylwyr y dudalen',
'pageinfo-authors' => 'Cyfanswm yr awduron gwahanol',
'pageinfo-magic-words' => '{{PLURAL:$1|Gair|Gair|Geiriau}} hud ($1)',
'pageinfo-hidden-categories' => '{{PLURAL:$1|Categori|Categori|Categorïau}} cudd ($1)',
+'pageinfo-toolboxlink' => 'Gwybodaeth am y dudalen',
# Skin names
'skinname-standard' => 'Safonol',
'underline-always' => 'Altid',
'underline-never' => 'Aldrig',
-'underline-default' => 'Brug browserens indstilling',
+'underline-default' => 'Brug browserens indstilling eller standarden for det valgte udseende',
# Font style option in Special:Preferences
'editfont-style' => 'Skriftstil ved redigering:',
'cancel' => 'Afbryd',
'moredotdotdot' => 'Mere...',
'mypage' => 'Min side',
-'mytalk' => 'Min diskussion',
+'mytalk' => 'Diskussion',
'anontalk' => 'Diskussionsside for denne IP-adresse',
'navigation' => 'Navigation',
'and' => ' og',
'rightslogtext' => 'Dette er en log over ændringer i brugeres rettigheder.',
'rightslogentry' => 'ændrede grupperettigheder for „$1“ fra „$2“ til „$3“.',
'rightslogentry-autopromote' => 'blev automatisk forfremmet fra $2 til $3',
+'logentry-rights-rights' => '$1 ændrede gruppemedlemskabet for $3 fra $4 til $5',
+'logentry-rights-rights-legacy' => '$1 ændrede gruppemedlemskabet for $3',
+'logentry-rights-autopromote' => '$1 blev automatisk forfremmet fra $4 til $5',
'rightsnone' => '(-)',
# Associated actions - in the sentence "You do not have permission to X"
'linksearch-ok' => 'Søg',
'linksearch-text' => 'Wildcards som "*.wikipedia.org" kan benyttes.
Der skal som minimum angives et topniveau-domæne som f. eks. "*.org".<br />
-Understøttede protokoller: <code>$1</code> (tilføj ikke protokollerne til din søgning).',
+Understøttede protokoller: <code>$1</code> (bruger automatisk http:// hvis der ikke er angivet nogen protokol).',
'linksearch-line' => '$2 linker til $1',
'linksearch-error' => 'Wildcards må kun benyttes i starten af hostnavnet.',
# Watchlist
'watchlist' => 'Overvågningsliste',
-'mywatchlist' => 'Min overvågningsliste',
+'mywatchlist' => 'Overvågningsliste',
'watchlistfor2' => 'For $1 $2',
'nowatchlist' => 'Du har ingenting i din overvågningsliste.',
'watchlistanontext' => 'Du skal $1, for at se din overvågningsliste eller ændre indholdet af den.',
# Contributions
'contributions' => 'Brugerbidrag',
'contributions-title' => 'Brugerbidrag for $1',
-'mycontris' => 'Mine bidrag',
+'mycontris' => 'Bidrag',
'contribsub2' => 'For $1 ($2)',
'nocontribs' => 'Ingen ændringer er fundet som opfylder disse kriterier.',
'uctop' => ' (seneste)',
'whatlinkshere-hideredirs' => '$1 omdirigeringer',
'whatlinkshere-hidetrans' => '$1 inkluderinger',
'whatlinkshere-hidelinks' => '$1 henvisninger',
-'whatlinkshere-hideimages' => '$1 fillinks',
+'whatlinkshere-hideimages' => '$1 filhenvisninger',
'whatlinkshere-filters' => 'Filtre',
# Block/unblock
'duration-centuries' => '$1 {{PLURAL:$1|århundrede|århundreder}}',
'duration-millennia' => '$1 {{PLURAL:$1|årtusind|årtusinder}}',
+# Unknown messages
+'mytalk-parenthetical' => 'diskussion',
);
'cancel' => 'Abbrechen',
'moredotdotdot' => 'Mehr …',
'mypage' => 'Eigene Seite',
-'mytalk' => 'Eigene Diskussion',
+'mytalk' => 'Diskussion',
'anontalk' => 'Diskussionsseite dieser IP',
'navigation' => 'Navigation',
'and' => ' und',
'linksearch-pat' => 'Suchmuster:',
'linksearch-ns' => 'Namensraum:',
'linksearch-ok' => 'Suchen',
-'linksearch-text' => 'Diese Spezialseite ermöglicht die Suche nach Seiten, in denen bestimmte Weblinks enthalten sind. Dabei können Platzhalter wie beispielsweise <code>*.beispiel.de</code> benutzt werden. Es muss mindestens eine Top-Level-Domain, z. B. „*.org“. angegeben werden. <br />Unterstützte Protokolle: <code>$1</code> (Diese bitte nicht bei der Suchanfrage angeben.)',
+'linksearch-text' => 'Diese Spezialseite ermöglicht die Suche nach Seiten, in denen bestimmte Weblinks enthalten sind. Dabei können Platzhalter wie beispielsweise <code>*.beispiel.de</code> benutzt werden. Es muss mindestens eine Top-Level-Domain, z. B. „*.org“. angegeben werden. <br />Unterstützte Protokolle: <code>$1</code> (Standard ist http, falls kein Protokoll angegeben ist.)',
'linksearch-line' => '$1 ist verlinkt von $2',
'linksearch-error' => 'Wildcards können nur am Anfang der URL verwendet werden.',
# Contributions
'contributions' => 'Benutzerbeiträge',
'contributions-title' => 'Benutzerbeiträge von „$1“',
-'mycontris' => 'Eigene Beiträge',
+'mycontris' => 'Beiträge',
'contribsub2' => 'Von $1 ($2)',
'nocontribs' => 'Es wurden keine Benutzerbeiträge mit diesen Kriterien gefunden.',
'uctop' => '(aktuell)',
'pageinfo-lasttime' => 'Datum der letzten Bearbeitung',
'pageinfo-edits' => 'Gesamtzahl der Bearbeitungen',
'pageinfo-authors' => 'Gesamtzahl unterschiedlicher Autoren',
-'pageinfo-recent-edits' => 'Anzahl der kürzlich erfolgten Bearbeitungen (innerhalb von $1)',
-'pageinfo-recent-authors' => 'Anzahl der unterschiedlichen Autoren',
+'pageinfo-recent-edits' => 'Anzahl der kürzlich erfolgten Bearbeitungen (innerhalb der letzten $1)',
+'pageinfo-recent-authors' => 'Anzahl unterschiedlicher Autoren',
'pageinfo-magic-words' => '{{PLURAL:$1|Magisches Wort|Magische Wörter}} ($1)',
'pageinfo-hidden-categories' => 'Versteckte {{PLURAL:$1|Kategorie|Kategorien}} ($1)',
'pageinfo-templates' => 'Eingebundene {{PLURAL:$1|Vorlage|Vorlagen}} ($1)',
'duration-centuries' => '$1 {{PLURAL:$1|Jahrhundert|Jahrhunderte}}',
'duration-millennia' => '$1 {{PLURAL:$1|Jahrtausend|Jahrtausende}}',
+# Unknown messages
+'mytalk-parenthetical' => 'Diskussion',
);
'underline-always' => 'Tım',
'underline-never' => 'Qet',
-'underline-default' => 'Cild ya zi cıgeyrayoğo hesebiyaye',
+'underline-default' => 'Cild ya zi cıgeyrayoğo hesıbyaye',
# Font style option in Special:Preferences
'editfont-style' => 'Cayê vurnayışi de terzê nuştışi:',
-'editfont-default' => 'Cıgeyrayoğo hesebiyaye',
+'editfont-default' => 'Cıgeyrayoğo hesabiyaye',
'editfont-monospace' => 'Terzê nusteyê sabıtcagırewtoği',
'editfont-sansserif' => 'Babetê Sans-serifi',
'editfont-serif' => 'Babetê serifi',
'about' => 'Heqa',
'article' => 'Wesiqe',
-'newwindow' => '(teqa da newey de beno a)',
+'newwindow' => '(pençereyê newey de beno a)',
'cancel' => 'Bıtexelne',
'moredotdotdot' => 'Vêşi...',
-'mypage' => 'Pela mı',
-'mytalk' => 'Werênayışê mı',
+'mypage' => 'Per',
+'mytalk' => 'Werênayış',
'anontalk' => 'Pela werênayışê nê IPy',
'navigation' => 'Geyrayış',
'and' => ' u',
# Vector skin
'vector-action-addsection' => 'Mesel Vırazê',
'vector-action-delete' => 'Besterne',
-'vector-action-move' => 'Bere',
+'vector-action-move' => 'Berê',
'vector-action-protect' => 'Bıpawe',
'vector-action-undelete' => 'Esterıtışi peyser bıgê',
'vector-action-unprotect' => 'Starkerdışi bıvurne',
'image_sample' => 'Misal resim.jpg',
'image_tip' => 'Dosyaya gumın',
'media_sample' => 'misal.jpg',
-'media_tip' => 'Gırey dosya',
+'media_tip' => 'Gıreyê dosya',
'sig_tip' => 'İmza u wext',
'hr_tip' => 'Çıxiza dimdayi (hend akar mefiye)',
Vurnayişê şıma qey nêxerepyayişê peli tepeya geyra a.
Eke şıma servisê proksi yo anonim şuxulneni sebebê ey noyo.'''",
'edit_form_incomplete' => "'''Qandê form dê vurnayışa tay wastera ma nêreşti; Vurnayışê ke şıma kerdê nêalızyayê, çım ra ravyarnê u fına bıcerbnê.'''",
-'editing' => '$1 Vurnayış',
+'editing' => 'Şımayê kenê <font style="color:red">$1</font> bıvurnê',
'creating' => "Pela $1'i vıraze",
'editingsection' => 'Per da $1 de şımaye kenê ke leti bıvurnê',
'editingcomment' => '$1 vuryeno (qısmo newe)',
# Preferences page
'preferences' => 'Tercihi',
-'mypreferences' => 'Tercihê mı',
+'mypreferences' => 'Tercihi',
'prefs-edits' => 'Amarê vurnayışan:',
'prefsnologin' => 'Şıma cıkewtış nêvıraşto',
'prefsnologintext' => 'Şıma gani be <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} cikewte]</span> ke tercihanê karberi xo eyar bıkerê.',
'newpages' => 'Pelê newey',
'newpages-username' => 'Nameyê karberi:',
'ancientpages' => 'Wesiqeyê ke vurnayışê ciyê peyeni tewr kehani',
-'move' => 'Bere',
+'move' => 'Berdış',
'movethispage' => 'Ena pele bere',
'unusedimagestext' => 'Enê dosyey estê, feqet zerrey yew pele de wedardey niyê.
Xo vira mekerê ke, sıteyê webiê bini şenê direkt ebe URLi yew dosya ra gırê bê, u wına şenê verba gurênayışo feal de tiya hewna lista bê.',
'linksearch-pat' => 'bıgêr motif:',
'linksearch-ns' => 'Cayênameyî:',
'linksearch-ok' => 'Cı geyre',
-'linksearch-text' => 'joker ê zey "*.wikipedia.org"i karneno.<br />
-qaydeyê destek biyayeyi: <code>$1</code>',
+'linksearch-text' => 'Jokeri ê zey "*.wikipedia.org"i benê ke bıgureniyê.
+Tewr senık yew sewiya serêna cayê tesiri lazıma, mesela "*.org".<br />
+Qeydeyê destegbiyayey: <code>$1</code> (qet yew qeydeyo hesabiyaye http:// ke name nêbiyo).',
'linksearch-line' => '$1, $2 ra link biya',
'linksearch-error' => 'jokeri têna nameyê makina ya serekini de aseni/eseni.',
# Watchlist
'watchlist' => 'Lista mına seyrkerdışi',
-'mywatchlist' => 'Lista mına seyrkerdışi',
+'mywatchlist' => 'Lista seyr kerdışi',
'watchlistfor2' => 'Qandê $1 ($2)',
'nowatchlist' => 'listeya temaşa kerdıişê şıma de yew madde zi çina.',
'watchlistanontext' => 'qey vurnayişê maddeya listeya temaşakerdişi $1.',
# Contributions
'contributions' => 'İştiraqê karberi',
'contributions-title' => 'Dekerdenê karber de $1',
-'mycontris' => 'Cıkerdışê mı',
+'mycontris' => 'Cıkerdışi',
'contribsub2' => 'Qandê $1 ($2)',
'nocontribs' => 'Ena kriteriya de vurnayîş çini yo.',
'uctop' => '(top)',
'whatlinkshere-hideredirs' => 'Hetenayışê $1',
'whatlinkshere-hidetrans' => 'Açarnayışê $1',
'whatlinkshere-hidelinks' => 'Greyê $1',
-'whatlinkshere-hideimages' => 'Gireyê resımi $1',
+'whatlinkshere-hideimages' => 'Gıreyê dosya $1',
'whatlinkshere-filters' => 'Avrêci',
# Block/unblock
'duration-centuries' => '$1 {{PLURAL:$1|seserre|seserri}}',
'duration-millennia' => '$1 {{PLURAL:$1|milenyum|milenyumi}}',
+# Unknown messages
+'mytalk-parenthetical' => 'behse',
);
'newwindow' => '(se wótcynijo w nowem woknje)',
'cancel' => 'Pśetergnuś',
'moredotdotdot' => 'Wěcej…',
-'mypage' => 'Mój bok',
-'mytalk' => 'mója diskusija',
+'mypage' => 'Bok',
+'mytalk' => 'Diskusija',
'anontalk' => 'Diskusija z toś teju IP',
'navigation' => 'Nawigacija',
'and' => ' a',
# Preferences page
'preferences' => 'Nastajenja',
-'mypreferences' => 'nastajenja',
+'mypreferences' => 'Nastajenja',
'prefs-edits' => 'Licba wobźěłanjow:',
'prefsnologin' => 'Njejsy pśizjawjony',
'prefsnologintext' => 'Musyš se <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} pśizjawiś]</span>, aby mógał swóje nastajenja změniś.',
'linksearch-ok' => 'Pytaś',
'linksearch-text' => 'Jo móžno zastupne znamuška kaž "*.wikipedia.org" wužywaś.
Jo nanejmjenjej głowna domena trěbna, na pśikład "*.org"<br />
-Pódpěrane protokole: <code>$1</code> (pšosym njepódaj je w swójom pytanju).',
+Pódpěrane protokole: <code>$1</code> (standard jo http://, jolic žeden protokol njejo pódany).',
'linksearch-line' => '$1 wótkazany z $2',
'linksearch-error' => 'Zasupne znamješko daju se jano na zachopjeńku URL wužywaś.',
# Watchlist
'watchlist' => 'Wobglědowańka',
-'mywatchlist' => 'wobglědowańka',
+'mywatchlist' => 'Wobglědowańka',
'watchlistfor2' => 'Za wužywarja $1 $2',
'nowatchlist' => 'Žedne zapise w twójej wobglědowańce.',
'watchlistanontext' => 'Dejš $1, aby mógał swóju wobglědowańku wiźeś abo zapise w njej wobźěłaś.',
# Contributions
'contributions' => 'Wužywarske pśinoski',
'contributions-title' => 'Wužywarske pśinoski wót $1',
-'mycontris' => 'móje pśinoski',
+'mycontris' => 'Pśinoski',
'contribsub2' => 'Za $1 ($2)',
'nocontribs' => 'Za toś te kriterije njejsu žedne změny se namakali.',
'uctop' => '(aktualny)',
'duration-centuries' => '$1 {{PLURAL:$1|stolěśe|stolěśi|stolěśa|stolěśow}}',
'duration-millennia' => '$1 {{PLURAL:$1|lěttysac|lěttysaca|lěttysace|lěttysacow}}',
+# Unknown messages
+'mytalk-parenthetical' => 'diskusija',
);
'history_short' => 'Ιστορικό',
'updatedmarker' => 'Ενημερωμένα από την τελευταία επίσκεψή μου',
'printableversion' => 'Εκτυπώσιμη έκδοση',
-'permalink' => 'Î\9cÏ\8cνιμος σύνδεσμος',
+'permalink' => 'ΣÏ\84αθεÏ\81Ï\8cς σύνδεσμος',
'print' => 'Εκτύπωση',
'view' => 'Προβολή',
'edit' => 'Επεξεργασία',
'articlepage' => 'Εμφάνιση σελίδας κειμένου',
'talk' => 'Συζήτηση',
'views' => 'Εμφανίσεις',
-'toolbox' => 'Î\95Ï\81γαλεία',
+'toolbox' => 'Î\95Ï\81γαλειοθήκη',
'userpage' => 'Εμφάνιση σελίδας χρήστη',
'projectpage' => 'Εμφάνιση σελίδας βοήθειας',
'imagepage' => 'Εμφάνιση σελίδας αρχείου',
Μπορεί να υπάρχουν λεπτομέρειες στο [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} αρχείο απόκρυψης].
Μπορείτε ακόμα [$1 να δείτε την έκδοση] αν επιθυμείτε να συνεχίσετε.",
'rev-deleted-text-view' => "Αυτή η αναθεώρηση της σελίδας έχει '''διαγραφεί'''.
-Μπορείτε να την δείτε, λεπτομέρειες μπορούν να βρεθούν στο [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} αρχείο καταγραφής διαγραφών].",
+Μπορείτε να την δείτε. Λεπτομέρειες μπορούν να βρεθούν στο [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} αρχείο καταγραφής διαγραφών].",
'rev-suppressed-text-view' => "Αυτή η έκδοση της σελίδας έχει '''κατασταλλεί'''.
Μπορείτε να τη δείτε. Λεπτομέρειες μπορούν να βρεθούν στο [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} αρχείο καταστολής].",
'rev-deleted-no-diff' => "Δεν μπορείτε να δείτε αυτή τη διαφορά επειδή μια από τις αναθεωρήσεις έχει '''διαγραφεί'''.
'tooltip-search-go' => 'Πήγαινε σε μια σελίδα με το ακριβές όνομα εάν υπάρχει',
'tooltip-search-fulltext' => 'Αναζήτηση για αυτό το κείμενο',
'tooltip-p-logo' => 'Αρχική σελίδα',
-'tooltip-n-mainpage' => 'Î\94είÏ\84ε Ï\84ην Î\91ρχική σελίδα',
+'tooltip-n-mainpage' => 'Î\94είÏ\84ε Ï\84ην αρχική σελίδα',
'tooltip-n-mainpage-description' => 'Επισκεφθείτε την κύρια σελίδα',
'tooltip-n-portal' => 'Σχετικά με το Wiκi - πώς μπορείτε να βοηθήσετε, πού μπορείτε να απευθυνθείτε',
'tooltip-n-currentevents' => 'Πληροφορίες για πρόσφατα γεγονότα',
# Info page
'pageinfo-title' => 'Πληροφορίες για "$1"',
+'pageinfo-not-current' => 'Μας συγχωρείτε, είναι αδύνατο να παράσχουμε αυτή την πληροφορία για παλιές αναθεωρήσεις.',
'pageinfo-header-basic' => 'Βασικές πληροφορίες',
'pageinfo-header-edits' => 'Ιστορικό επεξεργασίας',
'pageinfo-header-restrictions' => 'Προστασία σελίδας',
'pageinfo-default-sort' => 'Προεπιλεγμένο κλειδί ταξινόμησης',
'pageinfo-length' => 'Μήκος σελίδας (σε bytes)',
'pageinfo-article-id' => 'Αναγνωριστικό σελίδας',
+'pageinfo-language' => 'Γλώσσα σελίδας περιεχομένου',
+'pageinfo-robot-policy' => 'Στάτους μηχανής αναζήτησης',
'pageinfo-views' => 'Αριθμός προβολών',
-'pageinfo-watchers' => 'Αριθμός παρατηρητών',
-'pageinfo-edits' => 'Αριθμός επεξεργασιών',
-'pageinfo-authors' => 'Αριθμός ξεχωριστών συγγραφέων',
+'pageinfo-watchers' => 'Αριθμός παρατηρητών σελίδας',
+'pageinfo-redirects-name' => 'Ανακατευθύνσεις σε αυτή τη σελίδα',
+'pageinfo-redirects-value' => '$1',
+'pageinfo-subpages-name' => 'Υποσελίδες αυτής της σελίδας',
+'pageinfo-firstuser' => 'Δημιουργός της σελίδας',
+'pageinfo-firsttime' => 'Ημερομηνία δημιουργίας της σελίδας',
+'pageinfo-lastuser' => 'Τελευταίος συντάκτης',
+'pageinfo-lasttime' => 'Ημερομηνία τελευταίας επεξεργασίας',
+'pageinfo-edits' => 'Συνολικός αριθμός επεξεργασιών',
+'pageinfo-authors' => 'Συνολικός αριθμός διαφορετικών συντακτών',
+'pageinfo-recent-edits' => 'Πρόσφατος αριθμός επεξεργασιών (σε διάστημα &1)',
+'pageinfo-recent-authors' => 'Πρόσφατος αριθμός μοναδικών συντακτών',
+'pageinfo-magic-words' => '{{PLURAL:$1|Μαγική λέξη|Μαγικές λέξεις}} ($1)',
+'pageinfo-hidden-categories' => '{{PLURAL:$1|Κρυφή κατηγορία|Κρυφές κατηγορίες}} ($1)',
+'pageinfo-templates' => 'Ενσωματωμένα {{PLURAL:$1|πρότυπο|πρότυπα}} ($1)',
+'pageinfo-toolboxlink' => 'Πληροφορίες σελίδας',
+'pageinfo-redirectsto' => 'Ανακατευθύνσεις σε',
+'pageinfo-redirectsto-info' => 'πληροφορίες',
+'pageinfo-contentpage' => 'Υπολογίζονται ως σελίδες περιεχομένου',
+'pageinfo-contentpage-yes' => 'Ναι',
+'pageinfo-protect-cascading-yes' => 'Ναι',
# Skin names
'skinname-standard' => 'Κλασσικό',
'linkprefix' => '/^(.*?)([a-zA-Z\\x80-\\xff]+)$/sD', # only translate this message to other languages if you have to change it
-'about' => 'About',
-'article' => 'Content page',
-'newwindow' => '(opens in new window)',
-'cancel' => 'Cancel',
-'moredotdotdot' => 'More...',
-'mypage' => 'My page',
-'mytalk' => 'My talk',
-'anontalk' => 'Talk for this IP address',
-'navigation' => 'Navigation',
-'and' => ' and',
+'about' => 'About',
+'article' => 'Content page',
+'newwindow' => '(opens in new window)',
+'cancel' => 'Cancel',
+'moredotdotdot' => 'More...',
+'mypage' => 'Page',
+'mytalk' => 'Talk',
+'mytalk-parenthetical' => 'talk',
+'anontalk' => 'Talk for this IP address',
+'navigation' => 'Navigation',
+'and' => ' and',
# Cologne Blue skin
'qbfind' => 'Find',
# Preferences page
'preferences' => 'Preferences',
'preferences-summary' => '', # do not translate or duplicate this message to other languages
-'mypreferences' => 'My preferences',
+'mypreferences' => 'Preferences',
'prefs-edits' => 'Number of edits:',
'prefsnologin' => 'Not logged in',
'prefsnologintext' => 'You must be <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} logged in]</span> to set user preferences.',
# Watchlist
'watchlist' => 'My watchlist',
'watchlist-summary' => '', # do not translate or duplicate this message to other languages
-'mywatchlist' => 'My watchlist',
+'mywatchlist' => 'Watchlist',
'watchlistfor2' => 'For $1 $2',
'nowatchlist' => 'You have no items on your watchlist.',
'watchlistanontext' => 'Please $1 to view or edit items on your watchlist.',
'contributions' => 'User contributions',
'contributions-summary' => '', # do not translate or duplicate this message to other languages
'contributions-title' => 'User contributions for $1',
-'mycontris' => 'My contributions',
+'mycontris' => 'Contributions',
'contribsub2' => 'For $1 ($2)',
'nocontribs' => 'No changes were found matching these criteria.',
'uctop' => '(top)',
'underline-always' => 'Ĉiam',
'underline-never' => 'Neniam',
-'underline-default' => 'Defaŭlte laŭ foliumilo',
+'underline-default' => 'Pravaloro laŭ foliumilo',
# Font style option in Special:Preferences
'editfont-style' => 'Tipara stilo de redakta tekstujo',
'vector-action-protect' => 'Protekti',
'vector-action-undelete' => 'Malforigi',
'vector-action-unprotect' => 'Ŝanĝi protekadon',
-'vector-simplesearch-preference' => 'Ebligi plibonigitajn serĉajn sugestojn (nur Vektora etoso)',
+'vector-simplesearch-preference' => 'Ebligi simpligitan serĉan strion (nur Vektora etoso)',
'vector-view-create' => 'Krei',
'vector-view-edit' => 'Redakti',
'vector-view-history' => 'Vidi historion',
'protectedpagetext' => 'Tiu ĉi paĝo estas ŝlosita por malebligi redaktadon.',
'viewsourcetext' => 'Vi povas rigardi kaj kopii la fonton de la paĝo:',
'viewyourtext' => "Vi povas vidi kaj kopii la fonton de '''viaj redaktoj''' al ĉi tiu paĝo:",
-'protectedinterface' => 'Ĉi tiu paĝo provizas interfacan tekston por la softvaro, kaj estas ŝlosita por malabeligi misuzon.',
-'editinginterface' => "'''Atentu:''' Vi redaktas paĝon, kiu estas uzata kiel interfaca teksto por la rogramaro. Ŝanĝoj de ĉi tiu teksto povas ŝanĝi aspekton de la interfaco por aliaj uzantoj. Por tradukojn, bonvolu uzi [//translatewiki.net/wiki/Main_Page?setlang=eo translatewiki.net], la MediaWiki-projekton por lingvigaj versioj.",
+'protectedinterface' => 'Ĉi tiu paĝo provizas interfacan tekston por la softvaro, kaj estas ŝlosita por malebligi misuzon.
+Por aldoni aŭ ŝanĝi tradukojn por ĉiuj vikioj, bonvolu uzi [//translatewiki.net/ translatewiki.net], la projekto por provizi tradukojn por MediaWiki.',
+'editinginterface' => "'''Atentu:''' Vi redaktas paĝon, kiu estas uzata kiel interfaca teksto por la programaro. Ŝanĝoj de ĉi tiu teksto povas ŝanĝi aspekton de la interfaco por aliaj uzantoj sur ĉi tiu vikio. Por aldoni aŭ ŝanĝi tradukojn, bonvolu uzi [//translatewiki.net/ translatewiki.net], la MediaWiki-projekton por lingvigaj versioj.",
'sqlhidden' => '(SQL serĉomendo kaŝita)',
'cascadeprotected' => 'Ĉi tiu paĝo estas protektita kontraŭ redaktado, ĉar ĝi estas inkludita en la {{PLURAL:$1|sekvan paĝon, kiu|sekvajn paĝojn, kiuj}} estas {{PLURAL:$1|protektata|protektataj}} kun la "kaskada" opcio turnita sur:
$2',
aŭ [{{fullurl:{{FULLPAGENAME}}|action=edit}} redakti ĉi tiun paĝon]</span>.',
'noarticletext-nopermission' => 'Estas neniom da teksto en ĉi tiu paĝo.
Vi povas [[Special:Search/{{PAGENAME}}|serĉi ĉi tiun paĝan titolon]] en aliaj paĝoj,
-aŭ <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} serĉi la rilatajn protokolojn]</span>.',
+aŭ <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} serĉi la rilatajn protokolojn]</span>, sed vi ne rajtas krei ĉi tiun paĝon.',
'missing-revision' => 'La revizio n-ro $1 de la paĝo nomata "{{PAGENAME}}" ne ekzistas.
La kutima kaŭzo estas sekvi malaktualan historio-ligilon al paĝo forviŝita.
* '''Interreta Esplorilo''': Premu ''Stir'' klakante ''Refreŝu'', aŭ premu ''Stir-F5''
* '''Opera:''' Nuligi la kaŝmemoro en ''Iloj → Preferoj''",
'usercssyoucanpreview' => "'''Konsileto:''' Uzu la butonon \"Antaŭrigardi\" por provi vian novan CSS-kodon antaŭ konservado.",
-'userjsyoucanpreview' => "'''Konsileto:''' Uzu la butonon \"Antaŭrigard\" por provi vian novan JS-kodon antaŭ konservado.",
+'userjsyoucanpreview' => "'''Konsileto:''' Uzu la butonon \"{{int:showpreview}}\" por provi vian novan JS-kodon antaŭ konservado.",
'usercsspreview' => "'''Notu ke vi nur antaŭvidas vian uzanto-CSS.
Ĝi ne jam estis konservita!'''",
'userjspreview' => "'''Memoru ke vi nun nur provas kaj antaŭrigardas vian uzantan javaskripton, ĝi ne estas jam konservita'''",
'note' => "'''Noto:'''",
'previewnote' => "'''Memoru, ke ĉi tio estas nur antaŭrigardo.'''
Viaj ŝanĝoj ne ankoraŭ estas konservitaj!",
-'continue-editing' => 'Redaktu plu',
+'continue-editing' => 'Iru al redakta spaco',
'previewconflict' => 'La jena antaŭrigardo montras la tekston el la supra tekstujo,
kiel ĝi aperos se vi elektos konservi la paĝon.',
'session_fail_preview' => "'''Ni ne povas procezi vian redakton pro perdo de seancaj datenoj.
'timezoneregion-indian' => 'Hinda Oceano',
'timezoneregion-pacific' => 'Pacifiko',
'allowemail' => 'Rajtigi retmesaĝojn de aliaj uzantoj',
-'prefs-searchoptions' => 'Serĉaj opcioj',
+'prefs-searchoptions' => 'Serĉu',
'prefs-namespaces' => 'Nomspacoj',
'defaultns' => 'Alimaniere, traserĉi la jenajn nomspacojn:',
'default' => 'defaŭlte',
'backend-fail-internal' => 'Nekonata eraro okazis en interna konservujo "$1".',
'backend-fail-contenttype' => 'Ne eblis determini la enhavo-tipo de la dosiero por konservi ĉe "$1".',
'backend-fail-batchsize' => 'Interna konservujo estis donita komandaron de $1 {{PLURAL:$1|dosiera operacio|dosieraj operacioj}}; la limo estas $2 {{PLURAL:$2|operacio|operacioj}}.',
-'backend-fail-usable' => 'Ne eblis skribi dosieron "$1" pro malsufiĉaj permesoj aŭ mankantaj dosierujoj.',
+'backend-fail-usable' => 'Ne eblis legi aŭ skribi dosieron "$1" pro malsufiĉaj permesoj aŭ mankantaj dosierujoj.',
# File journal errors
'filejournal-fail-dbconnect' => 'Ne eblis konekti la protokolan datumbazon por la ekstera konservujo "$1".',
# Info page
'pageinfo-title' => 'Informoj por "$1"',
+'pageinfo-not-current' => 'Informoj povas esti montritaj nur por la nuna versio',
'pageinfo-header-basic' => 'Baza informo',
'pageinfo-header-edits' => 'Historio de redaktoj',
'pageinfo-header-restrictions' => 'Protektado de la paĝo',
* '''Opera:''' vacía la caché en ''Herramientas → Preferencias''",
'usercssyoucanpreview' => "'''Consejo:''' Usa el botón «{{int:showpreview}}» para probar el nuevo CSS antes de guardarlo.",
'userjsyoucanpreview' => "'''Consejo:''' Usa el botón «{{int:showpreview}}» para probar el nuevo JS antes de guardarlo.",
-'usercsspreview' => "'''Recuerda que solo estás previsualizando tu CSS de usuario.'''
+'usercsspreview' => "'''Recuerda que sólo estás previsualizando tu CSS de usuario.'''
'''¡Aún no se ha guardado!'''",
'userjspreview' => "'''¡Recuerda que solo estás previsualizando tu JavaScript de usuario.'''
'''¡Aún no se ha guardado!'''",
'''¡Aún no se ha guardado!'''",
'sitejspreview' => "'''Recuerda que sólo estás previsualizando este código JavaScript.'''
'''¡Aún no se ha guardado!'''",
-'userinvalidcssjstitle' => "'''Aviso:''' No existe la skin «$1». Recuerda que las páginas personalizadas ''.css'' y ''.js'' tienen un título en minúsculas. Por ejemplo, {{ns:user}}:Ejemplo/vector.css en vez de {{ns:user}}:Ejemplo/Vector.css.",
+'userinvalidcssjstitle' => "'''Aviso:''' No existe la piel «$1». Recuerda que las páginas personalizadas ''.css'' y ''.js'' tienen un título en minúsculas. Por ejemplo, {{ns:user}}:Ejemplo/vector.css en vez de {{ns:user}}:Ejemplo/Vector.css.",
'updated' => '(Actualizado)',
'note' => "'''Nota:'''",
'previewnote' => "'''Recuerda que esto es solo una previsualización.'''
'page_first' => 'primeras',
'page_last' => 'últimas',
'histlegend' => "Selección de diferencias: marca los selectores de las versiones a comparar y pulsa ''enter'' o el botón de abajo.<br />
-Leyenda: (act) = diferencias con la versión actual,
-(prev) = diferencias con la versión previa, M = edición menor",
+Leyenda: '''(act)''' = diferencias con la versión actual,
+'''(ant)''' = diferencias con la versión anterior, '''m''' = edición menor",
'history-fieldset-title' => 'Buscar en el historial',
'history-show-deleted' => 'Solo ediciones ocultadas',
'histfirst' => 'Primeras',
'revdelete-text' => "Las revisiones borradas aún aparecerán en el historial de la página y en los registros, pero sus contenidos no serán accesibles al público.'''
Otros administradores de {{SITENAME}} aún podrán acceder al contenido oculto y podrán deshacer el borrado a través de la misma interfaz, a menos que se establezcan restricciones adicionales.",
'revdelete-confirm' => 'Por favor confirma que deseas realizar la operación, que entiendes las consecuencias y que estás ejecutando dicha acción acorde con [[{{MediaWiki:Policy-url}}|las políticas]].',
-'revdelete-suppress-text' => "La herramienta de supresión '''sólo''' debería usarse en los siguientes casos:
+'revdelete-suppress-text' => "La herramienta de supresión '''solo''' debería usarse en los siguientes casos:
* Información potencialmente injuriosa o calumniante.
* Información personal inapropiada, tal como:
*: ''nombres, domicilios, números de teléfono, números de la seguridad social e información análoga.",
'linksearch-ns' => 'Espacio de nombre:',
'linksearch-ok' => 'Buscar',
'linksearch-text' => 'Se pueden usar caracteres comodín como "*.wikipedia.org".
-Es necesario, por lo menos, un dominio de nivel, por ejemplo "*.org".<br />
-Protocolos soportados: <code>$1</code> (no añada ninguno de estos en su búsqueda).',
+Es necesario, por lo menos, un dominio de alto nivel, por ejemplo "*.org".<br />
+Protocolos soportados: <code>$1</code> (si no se especifica ninguno, el protocolo por defecto es http://).',
'linksearch-line' => '$1 enlazado desde $2',
'linksearch-error' => 'Los comodines sólo pueden aparecer al principio del nombre de sitio.',
# Contributions
'contributions' => 'Contribuciones {{GENDER:{{BASEPAGENAME}}|del usuario|de la usuaria}}',
'contributions-title' => 'Contribuciones {{GENDER:$1|del usuario|de la usuaria}} $1',
-'mycontris' => 'Mis contribuciones',
+'mycontris' => 'Contribuciones',
'contribsub2' => '$1 ($2)',
'nocontribs' => 'No se encontraron cambios que cumplieran estos criterios.',
'uctop' => '(última edición)',
'whatlinkshere-hideredirs' => '$1 redirecciones',
'whatlinkshere-hidetrans' => '$1 inclusiones',
'whatlinkshere-hidelinks' => '$1 enlaces',
-'whatlinkshere-hideimages' => '$1 enlaces a imágenes',
+'whatlinkshere-hideimages' => '$1 enlaces a archivos',
'whatlinkshere-filters' => 'Filtros',
# Block/unblock
'underline-always' => 'همیشه',
'underline-never' => 'هرگز',
-'underline-default' => 'پیشفرض مرورگر',
+'underline-default' => 'پوسته یا مرورگر پیشفرض',
# Font style option in Special:Preferences
'editfont-style' => 'سبک قلم جعبهٔ ویرایش:',
'newwindow' => '(در پنجرهٔ جدید باز میشود)',
'cancel' => 'لغو',
'moredotdotdot' => 'بیشتر...',
-'mypage' => 'صفحهٔ من',
-'mytalk' => 'بحث من',
+'mypage' => 'صفحه',
+'mytalk' => 'بحث',
'anontalk' => 'بحث برای این آیپی',
'navigation' => 'گشتن',
'and' => ' و',
'userpage-userdoesnotexist-view' => 'حساب کاربری «$1» ثبت نشدهاست.',
'blocked-notice-logextract' => 'دسترسی این کاربر در حال حاضر بسته است.
آخرین مورد سیاهه قطع دسترسی در زیر آمدهاست:',
-'clearyourcache' => "''نکته:''' پس از ذخیرهکردن ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.
+'clearyourcache' => "'''نکته:''' پس از ذخیرهکردن ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.
*'''فایرفاکس / سافاری:''' کلید ''Shift'' را نگه دارید و روی دکمهٔ ''Reload'' کلیک کنید، یا کلیدهای ''Ctrl-F5'' یا ''Ctrl-R'' را با هم فشار دهید (در رایانههای اپل مکینتاش کلیدهای ''⌘-R'')
*'''گوگل کروم:'''کلیدهای ''Ctrl+Shift+R'' را با هم فشار دهید. (در رایانههای اپل مکینتاش کلیدهای ''⌘-Shift-R'')
*'''اینترنت اکسپلورر:''' کلید ''Ctrl'' را نگهدارید و روی دکمهٔ ''Refresh'' کلیک کنید، یا کلیدهای ''Ctrl-F5'' را با هم فشار دهید
# Preferences page
'preferences' => 'ترجیحات',
-'mypreferences' => 'ترجیحات من',
+'mypreferences' => 'ترجیحات',
'prefs-edits' => 'تعداد ویرایشها:',
'prefsnologin' => 'به سامانه وارد نشدهاید',
'prefsnologintext' => 'برای تنظیم ترجیحات کاربر باید <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} به سامانه وارد شوید]</span>.',
'rightslogtext' => 'این سیاههٔ تغییرات اختیارات کاربر است.',
'rightslogentry' => 'عضویت $1 را از گروه $2 به $3 تغییر داد',
'rightslogentry-autopromote' => 'به طور خودکار از $2 به $3 ارتقا یافت',
+'logentry-rights-rights' => '$1 عضویت $3 را از گروه $4 به $5 تغییر داد',
+'logentry-rights-rights-legacy' => '$1 گروه عضویت $3 را تغییر داد',
+'logentry-rights-autopromote' => '$1به طور خودکار از $4 به $5 ارتقا یافت',
'rightsnone' => '(هیچ)',
# Associated actions - in the sentence "You do not have permission to X"
'linksearch-ok' => 'جستجو',
'linksearch-text' => 'نشانههایی مانند «*.wikipedia.org» را میتوان استفاده کرد.
حداقل یک دامنه سطح بالا ، به عنوان مثال "*.org" نیاز دارد.<br />
-پرÙ\88تکÙ\84â\80\8cÙ\87اÛ\8c پشتÛ\8cباÙ\86Û\8câ\80\8cشدÙ\87: <code>$1</code> (Ù\87Û\8cÚ\86 Û\8cÚ© از اÛ\8cÙ\86 Ù\85Ù\88ارد را در جستجÙ\88Û\8c Ø®Ù\88د Ù\86Û\8cاÙ\81زاÛ\8cÛ\8cد)',
+پرÙ\88تکÙ\84â\80\8cÙ\87اÛ\8c پشتÛ\8cباÙ\86Û\8câ\80\8cشدÙ\87: <code>$1</code> (Ù¾Û\8cØ´â\80\8cÙ\81رض براÛ\8c http:// در صÙ\88رت Ù\85شخص Ù\86شدÙ\86 پرÙ\88تکÙ\84 تÙ\86ظÛ\8cÙ\85 شدÙ\87â\80\8cاست)',
'linksearch-line' => '$1 از $2 پیوند دارد',
'linksearch-error' => 'نشانهها فقط در ابتدای نام میزبان اینترنتی میتوانند استفاده شوند.',
# Watchlist
'watchlist' => 'فهرست پیگیریهای من',
-'mywatchlist' => 'Ù¾Û\8câ\80\8cÚ¯Û\8cرÛ\8câ\80\8cÙ\87اÛ\8c Ù\85Ù\86',
+'mywatchlist' => 'Ù\81Ù\87رست Ù¾Û\8câ\80\8cÚ¯Û\8cرÛ\8câ\80\8cÙ\87ا',
'watchlistfor2' => 'برای $1 $2',
'nowatchlist' => 'در فهرست پیگیریهای شما هیچ موردی نیست.',
'watchlistanontext' => 'برای مشاهده و ویرایش فهرست پیگیریهای خود از $1 استفاده کنید.',
# Contributions
'contributions' => 'مشارکتهای کاربری',
'contributions-title' => 'مشارکتهای کاربری $1',
-'mycontris' => 'مشارکتهای من',
+'mycontris' => 'مشارکتها',
'contribsub2' => 'برای $1 ($2)',
'nocontribs' => 'هیچ تغییری با این مشخصات یافت نشد.',
'uctop' => ' (بالا)',
'whatlinkshere-hideredirs' => '$1 تغییرمسیر',
'whatlinkshere-hidetrans' => '$1 تراگنجانشها',
'whatlinkshere-hidelinks' => '$1 پیوند',
-'whatlinkshere-hideimages' => '$1 پیوند به تصویر',
+'whatlinkshere-hideimages' => '$1 پیوندهای پرونده',
'whatlinkshere-filters' => 'پالایهها',
# Block/unblock
# Info page
'pageinfo-title' => 'اطلاعات در مورد «$1»',
-'pageinfo-not-current' => 'اطلاعات ممکن است تنها برای نسخهٔ فعلی نمایش داده شود.',
+'pageinfo-not-current' => 'متاسفانه تهیه اطلاعات ویرایشهای قدیمی غیرممکن است.',
'pageinfo-header-basic' => 'اطلاعات اولیه',
'pageinfo-header-edits' => 'ویرایش تاریخچه',
'pageinfo-header-restrictions' => 'حفاظت از صفحه',
'version-license' => 'اجازهنامه',
'version-poweredby-credits' => "این ویکی توسط '''[//www.mediawiki.org/ مدیاویکی]''' پشتیبانی میشود، کلیهٔ حقوق محفوظ است © 2001-$1 $2.",
'version-poweredby-others' => 'دیگران',
+'version-credits-summary' => 'افراد زیر را به خاطر ویرایشهایش در [[Special:Version|مدیاویکی]] معرفی مینمائیم.',
'version-license-info' => 'مدیاویکی نرمافزاری رایگان است؛ میتوانید آن را تحت شرایط مجوز عمومی همگانی گنو که توسط بنیاد نرمافزار رایگان منتشر شدهاست، بازنشر کنید؛ یا نسخهٔ ۲ از این مجوز، یا (بنا به اختیار) نسخههای بعدی.
مدیاویکی به این امید که مفید واقع شود منتشر شدهاست، ولی بدون هیچگونه ضمانتی؛ بدون ضمانت ضمنی که تجاری یا برای کار خاصی مناسب باشد. برای اطلاعات بیشتر مجوز گنو جیپیال را مشاهده کنید.
'image_sample' => 'Esimerkki.jpg',
'image_tip' => 'Tallennettu tiedosto',
'media_sample' => 'Esimerkki.ogg',
-'media_tip' => 'Mediatiedostolinkki',
+'media_tip' => 'Tiedostolinkki',
'sig_tip' => 'Allekirjoitus aikamerkinnällä',
'hr_tip' => 'Vaakasuora viiva',
'rightslogtext' => 'Tämä on loki käyttäjien käyttöoikeuksien muutoksista.',
'rightslogentry' => 'muutti käyttäjän $1 oikeudet ryhmistä $2 ryhmiin $3',
'rightslogentry-autopromote' => 'muutettiin automaattisesti ryhmistä $2 ryhmiin $3',
+'logentry-rights-rights' => '$1 muutti käyttäjän $3 oikeudet ryhmistä $4 ryhmiin $5',
'rightsnone' => '(ei oikeuksia)',
# Associated actions - in the sentence "You do not have permission to X"
'linksearch-ok' => 'Etsi',
'linksearch-text' => 'Tähteä (*) voi käyttää jokerimerkkinä, esimerkiksi ”*.wikipedia.org”.
Vähintään ylätason verkkotunnus, esimerkiksi "*.org", tarvitaan.<br />
-Tuetut protokollat: <code>$1</code> (älä lisää näitä hakuusi).',
+Tuetut protokollat: <code>$1</code> (oletuksena on <code>http://</code>, jos protokollaa ei määritetä).',
'linksearch-line' => '$1 on linkitetty sivulta $2',
'linksearch-error' => 'Jokerimerkkiä voi käyttää ainoastaan osoitteen alussa.',
'underline-always' => 'Toujours',
'underline-never' => 'Jamais',
-'underline-default' => 'Valeur par défaut du navigateur',
+'underline-default' => 'Valeur par défaut du navigateur ou du thème',
# Font style option in Special:Preferences
'editfont-style' => 'Style de police de la zone de modification :',
'newwindow' => '(ouvre une nouvelle fenêtre)',
'cancel' => 'Annuler',
'moredotdotdot' => 'Plus...',
-'mypage' => 'Ma page',
-'mytalk' => 'Page de discussion',
+'mypage' => 'Page',
+'mytalk' => 'Discussion',
'anontalk' => 'Discussion avec cette adresse IP',
'navigation' => 'Navigation',
'and' => ' et',
'vector-simplesearch-preference' => "Activer la barre de recherche simplifiée (seulement pour l'habillage Vector)",
'vector-view-create' => 'Créer',
'vector-view-edit' => 'Modifier',
-'vector-view-history' => 'Afficher l’historique',
+'vector-view-history' => "Afficher l'historique",
'vector-view-view' => 'Lire',
'vector-view-viewsource' => 'Voir la source',
'actions' => 'Actions',
'imagepage' => 'Voir la page du fichier',
'mediawikipage' => 'Voir la page du message',
'templatepage' => 'Voir la page du modèle',
-'viewhelppage' => 'Voir la page d’aide',
+'viewhelppage' => "Voir la page d'aide",
'categorypage' => 'Voir la page de catégorie',
'viewtalkpage' => 'Page de discussion',
'otherlanguages' => 'Autres langues',
'jumpto' => 'Aller à :',
'jumptonavigation' => 'Navigation',
'jumptosearch' => 'rechercher',
-'view-pool-error' => 'Désolé, les serveurs sont surchargés en ce moment.
-Trop d’utilisateurs cherchent à consulter cette page.
-Veuillez attendre un moment avant de retenter l’accès à cette page.
+'view-pool-error' => "Désolé, les serveurs sont surchargés en ce moment.
+Trop d'utilisateurs cherchent à consulter cette page.
+Veuillez attendre un moment avant de retenter l'accès à cette page.
-$1',
-'pool-timeout' => 'Délai dépassé durant l’attente du verrou',
+$1",
+'pool-timeout' => "Délai dépassé durant l'attente du verrou",
'pool-queuefull' => 'La file de travail est pleine',
'pool-errorunknown' => 'Erreur inconnue',
'privacypage' => 'Project:Confidentialité',
'badaccess' => 'Erreur de permission',
-'badaccess-group0' => 'Vous n’avez pas les droits suffisants pour réaliser l’action demandée.',
-'badaccess-groups' => 'L’action que vous essayez de réaliser n’est accessible qu’aux utilisateurs {{PLURAL:$2|du groupe|des groupes}} : $1.',
+'badaccess-group0' => "Vous n'avez pas les droits suffisants pour réaliser l'action demandée.",
+'badaccess-groups' => "L'action que vous essayez de réaliser n'est accessible qu'aux utilisateurs {{PLURAL:$2|du groupe|des groupes}} : $1.",
'versionrequired' => 'Version $1 de MediaWiki nécessaire',
'versionrequiredtext' => 'La version $1 de MediaWiki est nécessaire pour utiliser cette page. Consultez [[Special:Version|la page des versions]]',
# Main script and global functions
'nosuchaction' => 'Action inconnue',
-'nosuchactiontext' => 'L’action spécifiée dans l’URL est invalide.
-Vous avez peut-être mal entré l’URL ou suivi un lien erroné.
-Il peut également s’agir d’un bogue dans le logiciel utilisé par {{SITENAME}}.',
+'nosuchactiontext' => "L'action spécifiée dans l'URL est invalide.
+Vous avez peut-être mal entré l'URL ou suivi un lien erroné.
+Il peut également s'agir d'un bug dans le logiciel utilisé par {{SITENAME}}.",
'nosuchspecialpage' => 'Page spéciale inexistante',
-'nospecialpagetext' => '<strong>Vous avez demandé une page spéciale qui n’existe pas.</strong>
+'nospecialpagetext' => "<strong>Vous avez demandé une page spéciale qui n'existe pas.</strong>
-Une liste des pages spéciales valides se trouve sur [[Special:SpecialPages|{{int:specialpages}}]].',
+Une liste des pages spéciales valides se trouve sur [[Special:SpecialPages|{{int:specialpages}}]].",
# General errors
'error' => 'Erreur',
'databaseerror' => 'Erreur de la base de données',
-'dberrortext' => 'Une erreur de syntaxe de la requête dans la base de données est survenue.
-Ceci peut indiquer un bogue dans le logiciel.
+'dberrortext' => "Une erreur de syntaxe de la requête dans la base de données est survenue.
+Ceci peut indiquer un bug dans le logiciel.
La dernière requête traitée par la base de données était :
<blockquote><code>$1</code></blockquote>
depuis la fonction « <code>$2</code> ».
-La base de données a renvoyé l’erreur « <samp>$3 : $4</samp> ».',
-'dberrortextcl' => 'Une requête dans la base de données comporte une erreur de syntaxe.
+La base de données a renvoyé l'erreur « <samp>$3 : $4</samp> ».",
+'dberrortextcl' => "Une requête dans la base de données comporte une erreur de syntaxe.
La dernière requête émise était :
« $1 »
dans la fonction « $2 ».
-La base de données a renvoyé l’erreur « $3 : $4 ».',
+La base de données a renvoyé l'erreur « $3 : $4 ».",
'laggedslavemode' => 'Attention, cette page peut ne pas contenir les toutes dernières modifications effectuées',
'readonly' => 'Base de données verrouillée',
-'enterlockreason' => 'Indiquez la raison du verrouillage ainsi qu’une estimation de sa durée',
-'readonlytext' => 'Les ajouts et mises à jour de la base de données sont actuellement bloqués, probablement pour permettre la maintenance de la base, après quoi, tout rentrera dans l’ordre.
+'enterlockreason' => "Indiquez la raison du verrouillage ainsi qu'une estimation de sa durée",
+'readonlytext' => "Les ajouts et mises à jour de la base de données sont actuellement bloqués, probablement pour permettre la maintenance de la base, après quoi, tout rentrera dans l'ordre.
-L’administrateur ayant verrouillé la base de données a fourni l’explication suivante :<br />$1',
-'missing-article' => "La base de données n’a pas trouvé le texte d'une page qu’elle aurait dû trouver, intitulée « $1 » $2.
+L'administrateur ayant verrouillé la base de données a fourni l'explication suivante :<br />$1",
+'missing-article' => "La base de données n'a pas trouvé le texte d'une page qu'elle aurait dû trouver, intitulée « $1 » $2.
-Généralement, cela survient en suivant un lien vers un diff périmé ou vers l’historique d'une page supprimée.
+Généralement, cela survient en suivant un lien vers un diff périmé ou vers l'historique d'une page supprimée.
-Si ce n’est pas le cas, il peut s’agir d'un bogue dans le programme.
-Veuillez le signaler à un [[Special:ListUsers/sysop|administrateur]] sans oublier de lui indiquer l’URL du lien.",
+Si ce n'est pas le cas, il peut s'agir d'un bug dans le programme.
+Veuillez le signaler à un [[Special:ListUsers/sysop|administrateur]] sans oublier de lui indiquer l'URL du lien.",
'missingarticle-rev' => '(numéro de version : $1)',
'missingarticle-diff' => '(diff : $1, $2)',
'readonly_lag' => 'La base de données a été automatiquement verrouillée pendant que les serveurs secondaires rattrapent leur retard sur le serveur principal.',
'internalerror' => 'Erreur interne',
'internalerror_info' => 'Erreur interne : $1',
-'fileappenderrorread' => 'Impossible de lire « $1 » lors de l’insertion',
-'fileappenderror' => 'Impossible d’ajouter « $1 » à « $2 ».',
+'fileappenderrorread' => "Impossible de lire « $1 » lors de l'insertion",
+'fileappenderror' => "Impossible d'ajouter « $1 » à « $2 ».",
'filecopyerror' => 'Impossible de copier le fichier « $1 » vers « $2 ».',
'filerenameerror' => 'Impossible de renommer le fichier « $1 » en « $2 ».',
'filedeleteerror' => 'Impossible de supprimer le fichier « $1 ».',
'directorycreateerror' => 'Impossible de créer le dossier « $1 ».',
'filenotfound' => 'Impossible de trouver le fichier « $1 ».',
-'fileexistserror' => 'Impossible d’écrire le fichier « $1 » : le fichier existe.',
+'fileexistserror' => "Impossible d'écrire le fichier « $1 » : le fichier existe.",
'unexpected' => 'Valeur inattendue : « $1 » = « $2 ».',
'formerror' => 'Erreur : Impossible de soumettre le formulaire.',
'badarticleerror' => 'Cette action ne peut pas être effectuée sur cette page.',
-'cannotdelete' => 'Impossible de supprimer la page ou le fichier « $1 ».
-La suppression a peut-être déjà été effectuée par quelqu’un d’autre.',
+'cannotdelete' => "Impossible de supprimer la page ou le fichier « $1 ».
+La suppression a peut-être déjà été effectuée par quelqu'un d'autre.",
'cannotdelete-title' => 'Impossible de supprimer la page « $1 »',
'delete-hook-aborted' => "Suppression annulée par une extension.
Aucune explication n'a été fournie.",
'badtitle' => 'Mauvais titre',
-'badtitletext' => 'Le titre de la page demandée est invalide, vide, ou il s’agit d’un titre inter-langue ou inter-projet mal lié. Il contient peut-être un ou plusieurs caractères qui ne peuvent pas être utilisés dans les titres.',
+'badtitletext' => "Le titre de la page demandée est invalide, vide, ou il s'agit d'un titre inter-langue ou inter-projet mal lié. Il contient peut-être un ou plusieurs caractères qui ne peuvent pas être utilisés dans les titres.",
'perfcached' => 'Les données suivantes sont en cache et peuvent ne pas être à jour. Un maximum de {{PLURAL:$1|un résultat|$1 résultats}} est disponible dans le cache.',
'perfcachedts' => 'Les données suivantes sont en cache et ont été mises à jour pour la dernière fois à $1. Un maximum de {{PLURAL:$4|un résultat|$4 résultats}} est disponible dans le cache.',
'querypage-no-updates' => 'Les mises à jour pour cette page sont actuellement désactivées. Les données ci-dessous ne sont pas mises à jour.',
'viewsource' => 'Voir le texte source',
'viewsource-title' => 'Voir la source de $1',
'actionthrottled' => 'Action limitée',
-'actionthrottledtext' => 'Pour lutter contre les pourriels, l’utilisation de cette action est limitée à un certain nombre de fois dans un laps de temps assez court. Il s’avère que vous avez dépassé cette limite.
-Essayez à nouveau dans quelques minutes.',
+'actionthrottledtext' => "Pour lutter contre le spam, l'utilisation de cette action est limitée à un certain nombre de fois dans un laps de temps assez court. Il s'avère que vous avez dépassé cette limite.
+Essayez à nouveau dans quelques minutes.",
'protectedpagetext' => 'Cette page a été protégée pour empêcher sa modification.',
'viewsourcetext' => 'Vous pouvez voir et copier le contenu de la page :',
'viewyourtext' => "Vous pouvez voir et copier le contenu de '''vos modifications''' à cette page :",
-'protectedinterface' => 'Cette page fournit du texte d’interface pour le logiciel sur ce wiki, et est protégée pour éviter les abus.
-Pour ajouter ou modifier des traductions sur tous les wikis, veuillez utiliser [//translatewiki.net/ translatewiki.net], le projet de localisation de MediaWiki.',
-'editinginterface' => "'''Attention''': Vous êtes en train de modifier une page utilisée pour créer le texte de l’interface du logiciel. Les changements sur cette page se répercuteront dur l'apparence de l'interface utilisateur pour les autres utilisateurs de ce wiki.
-Pour ajouter ou modifier des traductions pour tous les wikis, veuillez utiliser [//translatewiki.net/ translatewiki.net], le projet d’internationalisation de MediaWiki.",
+'protectedinterface' => "Cette page fournit du texte d'interface pour le logiciel sur ce wiki, et est protégée pour éviter les abus.
+Pour ajouter ou modifier des traductions sur tous les wikis, veuillez utiliser [//translatewiki.net/ translatewiki.net], le projet de localisation de MediaWiki.",
+'editinginterface' => "'''Attention''': Vous êtes en train de modifier une page utilisée pour créer le texte de l'interface du logiciel. Les changements sur cette page se répercuteront dur l'apparence de l'interface utilisateur pour les autres utilisateurs de ce wiki.
+Pour ajouter ou modifier des traductions pour tous les wikis, veuillez utiliser [//translatewiki.net/ translatewiki.net], le projet d'internationalisation de MediaWiki.",
'sqlhidden' => '(Requête SQL cachée)',
-'cascadeprotected' => 'Cette page est protégée car elle est incluse par {{PLURAL:$1|la page suivante, qui a été protégée|les pages suivantes, qui ont été protégées}} avec l’option « protection en cascade » activée :
-$2',
-'namespaceprotected' => "Vous n’avez pas la permission de modifier les pages de l’espace de noms « '''$1''' ».",
-'customcssprotected' => 'Vous n’avez pas la permission de modifier cette page de CSS, car elle contient les paramètres personnels d’un autre utilisateur.',
-'customjsprotected' => 'Vous n’avez pas la permission de modifier cette page de JavaScript, car elle contient les paramètres personnels d’un autre utilisateur.',
-'ns-specialprotected' => 'Les pages dans l’espace de noms « {{ns:special}} » ne peuvent pas être modifiées.',
+'cascadeprotected' => "Cette page est protégée car elle est incluse par {{PLURAL:$1|la page suivante, qui a été protégée|les pages suivantes, qui ont été protégées}} avec l'option « protection en cascade » activée :
+$2",
+'namespaceprotected' => "Vous n'avez pas la permission de modifier les pages de l'espace de noms « '''$1''' ».",
+'customcssprotected' => "Vous n'avez pas la permission de modifier cette page de CSS, car elle contient les paramètres personnels d'un autre utilisateur.",
+'customjsprotected' => "Vous n'avez pas la permission de modifier cette page de JavaScript, car elle contient les paramètres personnels d'un autre utilisateur.",
+'ns-specialprotected' => "Les pages dans l'espace de noms « {{ns:special}} » ne peuvent pas être modifiées.",
'titleprotected' => "Ce titre a été protégé à la création par [[User:$1|$1]].
Le motif avancé est « ''$2'' ».",
-'filereadonlyerror' => 'Impossible de modifier le fichier « $1 » parce que le répertoire de fichiers « $2 » est en lecture seule.
+'filereadonlyerror' => "Impossible de modifier le fichier « $1 » parce que le répertoire de fichiers « $2 » est en lecture seule.
-L’administrateur qui l’a verrouillé a fourni ce motif: « $3 ».',
-'invalidtitle-knownnamespace' => 'Titre invalide avec l’espace de noms « $2 » et l’intitulé « $3 »',
-'invalidtitle-unknownnamespace' => 'Titre invalide avec le numéro d’espace de noms $1 et l’intitulé « $2 » inconnus',
+L'administrateur qui l'a verrouillé a fourni ce motif: « $3 ».",
+'invalidtitle-knownnamespace' => "Titre invalide avec l'espace de noms « $2 » et l'intitulé « $3 »",
+'invalidtitle-unknownnamespace' => "Titre invalide avec le numéro d'espace de noms $1 et l'intitulé « $2 » inconnus",
'exception-nologin' => 'Non connecté',
'exception-nologin-text' => "Cette page ou cette action nécessite d'être connecté sur ce wiki.",
'logouttext' => "'''Vous êtes à présent déconnecté(e).'''
Vous pouvez continuer à utiliser {{SITENAME}} de façon anonyme, <span class='plainlinks'>[$1 vous reconnecter]</span> sous le même nom ou un autre.
-Notez que certaines pages peuvent être encore affichées comme si vous étiez toujours connecté(e), jusqu’à ce que vous effaciez le cache de votre navigateur.",
-'welcomecreation' => '== Bienvenue, $1 ! ==
+Notez que certaines pages peuvent être encore affichées comme si vous étiez toujours connecté(e), jusqu'à ce que vous effaciez le cache de votre navigateur.",
+'welcomecreation' => "== Bienvenue, $1 ! ==
Votre compte a été créé.
-N’oubliez pas de personnaliser vos [[Special:Preferences|préférences sur {{SITENAME}}]].',
-'yourname' => 'Nom d’utilisateur :',
+N'oubliez pas de personnaliser vos [[Special:Preferences|préférences sur {{SITENAME}}]].",
+'yourname' => "Nom d'utilisateur :",
'yourpassword' => 'Mot de passe :',
'yourpasswordagain' => 'Confirmez le mot de passe :',
'remembermypassword' => 'Me reconnecter automatiquement aux prochaines visites avec ce navigateur (au maximum $1 {{PLURAL:$1|jour|jours}})',
'securelogin-stick-https' => 'Rester connecté en HTTPS après la connexion',
'yourdomainname' => 'Votre domaine :',
'password-change-forbidden' => 'Vous ne pouvez pas modifier les mots de passe sur ce wiki.',
-'externaldberror' => 'Une erreur s’est produite avec la base de données d’authentification externe, ou bien vous n’êtes pas autorisé{{GENDER:||e|(e)}} à mettre à jour votre compte externe.',
+'externaldberror' => "Une erreur s'est produite avec la base de données d'authentification externe, ou bien vous n'êtes pas autorisé{{GENDER:||e|(e)}} à mettre à jour votre compte externe.",
'login' => 'Connexion',
'nav-login-createaccount' => 'Créer un compte ou se connecter',
-'loginprompt' => "Vous devez activer les témoins (''cookies'') pour vous connecter à {{SITENAME}}.",
+'loginprompt' => 'Vous devez activer les cookies pour vous connecter à {{SITENAME}}.',
'userlogin' => 'Créer un compte ou se connecter',
'userloginnocreate' => 'Connexion',
'logout' => 'Se déconnecter',
'userlogout' => 'Déconnexion',
'notloggedin' => 'Non connecté',
-'nologin' => 'Vous n’êtes pas encore inscrit ? $1.',
+'nologin' => "Vous n'êtes pas encore inscrit ? $1.",
'nologinlink' => 'Créer un compte',
'createaccount' => 'Créer un compte',
'gotaccount' => "Vous avez déjà un compte ? '''$1'''.",
'createaccountmail' => 'par courriel',
'createaccountreason' => 'Motif :',
'badretype' => 'Les mots de passe que vous avez saisis ne correspondent pas.',
-'userexists' => 'Nom d’utilisateur entré déjà utilisé.
-Veuillez choisir un nom différent.',
+'userexists' => "Nom d'utilisateur entré déjà utilisé.
+Veuillez choisir un nom différent.",
'loginerror' => 'Erreur de connexion',
'createaccounterror' => 'Impossible de créer le compte : $1',
-'nocookiesnew' => "Le compte utilisateur a été créé, mais vous n’êtes pas connecté{{GENDER:||e|(e)}}. {{SITENAME}} utilise des témoins (''cookies'') pour la connexion mais vous les avez désactivés. Veuillez les activer et vous reconnecter avec le même nom et le même mot de passe.",
-'nocookieslogin' => "{{SITENAME}} utilise des témoins (''cookies'') pour la connexion mais vous les avez désactivés. Veuillez les activer et vous reconnecter.",
-'nocookiesfornew' => 'Le compte utilisateur n’a pas été créé, car nous n’avons pas pu identifier son origine.
-Vérifiez que vous avez activé les cookies, rechargez la page et réessayez.',
-'noname' => 'Vous n’avez pas saisi un nom d’utilisateur valide.',
+'nocookiesnew' => "Le compte utilisateur a été créé, mais vous n'êtes pas connecté{{GENDER:||e|(e)}}. {{SITENAME}} utilise des cookies pour la connexion mais vous les avez désactivés. Veuillez les activer et vous reconnecter avec le même nom et le même mot de passe.",
+'nocookieslogin' => '{{SITENAME}} utilise des cookies pour la connexion mais vous les avez désactivés. Veuillez les activer et vous reconnecter.',
+'nocookiesfornew' => "Le compte utilisateur n'a pas été créé, car nous n'avons pas pu identifier son origine.
+Vérifiez que vous avez activé les cookies, rechargez la page et réessayez.",
+'noname' => "Vous n'avez pas saisi un nom d'utilisateur valide.",
'loginsuccesstitle' => 'Connexion réussie',
'loginsuccess' => 'Vous êtes maintenant connecté{{GENDER:$1||e|(e)}} à {{SITENAME}} en tant que « $1 ».',
-'nosuchuser' => 'L’utilisateur « $1 » n’existe pas.
-Les noms d’utilisateurs sont sensibles à la casse.
-Vérifiez l’orthographe, ou [[Special:UserLogin/signup|créez un nouveau compte]].',
-'nosuchusershort' => 'Il n’y a pas de contributeur avec le nom « $1 ». Veuillez vérifier l’orthographe.',
-'nouserspecified' => 'Vous devez saisir un nom d’utilisateur.',
+'nosuchuser' => "L'utilisateur « $1 » n'existe pas.
+Les noms d'utilisateurs sont sensibles à la casse.
+Vérifiez l'orthographe, ou [[Special:UserLogin/signup|créez un nouveau compte]].",
+'nosuchusershort' => "Il n'y a pas de contributeur avec le nom « $1 ». Veuillez vérifier l'orthographe.",
+'nouserspecified' => "Vous devez saisir un nom d'utilisateur.",
'login-userblocked' => 'Cet utilisateur est bloqué. Connexion non autorisée.',
'wrongpassword' => 'Le mot de passe est incorrect. Veuillez essayer à nouveau.',
-'wrongpasswordempty' => 'Vous n’avez pas entré de mot de passe. Veuillez essayer à nouveau.',
+'wrongpasswordempty' => "Vous n'avez pas entré de mot de passe. Veuillez essayer à nouveau.",
'passwordtooshort' => 'Votre mot de passe doit contenir au moins $1 caractère{{PLURAL:$1||s}}.',
-'password-name-match' => 'Votre mot de passe doit être différent de votre nom d’utilisateur.',
-'password-login-forbidden' => "L’utilisation de ce nom d'utilisateur et de ce mot de passe a été interdite.",
+'password-name-match' => "Votre mot de passe doit être différent de votre nom d'utilisateur.",
+'password-login-forbidden' => "L'utilisation de ce nom d'utilisateur et de ce mot de passe a été interdite.",
'mailmypassword' => 'Recevoir un nouveau mot de passe par courriel',
'passwordremindertitle' => 'Nouveau mot de passe temporaire pour {{SITENAME}}',
-'passwordremindertext' => 'Quelqu’un (probablement vous, ayant l’adresse IP $1) a demandé un nouveau mot de
+'passwordremindertext' => "Quelqu'un (probablement vous, ayant l'adresse IP $1) a demandé un nouveau mot de
passe pour {{SITENAME}} ($4 ). Un mot de passe temporaire a été créé pour
-l’utilisateur « $2 » et est « $3 ». Si cela était votre intention, vous devrez
+l'utilisateur « $2 » et est « $3 ». Si cela était votre intention, vous devrez
vous connecter et choisir un nouveau mot de passe.
Votre mot de passe temporaire expirera dans $5 jour{{PLURAL:$5||s}}.
-Si vous n’êtes pas l’auteur de cette demande, ou si vous vous souvenez à présent
+Si vous n'êtes pas l'auteur de cette demande, ou si vous vous souvenez à présent
de votre ancien mot de passe et que vous ne souhaitez plus en changer, vous
-pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.',
-'noemail' => "Aucune adresse de courriel n’a été enregistrée pour l'utilisateur « $1 ».",
+pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.",
+'noemail' => "Aucune adresse de courriel n'a été enregistrée pour l'utilisateur « $1 ».",
'noemailcreate' => 'Vous devez fournir une adresse de courriel valide',
'passwordsent' => "Un nouveau mot de passe a été envoyé à l'adresse de courriel de l'utilisateur « $1 ». Veuillez vous reconnecter après l'avoir reçu.",
'blocked-mailpassword' => 'Votre adresse IP est bloquée en écriture, la fonction de rappel du mot de passe est donc désactivée pour éviter les abus.',
-'eauthentsent' => 'Un courriel de confirmation a été envoyé à l’adresse indiquée.
-Avant qu’un autre courriel ne soit envoyé à ce compte, vous devrez suivre les instructions du courriel et confirmer que le compte est bien le vôtre.',
-'throttled-mailpassword' => 'Un courriel de rappel de votre mot de passe a déjà été envoyé durant {{PLURAL:$1|la dernière heure|les $1 dernières heures}}. Afin d’éviter les abus, un seul courriel de rappel sera envoyé par {{PLURAL:$1|heure|intervalle de $1 heures}}.',
-'mailerror' => 'Erreur lors de l’envoi du courriel : $1',
-'acct_creation_throttle_hit' => 'Quelqu’un utilisant votre adresse IP a créé {{PLURAL:$1|un compte|$1 comptes}} au cours des dernières 24 heures, ce qui constitue la limite autorisée dans cet intervalle de temps.
-Par conséquent, la création de compte a été temporairement désactivée pour cette adresse IP.',
+'eauthentsent' => "Un courriel de confirmation a été envoyé à l'adresse indiquée.
+Avant qu'un autre courriel ne soit envoyé à ce compte, vous devrez suivre les instructions du courriel et confirmer que le compte est bien le vôtre.",
+'throttled-mailpassword' => "Un courriel de rappel de votre mot de passe a déjà été envoyé durant {{PLURAL:$1|la dernière heure|les $1 dernières heures}}. Afin d'éviter les abus, un seul courriel de rappel sera envoyé par {{PLURAL:$1|heure|intervalle de $1 heures}}.",
+'mailerror' => "Erreur lors de l'envoi du courriel : $1",
+'acct_creation_throttle_hit' => "Quelqu'un utilisant votre adresse IP a créé {{PLURAL:$1|un compte|$1 comptes}} au cours des dernières 24 heures, ce qui constitue la limite autorisée dans cet intervalle de temps.
+Par conséquent, la création de compte a été temporairement désactivée pour cette adresse IP.",
'emailauthenticated' => 'Votre adresse de courriel a été authentifiée le $2 à $3.',
-'emailnotauthenticated' => 'Votre adresse de courriel n’est <strong>pas encore authentifiée</strong>. Aucun courriel ne sera envoyé pour chacune des fonctions suivantes.',
+'emailnotauthenticated' => "Votre adresse de courriel n'est <strong>pas encore authentifiée</strong>. Aucun courriel ne sera envoyé pour chacune des fonctions suivantes.",
'noemailprefs' => 'Indiquez une adresse de courriel dans vos préférences pour utiliser ces fonctions.',
'emailconfirmlink' => 'Confirmez votre adresse de courriel',
'invalidemailaddress' => 'Cette adresse courriel ne peut pas être acceptée car elle semble avoir un format incorrect.
'emaildisabled' => 'Ce site ne peut pas envoyer de courriels.',
'accountcreated' => 'Compte créé',
'accountcreatedtext' => 'Le compte utilisateur pour $1 a été créé.',
-'createaccount-title' => 'Création d’un compte pour {{SITENAME}}',
-'createaccount-text' => 'Quelqu’un a créé un compte pour votre adresse de courriel sur {{SITENAME}} ($4) intitulé « $2 », avec le mot de passe « $3 ».
+'createaccount-title' => "Création d'un compte pour {{SITENAME}}",
+'createaccount-text' => "Quelqu'un a créé un compte pour votre adresse de courriel sur {{SITENAME}} ($4) intitulé « $2 », avec le mot de passe « $3 ».
Vous devriez ouvrir une session et modifier dès à présent votre mot de passe.
-Ignorez ce message si ce compte a été créé par erreur.',
-'usernamehasherror' => 'Le nom d’utilisateur ne peut pas contenir des caractères de hachage',
-'login-throttled' => 'Vous avez tenté un trop grand nombre de connexions dernièrement.
-Veuillez attendre avant d’essayer à nouveau.',
+Ignorez ce message si ce compte a été créé par erreur.",
+'usernamehasherror' => "Le nom d'utilisateur ne peut pas contenir des caractères de hachage",
+'login-throttled' => "Vous avez tenté un trop grand nombre de connexions dernièrement.
+Veuillez attendre avant d'essayer à nouveau.",
'login-abort-generic' => 'Votre tentative de connexion a échoué',
'loginlanguagelabel' => 'Langue : $1',
-'suspicious-userlogout' => 'Votre demande de déconnexion a été refusée car il semble qu’elle a été envoyée par un navigateur cassé ou la mise en cache d’un proxy.',
+'suspicious-userlogout' => "Votre demande de déconnexion a été refusée car il semble qu'elle a été envoyée par un navigateur cassé ou la mise en cache d'un proxy.",
# E-mail sending
'php-mail-error-unknown' => 'Erreur inconnue dans la fonction mail() de PHP.',
-'user-mail-no-addy' => 'Tenté d’envoyer un courriel sans adresse de courriel',
+'user-mail-no-addy' => "Tenté d'envoyer un courriel sans adresse de courriel",
# Change password dialog
'resetpass' => 'Changer de mot de passe',
-'resetpass_announce' => 'Vous vous êtes enregistré{{GENDER:||e|(e)}} avec un mot de passe temporaire envoyé par courriel. Pour terminer l’enregistrement, vous devez entrer un nouveau mot de passe ici :',
+'resetpass_announce' => "Vous vous êtes enregistré{{GENDER:||e|(e)}} avec un mot de passe temporaire envoyé par courriel. Pour terminer l'enregistrement, vous devez entrer un nouveau mot de passe ici :",
'resetpass_text' => '<!-- Ajoutez le texte ici -->',
'resetpass_header' => 'Changer le mot de passe du compte',
'oldpassword' => 'Ancien mot de passe :',
'passwordreset-legend' => 'Remise à zéro du mot de passe',
'passwordreset-disabled' => 'La réinitialisation des mots de passe a été désactivée sur ce wiki.',
'passwordreset-pretext' => '{{PLURAL:$1||Entrez un élément de données ci-dessous}}',
-'passwordreset-username' => 'Nom d’utilisateur :',
+'passwordreset-username' => "Nom d'utilisateur :",
'passwordreset-domain' => 'Domaine :',
'passwordreset-capture' => 'Voir le courriel résultant?',
-'passwordreset-capture-help' => 'Si vous cochez cette case, le courriel (avec le mot de passe temporaire) vous sera affiché en même temps qu’il sera envoyé à l’utilisateur.',
+'passwordreset-capture-help' => "Si vous cochez cette case, le courriel (avec le mot de passe temporaire) vous sera affiché en même temps qu'il sera envoyé à l'utilisateur.",
'passwordreset-email' => 'Adresse de courriel :',
'passwordreset-emailtitle' => 'Détails du compte sur {{SITENAME}}',
-'passwordreset-emailtext-ip' => 'Quelqu’un (probablement vous, depuis l’adresse IP $1) a demandé un rappel des informations de votre compte pour {{SITENAME}} ($4). {{PLURAL:$3|Le compte utilisateur suivant est associé|Les comptes utilisateurs suivants sont associés}} à cette adresse de courriel :
+'passwordreset-emailtext-ip' => "Quelqu'un (probablement vous, depuis l'adresse IP $1) a demandé un rappel des informations de votre compte pour {{SITENAME}} ($4). {{PLURAL:$3|Le compte utilisateur suivant est associé|Les comptes utilisateurs suivants sont associés}} à cette adresse de courriel :
$2
-{{PLURAL:$3|Ce mot de passe temporaire expirera|Ces mots de passe temporaires expireront}} dans {{PLURAL:$5|un jour|$5 jours}}. Vous devez maintenant vous connecter et choisir un nouveau mot de passe. Si cette demande ne provient pas de vous, ou que vous vous êtes souvenu de votre mot de passe initial, et ne souhaitez plus le modifier, vous pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.',
-'passwordreset-emailtext-user' => 'L’utilisateur $1 sur {{SITENAME}} a demandé un rappel des informations de votre compte pour {{SITENAME}} ($4). {{PLURAL:$3|Le compte utilisateur suivant est associé|Les comptes utilisateurs suivants sont associés}} à cette adresse de courriel :
+{{PLURAL:$3|Ce mot de passe temporaire expirera|Ces mots de passe temporaires expireront}} dans {{PLURAL:$5|un jour|$5 jours}}. Vous devez maintenant vous connecter et choisir un nouveau mot de passe. Si cette demande ne provient pas de vous, ou que vous vous êtes souvenu de votre mot de passe initial, et ne souhaitez plus le modifier, vous pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.",
+'passwordreset-emailtext-user' => "L'utilisateur $1 sur {{SITENAME}} a demandé un rappel des informations de votre compte pour {{SITENAME}} ($4). {{PLURAL:$3|Le compte utilisateur suivant est associé|Les comptes utilisateurs suivants sont associés}} à cette adresse de courriel :
$2
-{{PLURAL:$3|Ce mot de passe temporaire expirera|Ces mots de passe temporaires expireront}} dans {{PLURAL:$5|un jour|$5 jours}}. Vous devez maintenant vous connecter et choisir un nouveau mot de passe. Si cette demande ne provient pas de vous, ou que vous vous êtes souvenu de votre mot de passe initial, et ne souhaitez plus le modifier, vous pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.',
-'passwordreset-emailelement' => 'Nom d’utilisateur : $1
-Mot de passe temporaire : $2',
+{{PLURAL:$3|Ce mot de passe temporaire expirera|Ces mots de passe temporaires expireront}} dans {{PLURAL:$5|un jour|$5 jours}}. Vous devez maintenant vous connecter et choisir un nouveau mot de passe. Si cette demande ne provient pas de vous, ou que vous vous êtes souvenu de votre mot de passe initial, et ne souhaitez plus le modifier, vous pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.",
+'passwordreset-emailelement' => "Nom d'utilisateur : $1
+Mot de passe temporaire : $2",
'passwordreset-emailsent' => 'Un courriel de rappel a été envoyé.',
'passwordreset-emailsent-capture' => 'Un courriel de rappel a été envoyé, qui est affiché ci-dessous.',
-'passwordreset-emailerror-capture' => 'Un courriel de rappel a été généré, qui est affiché ci-dessous, mais l’envoi à l’utilisateur a échoué : $1',
+'passwordreset-emailerror-capture' => "Un courriel de rappel a été généré, qui est affiché ci-dessous, mais l'envoi à l'utilisateur a échoué : $1",
# Special:ChangeEmail
-'changeemail' => 'Changer l’adresse de courriel',
-'changeemail-header' => 'Changer l’adresse de courriel du compte',
+'changeemail' => "Changer l'adresse de courriel",
+'changeemail-header' => "Changer l'adresse de courriel du compte",
'changeemail-text' => 'Remplissez ce formulaire pour changer votre adresse de courriel. Vous devrez entrer votre mot de passe pour confirmer ce changement.',
'changeemail-no-info' => 'Vous devez être connecté pour pouvoir accéder directement à cette page.',
'changeemail-oldemail' => 'Adresse de courriel actuelle :',
'changeemail-newemail' => 'Nouvelle adresse de courriel :',
'changeemail-none' => '(aucune)',
-'changeemail-submit' => 'Changer l’adresse de courriel',
+'changeemail-submit' => "Changer l'adresse de courriel",
'changeemail-cancel' => 'Annuler',
# Edit page toolbar
'link_sample' => 'Titre du lien',
'link_tip' => 'Lien interne',
'extlink_sample' => 'http://www.example.com titre du lien',
-'extlink_tip' => 'Lien externe (n’oubliez pas le préfixe http://)',
+'extlink_tip' => "Lien externe (n'oubliez pas le préfixe http://)",
'headline_sample' => 'Texte du titre',
'headline_tip' => 'Sous-titre niveau 2',
'nowiki_sample' => 'Entrez le texte non formaté ici',
'showpreview' => 'Prévisualiser',
'showlivepreview' => 'Aperçu rapide',
'showdiff' => 'Modifications en cours',
-'anoneditwarning' => "'''Attention :''' vous n’êtes pas identifié(e). Votre adresse IP sera enregistrée dans l’historique de cette page.",
-'anonpreviewwarning' => "''Vous n’êtes pas identifié. Sauvegarder enregistrera votre adresse IP dans l’historique des modifications de la page.''",
-'missingsummary' => "'''Rappel :''' vous n’avez pas encore fourni le résumé de votre modification.
+'anoneditwarning' => "'''Attention :''' vous n'êtes pas identifié(e). Votre adresse IP sera enregistrée dans l'historique de cette page.",
+'anonpreviewwarning' => "''Vous n'êtes pas identifié. Sauvegarder enregistrera votre adresse IP dans l'historique des modifications de la page.''",
+'missingsummary' => "'''Rappel :''' vous n'avez pas encore fourni le résumé de votre modification.
Si vous cliquez de nouveau sur le bouton « {{int:savearticle}} », la publication sera faite sans nouvel avertissement.",
'missingcommenttext' => 'Veuillez entrer un commentaire ci-dessous.',
-'missingcommentheader' => "'''Rappel :''' vous n’avez pas fourni de sujet ou de titre à ce commentaire.
+'missingcommentheader' => "'''Rappel :''' vous n'avez pas fourni de sujet ou de titre à ce commentaire.
Si vous cliquez de nouveau sur « {{int:Savearticle}} », votre modification sera enregistrée sans titre.",
'summary-preview' => 'Aperçu du résumé :',
'subject-preview' => 'Prévisualisation du sujet/titre :',
-'blockedtitle' => 'L’utilisateur est bloqué.',
+'blockedtitle' => "L'utilisateur est bloqué.",
'blockedtext' => "'''Votre compte utilisateur ou votre adresse IP a été bloqué.'''
Le blocage a été effectué par $1.
* Compte bloqué : $7.
Vous pouvez contacter $1 ou un autre [[{{MediaWiki:Grouppage-sysop}}|administrateur]] pour en discuter.
-Vous ne pouvez utiliser la fonction « {{MediaWiki:emailpage}} » que si une adresse de courriel valide est spécifiée dans vos [[Special:Preferences|préférences]] et que cette fonctionnalité n’a pas été bloquée.
+Vous ne pouvez utiliser la fonction « {{MediaWiki:emailpage}} » que si une adresse de courriel valide est spécifiée dans vos [[Special:Preferences|préférences]] et que cette fonctionnalité n'a pas été bloquée.
Votre adresse IP actuelle est $3 et votre identifiant de blocage est $5.
Veuillez préciser ces indications dans toutes les requêtes que vous ferez.",
'autoblockedtext' => "Votre adresse IP a été bloquée automatiquement car elle a été utilisée par un autre utilisateur, lui-même bloqué par $1.
* Expiration du blocage : $6
* Compte bloqué : $7
-Vous pouvez contacter $1 ou l’un des autres [[{{MediaWiki:Grouppage-sysop}}|administrateurs]] pour discuter de ce blocage.
+Vous pouvez contacter $1 ou l'un des autres [[{{MediaWiki:Grouppage-sysop}}|administrateurs]] pour discuter de ce blocage.
-Notez que vous ne pourrez utiliser la fonctionnalité d’envoi de courriel que si vous avez une adresse de courriel validée dans vos [[Special:Preferences|préférences]] et que la fonctionnalité n’a pas été désactivée.
+Notez que vous ne pourrez utiliser la fonctionnalité d'envoi de courriel que si vous avez une adresse de courriel validée dans vos [[Special:Preferences|préférences]] et que la fonctionnalité n'a pas été désactivée.
Votre adresse IP actuelle est $3, et le numéro de blocage est $5.
Veuillez préciser ces indications dans toutes les requêtes que vous ferez.",
'confirmedittext' => 'Vous devez confirmer votre adresse de courriel avant de modifier les pages.
Veuillez entrer et valider votre adresse de courriel dans vos [[Special:Preferences|préférences]].',
'nosuchsectiontitle' => 'Impossible de trouver la section',
-'nosuchsectiontext' => 'Vous avez essayé de modifier une section qui n’existe pas.
-Elle a peut-être été déplacée ou supprimée depuis que vous avez lu cette page.',
+'nosuchsectiontext' => "Vous avez essayé de modifier une section qui n'existe pas.
+Elle a peut-être été déplacée ou supprimée depuis que vous avez lu cette page.",
'loginreqtitle' => 'Connexion nécessaire',
'loginreqlink' => 'connecter',
'loginreqpagetext' => 'Vous devez vous $1 pour voir les autres pages.',
'accmailtitle' => 'Mot de passe envoyé.',
'accmailtext' => "Un mot de passe généré aléatoirement pour [[User talk:$1|$1]] a été envoyé à $2.
-Le mot de passe pour ce nouveau compte peut être changé sur la page ''[[Special:ChangePassword|de changement de mot de passe]]'' après s’être connecté.",
+Le mot de passe pour ce nouveau compte peut être changé sur la page ''[[Special:ChangePassword|de changement de mot de passe]]'' après s'être connecté.",
'newarticle' => '(Nouveau)',
-'newarticletext' => "Vous avez suivi un lien vers une page qui n’existe pas encore ou qui a été [{{fullurl:Special:Log|type=delete&page={{FULLPAGENAMEE}}}} effacée].
-Pour créer cette page, entrez votre texte dans la boîte ci-dessous (vous pouvez consulter [[{{MediaWiki:Helppage}}|la page d’aide]] pour plus d’informations).
+'newarticletext' => "Vous avez suivi un lien vers une page qui n'existe pas encore ou qui a été [{{fullurl:Special:Log|type=delete&page={{FULLPAGENAMEE}}}} effacée].
+Pour créer cette page, entrez votre texte dans la boîte ci-dessous (vous pouvez consulter [[{{MediaWiki:Helppage}}|la page d'aide]] pour plus d'informations).
Si vous êtes arrivé{{GENDER:||e|(e)}} ici par erreur, cliquez sur le bouton '''retour''' de votre navigateur.",
-'anontalkpagetext' => "---- ''Vous êtes sur la page de discussion d’un utilisateur anonyme qui n’a pas encore créé de compte ou qui n’en utilise pas. Pour cette raison, nous devons utiliser son adresse IP pour l’identifier. Une adresse IP peut être partagée par plusieurs utilisateurs. Si vous êtes un{{GENDER:||e|}} utilisat{{GENDER:|eur|rice|eur}} anonyme et si vous constatez que des commentaires qui ne vous concernent pas vous ont été adressés, vous pouvez [[Special:UserLogin/signup|créer un compte]] ou [[Special:UserLogin|vous connecter]] afin d’éviter toute confusion future avec d’autres contributeurs anonymes.''",
-'noarticletext' => 'Il n’y a pour l’instant aucun texte sur cette page.
+'anontalkpagetext' => "---- ''Vous êtes sur la page de discussion d'un utilisateur anonyme qui n'a pas encore créé de compte ou qui n'en utilise pas. Pour cette raison, nous devons utiliser son adresse IP pour l'identifier. Une adresse IP peut être partagée par plusieurs utilisateurs. Si vous êtes un{{GENDER:||e|}} utilisat{{GENDER:|eur|rice|eur}} anonyme et si vous constatez que des commentaires qui ne vous concernent pas vous ont été adressés, vous pouvez [[Special:UserLogin/signup|créer un compte]] ou [[Special:UserLogin|vous connecter]] afin d'éviter toute confusion future avec d'autres contributeurs anonymes.''",
+'noarticletext' => 'Il n\'y a pour l\'instant aucun texte sur cette page.
Vous pouvez [[Special:Search/{{PAGENAME}}|lancer une recherche sur ce titre]] dans les autres pages,
<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} rechercher dans les opérations liées]
ou [{{fullurl:{{FULLPAGENAME}}|action=edit}} créer cette page]</span>.',
-'noarticletext-nopermission' => 'Il n’y a pour l’instant aucun texte sur cette page.
+'noarticletext-nopermission' => 'Il n\'y a pour l\'instant aucun texte sur cette page.
Vous pouvez [[Special:Search/{{PAGENAME}}|faire une recherche sur ce titre]] dans les autres pages,
ou <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} rechercher dans les journaux associés]</span>.',
'missing-revision' => "La révision n° $1 de la page intitulée « {{PAGENAME}} » n'existe pas.
Cela survient en général en suivant un lien historique obsolète vers une page qui a été supprimée.
Vous pouvez trouver plus de détails dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].",
-'userpage-userdoesnotexist' => 'Le compte utilisateur « <nowiki>$1</nowiki> » n’est pas enregistré. Veuillez vérifier que vous voulez créer cette page.',
-'userpage-userdoesnotexist-view' => 'Le compte utilisateur « $1 » n’est pas enregistré.',
-'blocked-notice-logextract' => 'Cet utilisateur est actuellement bloqué.
-La dernière entrée du registre des blocages est indiquée ci-dessous à titre d’information :',
+'userpage-userdoesnotexist' => "Le compte utilisateur « <nowiki>$1</nowiki> » n'est pas enregistré. Veuillez vérifier que vous voulez créer cette page.",
+'userpage-userdoesnotexist-view' => "Le compte utilisateur « $1 » n'est pas enregistré.",
+'blocked-notice-logextract' => "Cet utilisateur est actuellement bloqué.
+La dernière entrée du registre des blocages est indiquée ci-dessous à titre d'information :",
'clearyourcache' => "'''Note :''' après avoir enregistré vos préférences, vous devrez forcer le rechargement complet du cache de votre navigateur pour voir les changements.
* '''Firefox / Safari :''' Maintenez la touche ''Maj'' (''Shift'') en cliquant sur le bouton ''Actualiser'' ou pressez ''Ctrl-F5'' ou ''Ctrl-R'' (''⌘-R'' sur un Mac) ;
* '''Google Chrome :''' Appuyez sur ''Ctrl-Maj-R'' (''⌘-Shift-R'' sur un Mac) ;
* '''Internet Explorer :''' Maintenez la touche ''Ctrl'' en cliquant sur le bouton ''Actualiser'' ou pressez ''Ctrl-F5'' ;
* '''Opera :''' Videz le cache dans ''Outils → Préférences''.",
-'usercssyoucanpreview' => "'''Astuce :''' utilisez le bouton « {{int:showpreview}} » pour tester votre nouvelle feuille CSS avant de l’enregistrer.",
-'userjsyoucanpreview' => "'''Astuce :''' utilisez le bouton « {{int:showpreview}} » pour tester votre nouvelle feuille JavaScript avant de l’enregistrer.",
-'usercsspreview' => "'''Rappelez-vous que vous n’êtes qu’en train de prévisualiser votre propre feuille CSS.'''
-'''Elle n’a pas encore été enregistrée !'''",
-'userjspreview' => "'''Rappelez-vous que vous êtes en train de visualiser ou de tester votre code JavaScript et qu’il n’a pas encore été enregistré !'''",
+'usercssyoucanpreview' => "'''Astuce :''' utilisez le bouton « {{int:showpreview}} » pour tester votre nouvelle feuille CSS avant de l'enregistrer.",
+'userjsyoucanpreview' => "'''Astuce :''' utilisez le bouton « {{int:showpreview}} » pour tester votre nouvelle feuille JavaScript avant de l'enregistrer.",
+'usercsspreview' => "'''Rappelez-vous que vous n'êtes qu'en train de prévisualiser votre propre feuille CSS.'''
+'''Elle n'a pas encore été enregistrée !'''",
+'userjspreview' => "'''Rappelez-vous que vous êtes en train de visualiser ou de tester votre code JavaScript et qu'il n'a pas encore été enregistré !'''",
'sitecsspreview' => "'''Souvenez-vous que vous êtes seulement en train de prévisualiser cette feuille de style.'''
-'''Elle n’a pas encore été enregistrée !'''",
+'''Elle n'a pas encore été enregistrée !'''",
'sitejspreview' => "'''Souvenez-vous que vous êtes seulement en train de prévisualiser ce code JavaScript.'''
-'''Il n’a pas encore été enregistré !'''",
-'userinvalidcssjstitle' => "'''Attention :''' il n’existe pas d’habillage « $1 ». Rappelez-vous que les pages personnelles avec extensions .css et .js utilisent des titres en minuscules, par exemple {{ns:user}}:Foo/vector.css et non {{ns:user}}:Foo/Vector.css.",
+'''Il n'a pas encore été enregistré !'''",
+'userinvalidcssjstitle' => "'''Attention :''' il n'existe pas d'habillage « $1 ». Rappelez-vous que les pages personnelles avec extensions .css et .js utilisent des titres en minuscules, par exemple {{ns:user}}:Foo/vector.css et non {{ns:user}}:Foo/Vector.css.",
'updated' => '(Mis à jour)',
'note' => "'''Note :'''",
-'previewnote' => "'''Rappelez-vous que ce n’est qu’une prévisualisation.'''
-Vos modifications n’ont pas encore été enregistrées !",
+'previewnote' => "'''Rappelez-vous que ce n'est qu'une prévisualisation.'''
+Vos modifications n'ont pas encore été enregistrées !",
'continue-editing' => 'Aller à la zone de modification',
-'previewconflict' => 'Cette prévisualisation montre le texte de la boîte supérieure de modification tel qu’il apparaîtra si vous choisissez de le publier.',
-'session_fail_preview' => "'''Nous ne pouvons enregistrer votre modification à cause d’une perte d’informations concernant votre session.'''
+'previewconflict' => "Cette prévisualisation montre le texte de la boîte supérieure de modification tel qu'il apparaîtra si vous choisissez de le publier.",
+'session_fail_preview' => "'''Nous ne pouvons enregistrer votre modification à cause d'une perte d'informations concernant votre session.'''
Veuillez réessayer.
Si cela échoue de nouveau, essayez en vous [[Special:UserLogout|déconnectant]], puis en vous reconnectant.",
-'session_fail_preview_html' => "'''Nous ne pouvons enregistrer votre modification à cause d’une perte d’informations concernant votre session.'''
+'session_fail_preview_html' => "'''Nous ne pouvons enregistrer votre modification à cause d'une perte d'informations concernant votre session.'''
''Parce que {{SITENAME}} a activé le HTML brut, la prévisualisation a été masquée afin de prévenir les attaques par JavaScript.''
'''Si la tentative de modification était légitime, veuillez réessayer.'''
Si cela échoue de nouveau, [[Special:UserLogout|déconnectez-vous]], puis reconnectez-vous.",
-'token_suffix_mismatch' => "'''Votre modification n’a pas été acceptée car votre navigateur a mal codé les caractères de ponctuation dans l’identifiant de modification.'''
+'token_suffix_mismatch' => "'''Votre modification n'a pas été acceptée car votre navigateur a mal codé les caractères de ponctuation dans l'identifiant de modification.'''
Ce rejet est nécessaire pour empêcher la corruption du texte de la page.
Ce problème se produit parfois lorsque vous utilisez un serveur mandataire anonyme problématique basé sur le web.",
-'edit_form_incomplete' => "'''Certaines parties du formulaire de modification n’ont pas atteint le serveur, vérifiez que vos modifications sont intactes et essayez à nouveau.'''",
+'edit_form_incomplete' => "'''Certaines parties du formulaire de modification n'ont pas atteint le serveur, vérifiez que vos modifications sont intactes et essayez à nouveau.'''",
'editing' => 'Modification de $1',
'creating' => 'Création de $1',
'editingsection' => 'Modification de $1 (section)',
'editingcomment' => 'Modification de $1 (nouvelle section)',
'editconflict' => 'Conflit de modification : $1',
'explainconflict' => "Cette page a été changée après que vous ayez commencé à la modifier.
-La zone de modification supérieure contient le texte tel qu’il est actuellement enregistré dans la base de données.
+La zone de modification supérieure contient le texte tel qu'il est actuellement enregistré dans la base de données.
Vos modifications apparaissent dans la zone de modification inférieure.
Vous allez devoir fusionner vos modifications dans le texte existant.
'''Seul''' le texte de la zone supérieure sera sauvegardé si vous cliquez sur « {{int:savearticle}} ».",
'yourtext' => 'Votre texte',
'storedversion' => 'La version enregistrée',
-'nonunicodebrowser' => "'''Attention : Votre navigateur ne supporte pas l’Unicode.'''
+'nonunicodebrowser' => "'''Attention : Votre navigateur ne supporte pas l'Unicode.'''
Une solution de rechange a été trouvée pour vous permettre de modifier en toute sûreté une page : les caractères non-ASCII apparaîtront dans votre boîte de modification en tant que codes hexadécimaux. Vous devriez utiliser un navigateur plus récent.",
'editingold' => "'''Attention : vous êtes en train de modifier une ancienne version de cette page.
Si vous la publiez, toutes les modifications effectuées depuis cette version seront perdues.'''",
'yourdiff' => 'Différences',
'copyrightwarning' => "Toutes les contributions à {{SITENAME}} sont considérées comme publiées sous les termes de la $2 (voir $1 pour plus de détails). Si vous ne désirez pas que vos écrits soient modifiés et distribués à volonté, merci de ne pas les soumettre ici.<br />
-Vous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l’avez copié d’une source provenant du domaine public, ou d’une ressource libre. '''N’UTILISEZ PAS DE TRAVAUX SOUS DROIT D’AUTEUR SANS AUTORISATION EXPRESSE !'''",
-'copyrightwarning2' => "Toutes les contributions à {{SITENAME}} peuvent être modifiées ou supprimées par d’autres utilisateurs. Si vous ne désirez pas que vos écrits soient modifiés et distribués à volonté, merci de ne pas les soumettre ici.<br />
-Vous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l’avez copié d’une source provenant du domaine public, ou d’une ressource libre. (voir $1 pour plus de détails).
-'''N’UTILISEZ PAS DE TRAVAUX SOUS DROIT D’AUTEUR SANS AUTORISATION EXPRESSE !'''",
+Vous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l'avez copié d'une source provenant du domaine public, ou d'une ressource libre. '''N'UTILISEZ PAS DE TRAVAUX SOUS DROIT D'AUTEUR SANS AUTORISATION EXPRESSE !'''",
+'copyrightwarning2' => "Toutes les contributions à {{SITENAME}} peuvent être modifiées ou supprimées par d'autres utilisateurs. Si vous ne désirez pas que vos écrits soient modifiés et distribués à volonté, merci de ne pas les soumettre ici.<br />
+Vous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l'avez copié d'une source provenant du domaine public, ou d'une ressource libre. (voir $1 pour plus de détails).
+'''N'UTILISEZ PAS DE TRAVAUX SOUS DROIT D'AUTEUR SANS AUTORISATION EXPRESSE !'''",
'longpageerror' => "'''Erreur: Le texte que vous avez soumis fait {{PLURAL:$1|un Kio|$1 Kio}}, ce qui dépasse la limite fixée à {{PLURAL:$2|un Kio|$2 Kio}}.'''
Il ne peut pas être sauvegardé.",
-'readonlywarning' => "'''AVERTISSEMENT : la base de données a été verrouillée pour des opérations de maintenance. Vous ne pouvez donc pas publier vos modifications pour l’instant.'''
+'readonlywarning' => "'''AVERTISSEMENT : la base de données a été verrouillée pour des opérations de maintenance. Vous ne pouvez donc pas publier vos modifications pour l'instant.'''
Vous pouvez copier le texte dans un fichier texte et le conserver pour plus tard.
-L’administrateur ayant verrouillé la base de données a donné l’explication suivante : $1",
-'protectedpagewarning' => "'''AVERTISSEMENT : cette page est protégée. Seuls les utilisateurs ayant le statut d’administrateur peuvent la modifier.'''<br />
+L'administrateur ayant verrouillé la base de données a donné l'explication suivante : $1",
+'protectedpagewarning' => "'''AVERTISSEMENT : cette page est protégée. Seuls les utilisateurs ayant le statut d'administrateur peuvent la modifier.'''<br />
La dernière entrée du journal est affichée ci-dessous pour référence :",
'semiprotectedpagewarning' => "'''Note :''' Cette page a été protégée de telle façon que seuls les contributeurs enregistrés puissent la modifier. La dernière entrée du journal est affichée ci-dessous pour référence :",
-'cascadeprotectedwarning' => "'''ATTENTION :''' Cette page a été protégée de manière à ce que seuls les administrateurs puissent l’éditer. Cette protection est héritée par son inclusion par {{PLURAL:$1|la page protégée suivante, qui a|les pages protégées suivantes, qui ont}} la « protection en cascade » activée :",
+'cascadeprotectedwarning' => "'''ATTENTION :''' Cette page a été protégée de manière à ce que seuls les administrateurs puissent l'éditer. Cette protection est héritée par son inclusion par {{PLURAL:$1|la page protégée suivante, qui a|les pages protégées suivantes, qui ont}} la « protection en cascade » activée :",
'titleprotectedwarning' => "'''ATTENTION : Cette page a été protégée de telle manière que des [[Special:ListGroupRights|droits spécifiques]] sont requis pour pouvoir la créer.''' La dernière entrée du journal est affichée ci-dessous pour référence :",
'templatesused' => '{{PLURAL:$1|Modèle utilisé|Modèles utilisés}} par cette page :',
'templatesusedpreview' => '{{PLURAL:$1|Modèle utilisé|Modèles utilisés}} dans cette prévisualisation :',
'nocreatetitle' => 'Création de page limitée',
'nocreatetext' => '{{SITENAME}} a restreint la possibilité de créer de nouvelles pages.
Vous pouvez revenir en arrière et modifier une page existante, ou bien [[Special:UserLogin|vous connecter ou créer un compte]].',
-'nocreate-loggedin' => 'Vous n’avez pas la permission de créer de nouvelles pages.',
+'nocreate-loggedin' => "Vous n'avez pas la permission de créer de nouvelles pages.",
'sectioneditnotsupported-title' => 'Modification de section non prise en charge',
-'sectioneditnotsupported-text' => 'La modification d’une section n’est pas prise en charge pour cette page.',
+'sectioneditnotsupported-text' => "La modification d'une section n'est pas prise en charge pour cette page.",
'permissionserrors' => 'Erreur de permissions',
-'permissionserrorstext' => 'Vous n’avez pas la permission d’effectuer l’opération demandée pour {{PLURAL:$1|la raison suivante|les raisons suivantes}} :',
-'permissionserrorstext-withaction' => 'Vous n’êtes pas autorisé{{GENDER:||e|(e)}} à $2, pour {{PLURAL:$1|la raison suivante|les raisons suivantes}} :',
+'permissionserrorstext' => "Vous n'avez pas la permission d'effectuer l'opération demandée pour {{PLURAL:$1|la raison suivante|les raisons suivantes}} :",
+'permissionserrorstext-withaction' => "Vous n'êtes pas autorisé{{GENDER:||e|(e)}} à $2, pour {{PLURAL:$1|la raison suivante|les raisons suivantes}} :",
'recreate-moveddeleted-warn' => "'''Attention : vous êtes en train de recréer une page qui a été précédemment supprimée.'''
-Assurez-vous qu’il est pertinent de poursuivre les modifications sur cette page. Le journal des suppressions et des déplacements est affiché ci-dessous :",
+Assurez-vous qu'il est pertinent de poursuivre les modifications sur cette page. Le journal des suppressions et des déplacements est affiché ci-dessous :",
'moveddeleted-notice' => 'Cette page a été supprimée. Le journal des suppressions et des déplacements est affiché ci-dessous pour référence.',
'log-fulllog' => 'Voir le journal complet',
'edit-hook-aborted' => 'Échec de la modification par une extension.
Cause inconnue',
-'edit-gone-missing' => 'N’a pas pu mettre à jour la page.
-Il semble qu’elle ait été supprimée.',
+'edit-gone-missing' => "N'a pas pu mettre à jour la page.
+Il semble qu'elle ait été supprimée.",
'edit-conflict' => 'Conflit de modification.',
-'edit-no-change' => 'Votre modification a été ignorée car aucun changement n’a été fait au texte.',
-'edit-already-exists' => 'La nouvelle page n’a pas pu être créée.
-Elle existe déjà.',
+'edit-no-change' => "Votre modification a été ignorée car aucun changement n'a été fait au texte.",
+'edit-already-exists' => "La nouvelle page n'a pas pu être créée.
+Elle existe déjà.",
'defaultmessagetext' => 'Message par défaut',
'content-failed-to-parse' => "Échec de l'analyse du contenu de $2 pour le modèle $1: $3",
'invalid-content-data' => 'Données du contenu non valides',
'content-model-css' => 'CSS',
# Parser/template warnings
-'expensive-parserfunction-warning' => 'Attention : cette page contient de trop nombreux appels à des fonctions coûteuses de l’analyseur syntaxique.
+'expensive-parserfunction-warning' => "Attention : cette page contient de trop nombreux appels à des fonctions coûteuses de l'analyseur syntaxique.
-Il devrait y avoir moins de $2 appel{{PLURAL:$2||s}}, alors qu’il y en a maintenant $1.',
-'expensive-parserfunction-category' => 'Pages avec trop d’appels dispendieux de fonctions de l’analyseur syntaxique',
-'post-expand-template-inclusion-warning' => 'Attention : Cette page contient trop d’inclusions de modèles. Certaines inclusions ne seront pas effectuées.',
-'post-expand-template-inclusion-category' => 'Pages contenant trop d’inclusions de modèles',
-'post-expand-template-argument-warning' => 'Attention : Cette page contient au moins un paramètre de modèle dont l’inclusion est rendue impossible. Après extension, celui-ci aurait produit un résultat trop long, il n’a donc pas été inclus.',
+Il devrait y avoir moins de $2 appel{{PLURAL:$2||s}}, alors qu'il y en a maintenant $1.",
+'expensive-parserfunction-category' => "Pages avec trop d'appels dispendieux de fonctions de l'analyseur syntaxique",
+'post-expand-template-inclusion-warning' => "Attention : Cette page contient trop d'inclusions de modèles. Certaines inclusions ne seront pas effectuées.",
+'post-expand-template-inclusion-category' => "Pages contenant trop d'inclusions de modèles",
+'post-expand-template-argument-warning' => "Attention : Cette page contient au moins un paramètre de modèle dont l'inclusion est rendue impossible. Après extension, celui-ci aurait produit un résultat trop long, il n'a donc pas été inclus.",
'post-expand-template-argument-category' => 'Pages contenant des paramètres de modèle non évalués',
'parser-template-loop-warning' => 'Modèle en boucle détecté : [[$1]]',
'parser-template-recursion-depth-warning' => 'Limite de profondeur des appels de modèles dépassée ($1)',
'converter-manual-rule-error' => 'Erreur détectée dans la règle manuelle de conversion de langue',
# "Undo" feature
-'undo-success' => 'Cette modification va être défaite. Veuillez vérifier les modifications ci-dessous, puis publier si c’est bien ce que vous voulez faire.',
+'undo-success' => "Cette modification va être défaite. Veuillez vérifier les modifications ci-dessous, puis publier si c'est bien ce que vous voulez faire.",
'undo-failure' => 'Cette modification ne peut pas être défaite : cela entrerait en conflit avec les modifications intermédiaires.',
-'undo-norev' => 'La modification n’a pas pu être défaite parce qu’elle est inexistante ou qu’elle a été supprimée.',
+'undo-norev' => "La modification n'a pas pu être défaite parce qu'elle est inexistante ou qu'elle a été supprimée.",
'undo-summary' => 'Annulation des modifications $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|discussion]])',
# Account creation failure
# History pages
'viewpagelogs' => 'Voir les opérations sur cette page',
-'nohistory' => 'Il n’existe pas d’historique pour cette page.',
+'nohistory' => "Il n'existe pas d'historique pour cette page.",
'currentrev' => 'Version actuelle',
'currentrev-asof' => 'Version actuelle en date du $1',
'revisionasof' => 'Version du $1',
'page_first' => 'première',
'page_last' => 'dernière',
'histlegend' => 'Légende : ({{int:cur}}) = différence avec la version actuelle, ({{int:last}}) = différence avec la version précédente, <b>{{int:minoreditletter}}</b> = modification mineure',
-'history-fieldset-title' => 'Naviguer dans l’historique',
+'history-fieldset-title' => "Naviguer dans l'historique",
'history-show-deleted' => 'Masqués seulement',
'histfirst' => 'première page',
'histlast' => 'dernière page',
'history-feed-title' => 'Historique des versions',
'history-feed-description' => 'Historique pour cette page sur le wiki',
'history-feed-item-nocomment' => '$1 le $2',
-'history-feed-empty' => 'La page demandée n’existe pas.
+'history-feed-empty' => "La page demandée n'existe pas.
Elle a peut-être été effacée ou renommée.
-Essayez de [[Special:Search|rechercher sur le wiki]] pour trouver des pages en rapport.',
+Essayez de [[Special:Search|rechercher sur le wiki]] pour trouver des pages en rapport.",
# Revision deletion
-'rev-deleted-comment' => '(résumé d’édition enlevé)',
-'rev-deleted-user' => '(nom d’utilisateur supprimé)',
+'rev-deleted-comment' => "(résumé d'édition enlevé)",
+'rev-deleted-user' => "(nom d'utilisateur supprimé)",
'rev-deleted-event' => '(entrée supprimée)',
-'rev-deleted-user-contribs' => '[nom d’utilisateur ou adresse IP supprimée - modification cachée sur les contributions]',
+'rev-deleted-user-contribs' => "[nom d'utilisateur ou adresse IP supprimée - modification cachée sur les contributions]",
'rev-deleted-text-permission' => "Cette version de la page a été '''effacée'''.
Des détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des effacements].",
'rev-deleted-text-unhide' => "Cette version de la page a été '''effacée'''.
Vous pouvez la visualiser ; des détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des effacements].",
'rev-suppressed-text-view' => "Cette version de la page a été '''supprimée'''.
Vous pouvez la visualiser ; des détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} journal des suppressions].",
-'rev-deleted-no-diff' => "Vous ne pouvez pas voir ce diff parce qu’une des versions a été '''effacée'''.
+'rev-deleted-no-diff' => "Vous ne pouvez pas voir ce diff parce qu'une des versions a été '''effacée'''.
Des détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des effacements].",
'rev-suppressed-no-diff' => "Vous ne pouvez pas voir cette différence car une des révisions a été '''supprimée'''.",
'rev-deleted-unhide-diff' => "Une des révisions de cette différence a été '''effacée'''.
'wantedpages' => 'Pages les plus demandées',
'wantedpages-badtitle' => 'Titre invalide dans les résultats : $1',
'wantedfiles' => 'Fichiers les plus demandés',
-'wantedfiletext-cat' => "Les fichiers suivants sont utilisés, mais il n'existent pas. Les fichiers de dépôts à distance peuvent être listés malgré qu'ils existent. Tout ces faux positifs seront <del>barrés</del>. En outre, les pages qui intègrent des fichiers qui n'existent pas sont répertoriés dans [[:$1]].",
-'wantedfiletext-nocat' => "Les fichiers suivants sont utilisés, mais n'existent pas. Les fichiers de dépôts à distance peuvent être listés malgré qu'ils existent. Tout ces faux positifs seront <del>barrés</del>.",
+'wantedfiletext-cat' => 'Les fichiers suivants sont utilisés, mais n’existent pas. Les fichiers d’autres dépôts peuvent être listés malgré qu’ils existent. Tous ces faux positifs seront <del>barrés</del>. En outre, les pages qui intègrent des fichiers qui n’existent pas sont répertoriées dans [[:$1]].',
+'wantedfiletext-nocat' => 'Les fichiers suivants sont utilisés, mais n’existent pas. Les fichiers d’autres dépôts peuvent être listés malgré qu’ils existent. Tous ces faux positifs seront <del>barrés</del>.',
'wantedtemplates' => 'Modèles demandés',
'mostlinked' => 'Pages les plus liées',
'mostlinkedcategories' => 'Catégories les plus utilisées',
'linksearch-pat' => 'Expression recherchée :',
'linksearch-ns' => 'Espace de noms :',
'linksearch-ok' => 'Rechercher',
-'linksearch-text' => 'Des caractères jokers comme « *.wikipedia.org » peuvent être utilisés.
+'linksearch-text' => "Des caractères jokers comme « *.wikipedia.org » peuvent être utilisés.
Ils nécessitent au moins un domaine de niveau supérieur, par exemple « *.org ».<br />
-Protocoles reconnus : <code>$1</code> (n’ajoutez aucun de ceux-ci dans votre recherche).',
+Protocoles reconnus : <code>$1</code> (http:// par défaut si aucun protocole n'est indiqué).",
'linksearch-line' => '$1 est lié depuis $2',
'linksearch-error' => 'Les caractères jokers ne peuvent être utilisés qu’au début du nom de domaine de l’hôte.',
'sp-newimages-showfrom' => 'Afficher les nouveaux fichiers à partir du $1 à $2',
# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
+'days-abbrev' => '$1 j',
'seconds' => '{{PLURAL:$1|$1 seconde|$1 secondes}}',
'minutes' => '{{PLURAL:$1|$1 minute|$1 minutes}}',
'hours' => '{{PLURAL:$1|$1 heure|$1 heures}}',
'version-poweredby-credits' => "Ce wiki fonctionne grâce à '''[//www.mediawiki.org/ MediaWiki]''', copyright © 2001-$1 $2.",
'version-poweredby-others' => 'autres',
'version-credits-summary' => 'Nous tenons à remercier les personnes suivantes pour leur contribution à [[Special:Version|MediaWiki]].',
-'version-license-info' => "MediaWiki est un logiciel libre, vous pouvez le redistribuer et / ou le modifier selon les termes de la Licence Publique Générale GNU telle que publiée par la Free Software Foundation ; soit la version 2 de la Licence, ou (à votre choix) toute version ultérieure.
+'version-license-info' => 'MediaWiki est un logiciel libre, vous pouvez le redistribuer ou le modifier selon les termes de la Licence Publique Générale GNU telle que publiée par la Free Software Foundation ; soit la version 2 de la Licence, ou (à votre choix) toute version ultérieure.
-MediaWiki est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE, sans même la garantie implicite de COMMERCIALISATION ou D'ADAPTATION A UN USAGE PARTICULIER. Voir la Licence Publique Générale GNU pour plus de détails.
+MediaWiki est distribué dans l’espoir qu’il sera utile, mais SANS AUCUNE GARANTIE, sans même la garantie implicite de COMMERCIALISATION ou D’ADAPTATION À UN USAGE PARTICULIER. Voir la Licence Publique Générale GNU pour plus de détails.
-Vous devriez avoir reçu [{{SERVER}}{{SCRIPTPATH}}/COPYING une copie de la Licence Publique Générale GNU] avec ce programme, sinon, écrivez à la Free Software Foundation, Inc, 51, rue Franklin, cinquième étage, Boston, MA 02110-1301, États-Unis ou [//www.gnu.org/licenses/old-licenses/gpl-2.0.html lisez-la en ligne].",
+Vous devriez avoir reçu [{{SERVER}}{{SCRIPTPATH}}/COPYING une copie de la Licence Publique Générale GNU] avec ce programme, sinon, écrivez à la Free Software Foundation, Inc., 51, rue Franklin, cinquième étage, Boston, MA 02110-1301, États-Unis ou [//www.gnu.org/licenses/old-licenses/gpl-2.0.html lisez-la en ligne].',
'version-software' => 'Logiciels installés',
'version-software-product' => 'Produit',
'version-software-version' => 'Version',
'version-entrypoints' => 'URL des points d’entrée',
-'version-entrypoints-header-entrypoint' => "Point d'entrée",
+'version-entrypoints-header-entrypoint' => 'Point d’entrée',
'version-entrypoints-header-url' => 'URL',
-'version-entrypoints-articlepath' => '[https://www.mediawiki.org/wiki/Manual:$wgArticlePath Chemin d\'article]',
+'version-entrypoints-articlepath' => '[https://www.mediawiki.org/wiki/Manual:$wgArticlePath Chemin d’article]',
'version-entrypoints-scriptpath' => '[https://www.mediawiki.org/wiki/Manual:$wgScriptPath Chemin de script]',
# Special:FilePath
$dateFormats = array(
'dmy time' => 'H:i',
'dmy date' => 'j \d\e F \d\e Y',
- 'dmy both' => '\ j \d\e F \d\e Y "ás" H:i',
+ 'dmy both' => 'j \d\e F \d\e Y "ás" H:i',
);
$specialPageAliases = array(
'underline-always' => 'Sempre',
'underline-never' => 'Nunca',
-'underline-default' => 'Opción do propio navegador',
+'underline-default' => 'Opción predeterminada da aparencia ou do navegador',
# Font style option in Special:Preferences
'editfont-style' => 'Tipo de letra da caixa de edición:',
'newwindow' => '(abre unha ventá nova)',
'cancel' => 'Cancelar',
'moredotdotdot' => 'Máis...',
-'mypage' => 'A miña páxina',
-'mytalk' => 'A miña conversa',
+'mypage' => 'Páxina',
+'mytalk' => 'Conversa',
'anontalk' => 'Conversa con este enderezo IP',
'navigation' => 'Navegación',
'and' => ' e',
# Preferences page
'preferences' => 'Preferencias',
-'mypreferences' => 'As miñas preferencias',
+'mypreferences' => 'Preferencias',
'prefs-edits' => 'Número de edicións:',
'prefsnologin' => 'Non accedeu ao sistema',
'prefsnologintext' => 'Debe <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} acceder ao sistema]</span> para modificar as preferencias de usuario.',
# User rights log
'rightslog' => 'Rexistro de dereitos de usuario',
'rightslogtext' => 'Este é un rexistro dos cambios nos permisos de usuario.',
-'rightslogentry' => 'cambiou o grupo ao que pertence "$1" de $2 a $3',
+'rightslogentry' => 'cambiou o grupo ao que pertence $1 de $2 a $3',
'rightslogentry-autopromote' => 'foi promovido automaticamente de $2 a $3',
+'logentry-rights-rights' => '$1 cambiou o grupo ao que pertence $3 de $4 a $5',
+'logentry-rights-rights-legacy' => '$1 cambiou o grupo ao que pertence $3',
+'logentry-rights-autopromote' => '$1 foi promovido automaticamente de $4 a $5',
'rightsnone' => '(ningún)',
# Associated actions - in the sentence "You do not have permission to X"
'recentchanges-label-unpatrolled' => 'Esta edición aínda non foi comprobada',
'rcnote' => "A continuación {{PLURAL:$1|móstrase '''1''' cambio|móstranse os últimos '''$1''' cambios}} {{PLURAL:$2|no último día|nos últimos '''$2''' días}} ata o $4 ás $5.",
'rcnotefrom' => "A continuación móstranse os cambios feitos desde o '''$3''' ás '''$4''' (móstranse '''$1''' como máximo).",
-'rclistfrom' => 'Mostrar os cambios novos desde as $1',
+'rclistfrom' => 'Mostrar os cambios novos desde o $1',
'rcshowhideminor' => '$1 as edicións pequenas',
'rcshowhidebots' => '$1 os bots',
'rcshowhideliu' => '$1 os usuarios rexistrados',
'linksearch-ok' => 'Procurar',
'linksearch-text' => 'Pódense usar caracteres comodín como "*.wikipedia.org".
Cómpre, polo menos, un dominio de nivel superior, por exemplo "*.org".<br />
-Protocolos soportados: <code>$1</code> (non engada ningún destes na súa procura).',
+Protocolos soportados: <code>$1</code> (úsase http:// como predeterminado se non se especifica ningún protocolo).',
'linksearch-line' => '$1 está ligado desde a páxina "$2"',
'linksearch-error' => 'Os caracteres comodín só poden aparecer ao principio do nome do servidor.',
# Watchlist
'watchlist' => 'A miña lista de vixilancia',
-'mywatchlist' => 'A miña lista de vixilancia',
+'mywatchlist' => 'Lista de vixilancia',
'watchlistfor2' => 'De $1 $2',
'nowatchlist' => 'Non ten elementos na súa lista de vixilancia.',
'watchlistanontext' => 'Faga o favor de $1 ao sistema para ver ou editar os elementos da súa lista de vixilancia.',
# Contributions
'contributions' => 'Contribucións {{GENDER:{{BASEPAGENAME}}|do usuario|da usuaria}}',
'contributions-title' => 'Contribucións de $1',
-'mycontris' => 'As miñas contribucións',
+'mycontris' => 'Contribucións',
'contribsub2' => 'De $1 ($2)',
'nocontribs' => 'Non se deron atopado cambios con eses criterios.',
'uctop' => '(última revisión)',
'whatlinkshere-hideredirs' => '$1 as redireccións',
'whatlinkshere-hidetrans' => '$1 as inclusións',
'whatlinkshere-hidelinks' => '$1 as ligazóns',
-'whatlinkshere-hideimages' => '$1 as ligazóns á imaxe',
+'whatlinkshere-hideimages' => '$1 as ligazóns ao ficheiro',
'whatlinkshere-filters' => 'Filtros',
# Block/unblock
'nostalgia.js' => '/* Calquera JavaScript que haxa aquí será cargado para os usuarios que usen a aparencia Morriña */',
'cologneblue.js' => '/* Calquera JavaScript que haxa aquí será cargado para os usuarios que usen a aparencia Azul colonial */',
'monobook.js' => '/* Calquera JavaScript que haxa aquí será cargado para os usuarios que usen a aparencia MonoBook */',
-'myskin.js' => '/* Calquera JavaScript que haxa aquí será cargado para os usuarios que usen a aparencia A miña aparencia */',
+'myskin.js' => '/* O JavaScript que se coloque aquí afectará a quen use a aparencia A miña aparencia */',
'chick.js' => '/* Calquera JavaScript que haxa aquí será cargado para os usuarios que usen a aparencia Parrulo */',
'simple.js' => '/* Calquera JavaScript que haxa aquí será cargado para os usuarios que usen a aparencia Sinxela */',
'modern.js' => '/* Calquera JavaScript que haxa aquí será cargado para os usuarios que usen a aparencia Moderna */',
'duration-centuries' => '$1 {{PLURAL:$1|século|séculos}}',
'duration-millennia' => '$1 {{PLURAL:$1|milenio|milenios}}',
+# Unknown messages
+'mytalk-parenthetical' => 'conversa',
);
'underline-always' => 'immer',
'underline-never' => 'nie',
-'underline-default' => 'Browser-Vorystellig',
+'underline-default' => 'Voryystellig vu dr Benutzeroberfleichi oder em Brwoser',
# Font style option in Special:Preferences
'editfont-style' => 'Schriftfamilie fir dr Text im Bearbeitigsfänschter:',
'newwindow' => '(imene nöie Fänschter)',
'cancel' => 'Abbräche',
'moredotdotdot' => 'Meh …',
-'mypage' => 'Myyni Syte',
-'mytalk' => 'Myyni Diskussionsyte',
+'mypage' => 'Syte',
+'mytalk' => 'Diskussionsyte',
'anontalk' => 'Diskussionssyste vo sellere IP',
'navigation' => 'Navigation',
'and' => ' un',
'note' => "'''Obacht: '''",
'previewnote' => "'''Das isch numen e Vorschau und nonig gspycheret!'''
Die Syte isch nonig gspycheret wore!",
-'continue-editing' => 'Wyter bearbeite',
+'continue-editing' => 'Zum Bearbeitigsfäld',
'previewconflict' => 'Die Vorschau zeigt dr Inhalt vum obere Täxtfäld. Eso siht dr Artikel us, wän Du jetz uf Spychere drucksch.',
'session_fail_preview' => "'''Dyyni Bearbeitig het nid chenne gspycheret wäre, wel Sitzigsdate verlore gange sin.
Bitte versuech s nomol. Derzue drucksch unter däre Täxtvorschau nomol uf „Syte spychere“.
# Preferences page
'preferences' => 'Yystellige',
-'mypreferences' => 'Ystellige',
+'mypreferences' => 'Yystellige',
'prefs-edits' => 'Aazahl vu dr Bearbeitige:',
'prefsnologin' => 'Nid aagmäldet',
'prefsnologintext' => 'Du muesch <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} aagmäldet]</span> sy, für Benutzerystellige chönne z ändere',
'rightslogtext' => 'Des ischs Logbuech vun de Änderunge on Bnutzerrechte.',
'rightslogentry' => 'het d Benutzerrächt fir „$1“ vu „$2“ uf „$3“ gänderet',
'rightslogentry-autopromote' => 'd Zueornig zue dr Benutzergruppe isch automatisch vu $2 in $3 gänderet wore',
+'logentry-rights-rights' => '$1 het d Gruppezuegherigkeit fir $3 vu $4 uf $5 gänderet',
+'logentry-rights-rights-legacy' => '$1 het d Gruppezuegherigkeit fir $3 gänderet',
+'logentry-rights-autopromote' => '$1 isch automatisch vu $4 zue $5 zuegordnet wore',
'rightsnone' => '(keini)',
# Associated actions - in the sentence "You do not have permission to X"
'linksearch-pat' => 'Suechmuschter:',
'linksearch-ns' => 'Namensruum:',
'linksearch-ok' => 'Sueche',
-'linksearch-text' => 'Die Spezialsyte macht d Suechi no Syte megli, wu s bstimmti Weblink din het. Doderby chenne Platzhalter wie zem Byschpel <code>*.byschpel.de</code> brucht wäre. S mueß zmindecht ei Top-Level-Domain, z. B. „*.org“. aagee wäre. <br />Unterstitzti Protokoll: <code>$1</code> (Die bitte nit bi dr Suechaafrog aagee.)',
+'linksearch-text' => 'Die Spezialsyte macht d Suechi no Syte megli, wu s bstimmti Weblink din het. Doderby chenne Platzhalter wie zem Byschpel <code>*.byschpel.de</code> brucht wäre. S mueß zmindecht ei Top-Level-Domain, z. B. „*.org“. aagee wäre. <br />Unterstitzti Protokoll: <code>$1</code> (Standard isch http, wänn kei Protokoll aagee isch).',
'linksearch-line' => '$1 isch vo $2 verknüpft',
'linksearch-error' => 'Platzhalter chönne numme am Aafang verwändet werre.',
'emailuser-title-target' => 'E-Mail an {{GENDER:$1|dää Benutzer|die Benutzeri}} schicke',
'emailuser-title-notarget' => 'E-Mail an Benutzer',
'emailpage' => 'E-Mail an Benutzer',
-'emailpagetext' => 'Du chasch im Benutzer mit däm Formular e E-Mail schicke.
-As Absender wird d E-Mail-Adräss us Dyyne [[Special:Preferences|Yystellige]] yytrait, ass dr Benutzer Dir cha Antwort gee.',
+'emailpagetext' => 'Du chasch {{GENDER:$1|em Benutzer|dr Benutzeri}} mit däm Formular e E-Mail schicke.
+As Absender wird d E-Mail-Adräss us Dyyne [[Special:Preferences|Yystellige]] yytrait, ass {{GENDER:$1|dr Benutzer|d Benutzeri}} Dir cha Antwort gee.',
'usermailererror' => 'S Mail-Objekt het e Fähler zruckgee:',
'defemailsubject' => '{{SITENAME}}-E-Mail vum Benutzer „$1“',
'usermaildisabled' => 'Benutzer-E-Mail abgstellt',
'whatlinkshere-hideredirs' => 'Wyterleitige $1',
'whatlinkshere-hidetrans' => 'Vorlageyybindige $1',
'whatlinkshere-hidelinks' => 'Links $1',
-'whatlinkshere-hideimages' => 'Dateigleicher $1',
+'whatlinkshere-hideimages' => 'Dateilink $1',
'whatlinkshere-filters' => 'Filter',
# Block/unblock
# Info page
'pageinfo-title' => 'Informatione zue „$1“',
-'pageinfo-not-current' => 'Die Informatione chenne nume fir di nejscht Versions aazeigt wäre.',
+'pageinfo-not-current' => 'Die Informatione chenne leider nit fir alti Versionen aazeigt wäre.',
'pageinfo-header-basic' => 'Basisinformatione',
'pageinfo-header-edits' => 'Bearbeitige',
'pageinfo-header-restrictions' => 'Syteschutz',
'pageinfo-default-sort' => 'Standardsortierkriterium',
'pageinfo-length' => 'Sytelengi (in Byte)',
'pageinfo-article-id' => 'Syten-ID',
+'pageinfo-language' => 'Syteninhaltssproch',
'pageinfo-robot-policy' => 'Suechmaschinestatus',
'pageinfo-robot-index' => 'Indizierbar',
'pageinfo-robot-noindex' => 'Nit indizierbar',
'pageinfo-hidden-categories' => 'Versteckti {{PLURAL:$1|Kategori|Kategorie}} ($1)',
'pageinfo-templates' => 'Yybundeni {{PLURAL:$1|Vorlag|Vorlage}} ($1)',
'pageinfo-toolboxlink' => 'Informatione zue dr Syte',
+'pageinfo-redirectsto' => 'Weiterleitung nach',
+'pageinfo-redirectsto-info' => 'Information',
+'pageinfo-contentpage' => 'Zellt as Inhaltssyte',
+'pageinfo-contentpage-yes' => 'Jo',
+'pageinfo-protect-cascading' => 'Syte mit Kaskadeschutz vu do',
+'pageinfo-protect-cascading-yes' => 'Jo',
+'pageinfo-protect-cascading-from' => 'Syte mit Kaskadeschutz vu',
# Patrolling
'markaspatrolleddiff' => 'Als patrulyrt markyre',
'version-license' => 'Lizänz',
'version-poweredby-credits' => "Die Websyte nutzt '''[//www.mediawiki.org/wiki/MediaWiki/de MediaWiki]''', Copyright © 2001–$1 $2.",
'version-poweredby-others' => 'anderi',
+'version-credits-summary' => 'Mir danke däne Lyt fir ihri Bytreg zue [[Special:Version|MediaWiki]].',
'version-license-info' => 'MediaWiki isch e freji Software, d. h. s cha, no dr Bedingige vu dr GNU General Public-Lizänz, wu vu dr Free Software Foundation vereffentligt woren isch, wyterverteilt un/oder modifiziert wäre. Doderbyy cha d Version 2, oder no eigenem Ermässe, jedi nejeri Version vu dr Lizänz brucht wäre.
Des Programm wird in dr Hoffnig verteilt, ass es nitzli isch, aber OHNI JEDI GARANTI un sogar ohni di impliziert Garanti vun ere MÄRTGÄNGIGKEIT oder EIGNIG FIR E BSTIMMTE ZWÄCK. Doderzue git meh Hiiwys in dr GNU General Public-Lizänz.
'newwindow' => '(נפתח בחלון חדש)',
'cancel' => 'ביטול / יציאה',
'moredotdotdot' => 'עוד…',
-'mypage' => '×\94×\93×£ ש×\9c×\99',
-'mytalk' => '×\93×£ ×\94ש×\99×\97×\94 ש×\9c×\99',
+'mypage' => '×\93×£ ×\9eשת×\9eש',
+'mytalk' => 'ש×\99×\97×\94',
'anontalk' => 'השיחה עבור IP זה',
'navigation' => 'ניווט',
'and' => ' וגם',
# Preferences page
'preferences' => 'העדפות',
-'mypreferences' => '×\94×\94×¢×\93פ×\95ת ש×\9c×\99',
+'mypreferences' => '×\94×¢×\93פ×\95ת',
'prefs-edits' => 'מספר עריכות:',
'prefsnologin' => 'לא נכנסת לחשבון',
'prefsnologintext' => 'עליכם <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} להיכנס לחשבון]</span> כדי לשנות העדפות משתמש.',
'linksearch-ok' => 'חיפוש',
'linksearch-text' => 'ניתן להשתמש בתווים כלליים, לדוגמה <span dir="ltr">"*.wikipedia.org"</span>.
נדרשת לפחות סיומת אינטרנט (TLD), למשל <span dir="ltr">"*.org"</span>.<br />
-פר×\95×\98×\95ק×\95×\9c×\99×\9d × ×ª×\9e×\9b×\99×\9d: <code dir="ltr">$1</code> (×\90×\99×\9f ×\9c×\94×\95ס×\99×£ ×\90×\95ת×\9d ×\91×\97×\99פ×\95ש).',
+פר×\95×\98×\95ק×\95×\9c×\99×\9d × ×ª×\9e×\9b×\99×\9d: <code dir="ltr">$1</code> (×\91ר×\99רת ×\94×\9e×\97×\93×\9c ×\94×\99×\90 <span dir="ltr">http://</span> ×\90×\9d ×\9c×\90 צ×\95×\99×\9f פר×\95×\98×\95ק×\95×\9c).',
'linksearch-line' => '$1 מקושר מהדף $2',
'linksearch-error' => 'תווים כלליים יכולים להופיע רק בתחילת שם השרת.',
# Watchlist
'watchlist' => 'רשימת המעקב שלי',
-'mywatchlist' => 'רש×\99×\9eת ×\94×\9eעק×\91 ש×\9c×\99',
+'mywatchlist' => 'רש×\99×\9eת ×\9eעק×\91',
'watchlistfor2' => 'עבור $1 $2',
'nowatchlist' => 'אין דפים ברשימת המעקב.',
'watchlistanontext' => 'עליכם $1 כדי לצפות או לערוך פריטים ברשימת המעקב.',
# Contributions
'contributions' => 'תרומות המשתמש',
'contributions-title' => 'תרומות של המשתמש $1',
-'mycontris' => '×\94תר×\95×\9e×\95ת ש×\9c×\99',
+'mycontris' => 'תר×\95×\9e×\95ת',
'contribsub2' => 'עבור $1 ($2)',
'nocontribs' => 'לא נמצאו שינויים המתאימים לקריטריונים אלו.',
'uctop' => '(אחרון)',
'duration-centuries' => '{{PLURAL:$1|מאה שנה|מאתיים שנה|$1 מאות שנים}}',
'duration-millennia' => '{{PLURAL:$1|אלף שנה|אלפיים שנה|$1 אלפי שנים}}',
+# Unknown messages
+'mytalk-parenthetical' => 'שיחה',
);
'newwindow' => '(wočinja so w nowym woknje)',
'cancel' => 'Přetorhnyć',
'moredotdotdot' => 'Wjace…',
-'mypage' => 'Moja strona',
-'mytalk' => 'moja diskusija',
+'mypage' => 'Strona',
+'mytalk' => 'Diskusija',
'anontalk' => 'Diskusijna strona tuteje IP.adresy',
'navigation' => 'Nawigacija',
'and' => ' a',
# Preferences page
'preferences' => 'Nastajenja',
-'mypreferences' => 'nastajenja',
+'mypreferences' => 'Nastajenja',
'prefs-edits' => 'Ličba změnow:',
'prefsnologin' => 'Njepřizjewjeny',
'prefsnologintext' => 'Dyrbiš <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} přizjewjeny]</span> być, zo by móhł nastajenja postajić.',
'linksearch-ok' => 'Pytać',
'linksearch-text' => 'Zastupniske znamješka kaž "*.wikipedia.org" móža so wužiwać.
Znajmjeńša hłowna domena je trěbna, na přikład "*.org".<br />
-Podpěrowane protokole: <code>$1</code> (prošu njepodaj je w swojim pytanje).',
+Podpěrowane protokole: <code>$1</code> (standard je http://, jeli žadyn protokol njeje podaty).',
'linksearch-line' => '$1 je z $2 wotkazany.',
'linksearch-error' => 'Zastupniske znamjenja dadźa so jenož na spočatku URL wužiwać.',
# Watchlist
'watchlist' => 'wobkedźbowanki',
-'mywatchlist' => 'wobkedźbowanki',
+'mywatchlist' => 'Wobkedźbowanki',
'watchlistfor2' => 'Za wužiwarja $1 $2',
'nowatchlist' => 'Nimaš žane strony w swojich wobkedźbowankach.',
'watchlistanontext' => 'Dyrbiš so $1, zo by swoje wobkedźbowanki wobhladać abo wobdźěłać móhł.',
# Contributions
'contributions' => 'Přinoški wužiwarja',
'contributions-title' => 'Wužiwarske přinoški wot „$1“',
-'mycontris' => 'moje přinoški',
+'mycontris' => 'Přinoški',
'contribsub2' => 'za wužiwarja $1 ($2)',
'nocontribs' => 'Žane změny, kotrež podatym kriterijam wotpowěduja.',
'uctop' => '(aktualnje)',
'whatlinkshere-hideredirs' => 'Daleposrědkowanja $1',
'whatlinkshere-hidetrans' => 'Zapřijeća $1',
'whatlinkshere-hidelinks' => 'Wotkazy $1',
-'whatlinkshere-hideimages' => 'wobrazowe wotkazy $1',
+'whatlinkshere-hideimages' => 'Datajowe wotkazy $1',
'whatlinkshere-filters' => 'Filtry',
# Block/unblock
'duration-centuries' => '$1 {{PLURAL:$1|lětstotk|lětstotkaj|lětstotki|lětstotkow}}',
'duration-millennia' => '$1 {{PLURAL:$1|lěttysac|lěttysacaj|lěttysacy|lěttysacow}}',
+# Unknown messages
+'mytalk-parenthetical' => 'diskusija',
);
Már létezik.',
'defaultmessagetext' => 'Alapértelmezett szöveg',
+# Content models
+'content-model-wikitext' => 'wikiszöveg',
+'content-model-text' => 'egyszerű szöveg',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
+
# Parser/template warnings
'expensive-parserfunction-warning' => 'Figyelem: ezen a lapon túl sok erőforrásigényes elemzőfüggvény-hívás található.
# Preferences page
'preferences' => 'Beállítások',
-'mypreferences' => 'Beállításaim',
+'mypreferences' => 'Beállítások',
'prefs-edits' => 'Szerkesztéseid száma:',
'prefsnologin' => 'Nem jelentkeztél be',
'prefsnologintext' => 'Saját beállításaid elmentéséhez <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} be kell jelentkezned.] </span>',
'linksearch-ns' => 'Névtér:',
'linksearch-ok' => 'keresés',
'linksearch-text' => 'Helyettesítő karaktereket is lehet használni, például "*.wikipedia.org". Legalább egy felső szintű tartománynak lennie kell, például "*.org"<br />
-Támogatott protokollok: <code>$1</code> (ezeket ne írd be a keresésbe).',
+Támogatott protokollok: <code>$1</code> (http:// az alapértelmezett, ha nincs protokoll megadva).',
'linksearch-line' => '$1 hivatkozva innen: $2',
'linksearch-error' => 'Helyettesítő karakterek csak a cím elején szerepelhetnek.',
'whatlinkshere-hideredirs' => 'átirányítások $1',
'whatlinkshere-hidetrans' => 'beillesztések $1',
'whatlinkshere-hidelinks' => 'linkek $1',
-'whatlinkshere-hideimages' => 'képhivatkozás $1',
+'whatlinkshere-hideimages' => 'fájlhivatkozások $1',
'whatlinkshere-filters' => 'Elemek szűrése',
# Block/unblock
'cascadeprotected' => 'Այս էջը պաշտպանված է խմբագրումից, քանի որ ընդգրկված է հետևյալ {{PLURAL:$1|էջի|էջերի}} տեքստում, {{PLURAL:$1|որը|որոնք}} պաշտպանվել {{PLURAL:$1|է|են}} կասկադային հնարավորությամբ.
$2',
'namespaceprotected' => 'Դուք չունեք «$1» անվանատարածքի էջերի խմբագրման իրավունք։',
+'customcssprotected' => 'Դուք չեք կարող խմբագրել այս CSS էջը, քանի որ այն պարունակում է այլ մասնակցի անձնական նախընտրանքներ։',
+'customjsprotected' => 'Դուք չեք կարող խմբագրել այս ՋավաՍկրիպտ էջը, քանի որ այն պարունակում է այլ մասնակցի անձնական նախընտրանքներ։',
'ns-specialprotected' => '«{{ns:special}}» անվանատարածքի էջերը չեն կարող խմբագրվել։',
'titleprotected' => "Այս անվանմամբ էջի ստեղծումը արգելվել է [[User:$1|$1]] մասնակցի կողմից։
Տրված պատճառն է՝ ''$2''։",
+'exception-nologin' => 'Չեք մտել համակարգ',
+'exception-nologin-text' => 'Այս էջը դիտելու կամ գործողություն կատարելու համար դուք պետք է մուտք գործեք այս վիքի։',
# Virus scanner
'virus-badscanner' => "Սխալ կարգավորւմ։ Անծանոթ վիրուսների զննիչ. ''$1''",
'yourpasswordagain' => 'Կրկնեք գաղտնաբառը.',
'remembermypassword' => 'Հիշել իմ մուտքագրված տվյալները այս համակարգչում ($1 {{PLURAL:$1|օրից|օրից}} ոչ ավել ժամկետով)',
'yourdomainname' => 'Ձեր դոմենը.',
+'password-change-forbidden' => 'Այս վիքիում չեք կարող փոխել գաղտնաբառ։',
'externaldberror' => 'Տեղի է ունեցել վավերացման արտաքին տվյալների բազայի սխալ, կամ դուք չունեք բավարար իրավունքներ ձեր արտաքին հաշվի փոփոխման համար։',
'login' => 'Մտնել',
'nav-login-createaccount' => 'Մտնել / Գրանցվել',
'createaccounterror' => 'Չհաջողվեց ստեղծել մասնակցային հաշիվ. $1',
'nocookiesnew' => 'Մասնակցային հաշիվը ստեղծված է, սակայն մուտքը համակարգ չհաջողվեց։ {{SITENAME}} կայքը օգտագործում է «քուքիներ» մասնակիցների վավերացման համար։ Ձեր մոտ «քուքիները» արգելված են։ Խնդրում ենք թույլատրել սրանք, ապա մտնել համակարգ ձեր նոր մասնակցի անունով և գաղտնաբառով։',
'nocookieslogin' => '{{SITENAME}} կայքը օգտագործում է «քուքիներ» մասնակիցների վավերացման համար։ Ձեր մոտ «քուքիները» արգելված են։ Խնդրում ենք թույլատրել սրանք և փորձել կրկին։',
+'nocookiesfornew' => 'Մասնակցային հաշիվը չհաջողվեց ստեղծվել, քանի որ հնարավոր չեր վավերացնել աղբյուրը։
+Ստուգեք, որ ձեզ մոտ թույլատրված են քուկիները, վերբեռնեք էջը և փորձեք կրկին։',
'noname' => 'Դուք չեք նշել թույլատրելի մասնակցային անուն։',
'loginsuccesstitle' => 'Բարեհաջող մուտք',
'loginsuccess' => "'''Դուք մուտք գործեցիք {{SITENAME}}, որպես \"\$1\"։'''",
'noemailprefs' => 'Այս հնարավորության գործածման համար անհրաժեշտ է նշել էլ-փոստի հասցե։',
'emailconfirmlink' => 'Վավերացնել ձեր էլ-փոստի հասցեն',
'invalidemailaddress' => 'Նշված էլ-փոստի հասցեն անընդունելի է, քանի որ այն ունի անթույլատրելի ֆորմատ։ Խնդրում ենք նշել ճշմարիտ հասցե կամ այս դաշտը թողնել դատարկ։',
+'emaildisabled' => 'Այս կայքը չի կարող ուղարկել էլ․ նամակներ։',
'accountcreated' => 'Հաշիվը ստեղծված է',
'accountcreatedtext' => '$1 մասնակցի հաշիվը ստեղծված է։',
'createaccount-title' => '{{SITENAME}}. մասնակցային հաշվի ստեղծում',
# E-mail sending
'php-mail-error-unknown' => 'Անհայտ սխալ PHP-ի mail() ֆունկցիայում',
+'user-mail-no-addy' => 'Փորձվեց ուղարկել էլ․ նամակ առանց էլ․ հասցեի։',
# Change password dialog
'resetpass' => 'Փոխել գաղտնաբառը',
'passwordreset-username' => 'Մասնակցի անուն.',
'passwordreset-emailelement' => 'Մասնակցային անուն. $1
Ժամանակավոր գաղտնաբառ. $2',
+'passwordreset-emailsent' => 'Ուղարկվեց հիշեցնող էլ․ նամակ։',
+'passwordreset-emailsent-capture' => 'Ուղարկվեց հիշեցնող էլ․ նամակ։ Այն ներկայացված է ստորև։',
+'passwordreset-emailerror-capture' => 'Ուղարկվեց հիշեցնող էլ․ նամակ։ Այն ներկայացված է ստորև։ Սակայն մասնակցին ուղարկելը չհաջողվեց․',
# Special:ChangeEmail
'changeemail' => 'Փոխել էլ. հասցեն',
+'changeemail-header' => 'Փոխել հաշվի էլ․ հասցեն',
+'changeemail-oldemail' => 'Ներկա էլ․ հասցե․',
+'changeemail-newemail' => 'Նոր էլ․ հասցե․',
+'changeemail-none' => '(ոչ մի)',
'changeemail-submit' => 'Խմբագրել էլ․ հասցեն',
'changeemail-cancel' => 'Չեղարկել',
Համակարգ մուտք գործելուն պես կարող եք ''[[Special:ChangePassword|փոխել գաղտնաբառը]]''։",
'newarticle' => '(Նոր)',
-'newarticletext' => "Դուք հղվել եք դեռևս գոյություն չունեցող էջի։ Էջը ստեղծելու համար սկսեք տեքստի մուտքագրումը ներքևի արկղում (այցելեք [[{{MediaWiki:Helppage}}|օգնության էջը]]՝ մանրամասն տեղեկությունների համար)։ Եթե դուք սխալմամբ եք այստեղ հայտնվել, ապա մատնահարեք ձեր զննարկիչի '''back''' կոճակը։",
+'newarticletext' => "Դուք հղվել եք դեռևս գոյություն չունեցող էջի։
+Նոր էջ ստեղծելու համար ներքևում գտնվող խմբագրման դաշտում ավելացրեք ձեր տեքստը, այնուհետև սեղմեք '''Հիշել էջը''' (այցելեք [[{{MediaWiki:Helppage}}|օգնության էջը]]՝ մանրամասն տեղեկությունների համար)։
+
+Եթե դուք սխալմամբ եք այստեղ հայտնվել, ապա սեղմեք ձեր զննարկիչի '''հետ''' (back) կոճակը։",
'anontalkpagetext' => "{| style=\"background-repeat:no-repeat; background-position:800px -20px; margin:0.5em 0 0.5em 0; clear:both;\" width=100% class=toccolours
|-
| <span class=\"plainlinksneverexpand\">''Այս քննարկման էջը պատկանում է չգրանցված կամ համակարգ չմտած մասնակցի, ով խմբագրում կատարելիս օգտվել է {{BASEPAGENAME}} ԱյՓի հասցեից։''
'mailnologin' => 'Ուղարկման հասցե չկա',
'mailnologintext' => 'Անհրաժեշտ է [[Special:UserLogin|մտնել համակարգ]] և ունենալ գործող էլ-փոստի հասցե ձեր [[Special:Preferences|նախընտրություններում]]՝ ուրիշ մասնակիցներին էլեկտրոնային նամակներ ուղարկելու համար։',
'emailuser' => 'էլ-նամակ ուղարկել այս մասնակցին',
+'emailuser-title-target' => 'Ուղարկել էլ․ նամակ {{GENDER:$1|մասնակցին}}',
+'emailuser-title-notarget' => 'Ուղարկել էլ․ նամակ',
'emailpage' => 'Էլ-նամակ ուղարկել մասնակցին',
-'emailpagetext' => 'Եթե այս մասնակիցը նշել է գործող էլ-փոստի հասցե իր նախընտրություններում, ապա ստորև բերված ձևով հնարավոր է ուղարկել նրան էլ-նամակ։
-Այն էլ-հասցեն, որը դուք նշել եք ձեր նախընտրություններում, կերևա «Ումից» դաշտում, ուստի ստացողը հնարավորություն կունենա պատասխանել։',
+'emailpagetext' => 'Դուք կարող եք օգտագործել ներքևի ձևը այս {{GENDER:$1|մասնակցին}} էլ-նամաակ ուղարկելու համար։
+
+Ձեր նախընտրանքներում նշված էլ-հասցեն կերևա «Ումից» դաշտում և ստացողը կարող է անմիջապես պատասխանել ձեզ։',
'usermailererror' => 'Նամակն ուղարկելիս սխալ է վերադարձվել.',
-'defemailsubject' => '{{SITENAME}} e-mail',
+'defemailsubject' => '{{SITENAME}} էլ-նամակ',
+'usermaildisabled' => 'Էլ․ նամակ ուղարկելը թույլատրված չէ։',
+'usermaildisabledtext' => 'Այս վիքիում չեք կարղ էլ․ նամակ ուղարկել այլ մասնակիցների',
'noemailtitle' => 'Չկա էլ-փոստի հասցե',
'noemailtext' => 'Այս մասնակիցը չի նշել էլ-փոստի հասցե կամ նախընտրել է չստանալ էլ-նամակներ այլ մասնակիցներից։',
+'email-legend' => 'Ուղարկել էլ․ նամակ {{SITENAME}}յի այլ մասնակցի',
'emailfrom' => 'Ումից.',
'emailto' => 'Ում.',
'emailsubject' => 'Թեմա.',
'undelete-bad-store-key' => 'Չհաջողվեց վերականգնել նիշքի $1 ժամդրոշմով տարբերակը. նիշքը բացակայում էր ջնջումից առաջ։',
'undelete-cleanup-error' => 'Տեղի ունեցավ սխալ չօգտագործվող արխիվացված «$1» նիշքը ջնջելիս։',
'undelete-missing-filearchive' => 'Չհաջողվեց վերականգնել $1 արխիվային իդենտիֆիկատորով նիշքը, քանի որ այն բացակայում է տվյալների բազայից։ Հնարավոր է այն արդեն վերականգնվել է։',
+'undelete-error' => 'Սխալ էջը վերականգնելիս։',
'undelete-error-short' => 'Նայլի վերականգնման սխալ. $1',
'undelete-error-long' => 'Տեղի են ունեցել սխալներ նիշքը վերականգնելու ընթացքում.
$1',
+'undelete-show-file-submit' => 'Այո',
# Namespace form on various pages
'namespace' => 'Անվանատարածք.',
'sp-contributions-logs' => 'տեղեկամատյաններ',
'sp-contributions-talk' => 'քննարկում',
'sp-contributions-userrights' => 'մասնակիցների իրավունքների կառավարում',
+'sp-contributions-blocked-notice' => 'Այս մասնակիցը ներկա պահին արգելափակված է։
+Ստորև ներկայացված է արգելափակման տեղեկամատյանի վերջին գրառումը.',
+'sp-contributions-blocked-notice-anon' => 'Այս IP հասցեն ներկա պահին արգելափակված է։
+Ստորև ներկայացված է արգելափակման տեղեկամատյանի վերջին գրառումը.',
'sp-contributions-search' => 'Որոնել ներդրումները',
'sp-contributions-username' => 'IP-հասե կամ մասնակցի անուն.',
'sp-contributions-toponly' => 'Ցույց տալ միայն այն խմբագրումները, որոնք վերջին փոփոխություն են',
'whatlinkshere-hideredirs' => '$1 վերահղում',
'whatlinkshere-hidetrans' => '$1 ներառումները',
'whatlinkshere-hidelinks' => '$1 հղում',
+'whatlinkshere-hideimages' => '$1 նիշքային հղումներ',
'whatlinkshere-filters' => 'Զտիչներ',
# Block/unblock
+'autoblockid' => 'Ավտոմատ արգելափակում #$1',
+'block' => 'Արգելափակել մասնակցին',
+'unblock' => 'Արգելափակումից հանել',
'blockip' => 'Մասնակցի արգելափակում',
+'blockip-title' => 'Արգելափակել մասնակցին',
'blockip-legend' => 'Մասնակցի արգելափակում',
'blockiptext' => 'Օգտագործեք ստորև բերված ձևը որոշակի IP-հասցեից կամ մասնակցի անունից գրելու հնարավորությունը արգելափակելու համար։
Նման բան հարկավոր է անել միայն վանդալության կանխարգելման նպատակով և համաձայն [[{{MediaWiki:Policy-url}}|կանոնակարգի]]։
'ipusubmit' => 'Հանել արգելափակումը',
'unblocked' => '[[User:$1|$1]] մասնակիցը անարգելված է։',
'unblocked-id' => '$1 արգելափակումը հանված է',
+'blocklist' => 'Արգելափակված մասնակիցներ։',
'ipblocklist' => 'Արգելափակված IP-հասցեները և մասնակիցները',
'ipblocklist-legend' => 'Արգելափակված մասնակցի որոնում',
'ipblocklist-submit' => 'Որոնել',
'pagemovedsub' => 'Էջը վերանվանվեց',
'movepage-moved' => "'''«$1» էջը վերանվանվել է «$2»'''",
'movepage-moved-redirect' => 'Ստեղծվել է վերահղում։',
+'movepage-moved-noredirect' => 'Վերահղման ստեղծում թույլ չի տրվել',
'articleexists' => 'Այդ անվանմամբ էջ արդեն գոյություն ունի կամ ձեր ընտրած անվանումը անթույլատրելի է։
Խնդրում ենք ընտրել այլ անվանում։',
'talkexists' => "'''Էջը հաջողությամբ տեղափոխվեց, սակայն կցված քննարկման էջը հնարավոր չէր տեղափոխել, քանի որ նոր անվանմամբ էջ արդեն գոյություն ուներ։ Խնդրում ենք միաձուլել դրանք ձեռքով։'''",
# Special:ComparePages
'compare-page1' => 'Էջ 1',
'compare-page2' => 'Էջ 2',
+'compare-submit' => 'Համեմատել',
# Database error messages
'dberr-header' => 'Այս վիքիում խնդիրներ են առաջացել',
'logentry-newusers-newusers' => '$1 մասնակիցը ստեղծեց նոր հաշիվ',
'logentry-newusers-create' => '$1 մասնակիցը ստեղծեց նոր հաշիվ',
'logentry-newusers-create2' => '$1 Ստեղծեց նոր հաշիվ $3',
+'newuserlog-byemail' => 'Գաղտնաբառն ուղարկված է էլ․ փոստով',
+
+# Feedback
+'feedback-subject' => 'Թեմա.',
+'feedback-message' => 'Հաղորդագրություն․',
+'feedback-close' => 'Արված է',
# Search suggestions
'searchsuggest-search' => 'Որոնել',
* @author Malafaya
* @author McDutchie
* @author Reedy
+ * @author Yfdyh000
* @author לערי ריינהארט
*/
'statistics-mostpopular' => 'Le paginas plus visitate',
'disambiguations' => 'Paginas con ligamines a paginas de disambiguation',
-'disambiguationspage' => 'Template:Disambiguation',
+'disambiguationspage' => 'Template:Disambig
+Template:Disambiguation',
'disambiguations-text' => "Le sequente paginas contine al minus un ligamine a un '''pagina de disambiguation'''.
Istes debe forsan ligar directemente al articulo sur le thema in question.<br />
Un pagina se tracta como pagina de disambiguation si illo usa un patrono que es ligate ab [[MediaWiki:Disambiguationspage]].",
'underline-always' => 'Kanayon',
'underline-never' => 'Saan uray kaanoman',
-'underline-default' => 'Kasisigud a pagbasabasa',
+'underline-default' => 'Kasisigud a kudil wenno pagbasabasa',
# Font style option in Special:Preferences
'editfont-style' => 'Urnosen ti kita ti letra iti lugar:',
'newwindow' => '(aglukat iti sabali a tawa)',
'cancel' => 'Ukasen',
'moredotdotdot' => 'Adu pay...',
-'mypage' => 'Panidko',
-'mytalk' => 'Pakitungtungak',
+'mypage' => 'Panid',
+'mytalk' => 'Tungtungan',
'anontalk' => 'Tungtungan para iti daytoy a pagtaengan ti IP',
'navigation' => 'Pagdaliasatan',
'and' => ' ken',
'note' => "'''Paammo:'''",
'previewnote' => "'''Laglagipem a daytoy ket panagipadas laeng.'''
Dagiti sinukatam ket saan pay a naidulin!",
-'continue-editing' => 'Agtultuloy nga agurnos',
+'continue-editing' => 'Mapan idiay pagurnosan a lugar',
'previewconflict' => 'Daytoy a panagpadas ket agiparang ti testo dita ngato a panagurnos a lugar a kasla agparang no kayatmo nga idulin.',
'session_fail_preview' => "'''Pasensia! Saanmi a maaramid ti panag-urnos gapu ngamin ta naawanan ti gimong ti data.'''
Pangngaasi a padasem manen.
# Preferences page
'preferences' => 'Kaykayatan',
-'mypreferences' => 'Kaykayatko',
+'mypreferences' => 'Kaykayatan',
'prefs-edits' => 'Bilang dagiti inurnos:',
'prefsnologin' => 'Saan a nakastrek',
'prefsnologintext' => 'Masapul a <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} nakastrekka]</span> tapno makapili kadagiti kaykayatmo.',
'prefs-rc' => 'Kinaudi a binalbaliwan',
'prefs-watchlist' => 'Listaan ti bambantayan',
'prefs-watchlist-days' => 'Alaldaw nga iparang idiay listaan ti bambantayan:',
-'prefs-watchlist-days-max' => 'Kabayag nga $1 {{PLURAL:$1|nga aldaw|nga al-aldaw}}',
+'prefs-watchlist-days-max' => 'Kapaut nga $1 {{PLURAL:$1|nga aldaw|nga al-aldaw}}',
'prefs-watchlist-edits' => 'Kaadu a bilang ti ipakita kadagiti sinukatan iti napadakkel a bambantayan:',
'prefs-watchlist-edits-max' => 'Kaadu a bilang: 1000',
'prefs-watchlist-token' => 'Tandaan ti bambantayan:',
No adda makaammo daytoy a tulbek ditoy a pagikabilan ket mabalin da a basaen ti binambantayam, masapul nga agpilika ti pateg a seguridad.
Adda ditoy ti pugto a pateg a mausarmo: $1',
-'savedprefs' => 'Naidulin dagitoy kaykayatmon.',
+'savedprefs' => 'Naidulinen dagiti kakaykayatam.',
'timezonelegend' => 'Sona ti oras:',
'localtime' => 'Lokal nga oras:',
'timezoneuseserverdefault' => 'Usaren ti wiki a kasisigud ($1)',
'yourrealname' => 'Pudno a nagan:',
'yourlanguage' => 'Pagsasao:',
'yourvariant' => 'Linaon ti sabali a pagsasao:',
-'prefs-help-variant' => 'Ti kaykayatmo a sabsabali a panagsurat a maipakita kadagiti linaon ti panid daytoy a wiki.',
+'prefs-help-variant' => 'Ti kinaykayatmo a kita ti pagsasao wenno sabali a panagsurat a maipakita kadagiti linaon ti panid daytoy a wiki.',
'yournick' => 'Baro a pirma:',
'prefs-help-signature' => 'Komentario kadagiti pakipatangan a panid ket mapirmaan koma iti "<nowiki>~~~~</nowiki>" nga agpabalin ti pirmam ken ti petsa.',
'badsig' => 'Saan a pudno a kilaw a pirma.
'rightslogtext' => 'Listaan daytoy kadagiti sinukatan a karbengan ti agar-aramat.',
'rightslogentry' => 'sinukatan ti panagkameng iti bunggoy ti $1 manipud $2 iti $3',
'rightslogentry-autopromote' => 'naautomatiko a naipangato a naggapo iti $2 idiay $3',
+'logentry-rights-rights' => 'Ni $1 ket nangbaliw ti grupo a panakaikameng para kenni $3 manipud ti $4 iti $5',
+'logentry-rights-rights-legacy' => 'Ni $1 ket nangbaliw ti grupo a panakaikameng para kenni $3',
+'logentry-rights-autopromote' => 'Ni $1 ket automatiko idi a naipangato manipud ti $4 iti $5',
'rightsnone' => '(awan)',
# Associated actions - in the sentence "You do not have permission to X"
'linksearch-ok' => 'Biruken',
'linksearch-text' => 'Ti naataap a tarheta a kas "*.wikipedia.org" ket mabalin nga usaren.
Masapul ti kangatuan a pagturayan, a kaspagarigan "*.org".<br />
-Natapayaen a protokol: <code>$1</code> (saanmo nga inayon dagitoy iti panagbirukmo) .',
+Dagiti nasuportaran a protokol: <code>$1</code> (naipakasigud ti http:// no awan ti protokol a nainaganan).',
'linksearch-line' => 'Ti $1 ket nakasilpo idiay $2',
'linksearch-error' => 'Ti naatap a tarheta ket agparang laeng iti pinagrugi ti nagan ti agsangaili.',
'emailuser-title-target' => 'E-suratam daytoy nga {{GENDER:$1|agar-aramat}}',
'emailuser-title-notarget' => 'E-suratan ti agar-aramat',
'emailpage' => 'E-suratan ti agar-aramat',
-'emailpagetext' => 'Mabalinmo nga usaren ti kinabuklan dita baba nga agipatulod ti e-surat a mensahe daytoy nga agar-aramat.
+'emailpagetext' => 'Mabalinmo nga usaren ti kinabuklan dita baba nga agipatulod ti e-surat a mensahe ti daytoy nga {{GENDER:$1|agar-aramat}}.
Ti e-surat nga inkabilmo idiay [[Special:Preferences|kakaykayatam]] ket agparang a kas "Naggapu" a pagtaengan ti e-surat, tapno ti nagipatulodam ket makasungbat kenka.',
'usermailererror' => 'Kita ti surat ket nangisubli ti biddut:',
'defemailsubject' => '{{SITENAME}} e-surat naggapo ken ni "$1"',
# Watchlist
'watchlist' => 'Bambantayak',
-'mywatchlist' => 'Bambantayak',
+'mywatchlist' => 'Bambantayan',
'watchlistfor2' => 'Para iti $1 $2',
'nowatchlist' => 'Awan ti banag iti listaan dagiti bambantayam.',
'watchlistanontext' => 'Pangngaasim ti $1 tapno makitam dagiti inurnosmo dita bambantayam.',
# Contributions
'contributions' => 'Naaramidan dagiti agar-aramat',
'contributions-title' => 'Naaramidan ni $1',
-'mycontris' => 'Naaramidak',
+'mycontris' => 'Naar-aramid',
'contribsub2' => 'Para iti $1 ($2)',
'nocontribs' => 'Awan ti nasarakan a nasukatan a kapada daytoy a kita.',
'uctop' => '(rabaw)',
'whatlinkshere-hideredirs' => '$1 dagiti baw-ing',
'whatlinkshere-hidetrans' => '$1 dagiti mailaklak-am',
'whatlinkshere-hidelinks' => '$1 dagiti silpo',
-'whatlinkshere-hideimages' => '$1 dagiti silpo ti imahen',
+'whatlinkshere-hideimages' => '$1 a silsilpo ti papeles',
'whatlinkshere-filters' => 'Dagiti sagat',
# Block/unblock
'tooltip-upload' => 'Rugian ti agip-ipan',
'tooltip-rollback' => '"Baliktaden" isubli ti inurnos (dagiti inurnos) ti daytoy a panid ti kinaudi a nangaramid iti maysa a takla',
'tooltip-undo' => '"Ibabawi" ipasubli daytoy nga urnos ken lukatanna ti kinabuklan ti urnos iti panagpadas. Agpabalin daytoy a mangikabil ti rason idiay pinakabuklan.',
-'tooltip-preferences-save' => 'Idulin dagiti kaykayatmo',
+'tooltip-preferences-save' => 'Idulin dagiti kakaykayatam',
'tooltip-summary' => 'Ikabil ti bassit a pakabuklan',
# Metadata
# Info page
'pageinfo-title' => 'Pakaammo para iti "$1"',
-'pageinfo-not-current' => 'Ti pakaammo ket mabalin laeng a maiparang para iti agdama a panagbalbaliw.',
+'pageinfo-not-current' => 'Pasensia, saan a mabalin ti mangited ti pakaammo para kadagiti daan a panagbalbaliw.',
'pageinfo-header-basic' => 'Kangrunaan a pakaammuan',
'pageinfo-header-edits' => 'Pakasaritaan ti inurnos',
'pageinfo-header-restrictions' => 'Panagsalaknib ti panid',
'pageinfo-default-sort' => 'Kasisigud a kangrunaan a panagilasin',
'pageinfo-length' => 'Kaatiddog ti panid (kadagiti byte)',
'pageinfo-article-id' => 'ID ti panid',
+'pageinfo-language' => 'Pagsasao ti naglaon a panid',
'pageinfo-robot-policy' => 'Kasasaad ti panagbiruk a makina',
'pageinfo-robot-index' => 'Mabalin a maipasurotan',
'pageinfo-robot-noindex' => 'Saan a mabalin a maipasurotan',
'version-license' => 'Lisensia',
'version-poweredby-credits' => "Daytoy a wiki ket pinaandar ti '''[//www.mediawiki.org/ MediaWiki]''', karbengan a kopia © 2001-$1 $2.",
'version-poweredby-others' => 'dadduma pay',
+'version-credits-summary' => 'Kayat mi kuma a pammadayawan dagiti sumaganad a tao para kadagiti inparawadda ti [[Special:Version|MediaWiki]].',
'version-license-info' => 'Ti MediaWiki ket nawaya a software; maiwarasmo ken/wenno mabaliwam babaen ti banag iti GNU General Public License a naipablaak babaen ti Free Software Foundation; nupay iti bersion 2 iti Lisensia, wenno (ti panagpilim) ti ania man a bersion.
Ti MediaWiki ket naiwarwaras nga adda ti namnama a makatulong, ngem AWAN TI ANIA MAN A GARANTIA; nga awan pay ti naibagbaga a PANAKAILAKO wenno KALAINGAN NA ITI DAYTOY A PANGGEP. Kitaen ti GNU Sapasap a Publiko a Lisensia para kadagiti adu pay a salaysay.
'duration-centuries' => '$1 {{PLURAL:$1|siglo|sig-siglo}}',
'duration-millennia' => '$1 {{PLURAL:$1|milenio|mil-milenio}}',
+# Unknown messages
+'mytalk-parenthetical' => 'tungtungan',
);
'newwindow' => '(si apre in una nuova finestra)',
'cancel' => 'Annulla',
'moredotdotdot' => 'Altro...',
-'mypage' => 'La mia pagina',
-'mytalk' => 'mie discussioni',
+'mypage' => 'Pagina',
+'mytalk' => 'discussioni',
'anontalk' => 'Discussioni per questo IP',
'navigation' => 'Navigazione',
'and' => ' e',
'linksearch-ok' => 'Cerca',
'linksearch-text' => 'È possibile fare uso di metacaratteri, ad esempio "*.wikipedia.org".<br />
È necessario almeno un dominio di primo livello, ad esempio "*.org".<br />
-Protocolli supportati: <code>$1</code> (non aggiungere nessuno di questi nella tua ricerca).',
+Protocolli supportati: <code>$1</code> (predefinito http:// se nessun protocollo è specificato).',
'linksearch-line' => '$1 presente nella pagina $2',
'linksearch-error' => "I metacaratteri possono essere usati solo all'inizio dell'indirizzo.",
# Contributions
'contributions' => 'Contributi utente',
'contributions-title' => 'Contributi di $1',
-'mycontris' => 'miei contributi',
+'mycontris' => 'contributi',
'contribsub2' => 'Per $1 ($2)',
'nocontribs' => 'Non sono state trovate modifiche che soddisfino i criteri di ricerca.',
'uctop' => '(ultima per la pagina)',
'whatlinkshere-hideredirs' => '$1 redirect',
'whatlinkshere-hidetrans' => '$1 inclusioni',
'whatlinkshere-hidelinks' => '$1 link',
-'whatlinkshere-hideimages' => '$1 link da immagini',
+'whatlinkshere-hideimages' => '$1 link da file',
'whatlinkshere-filters' => 'Filtri',
# Block/unblock
'pageinfo-robot-index' => 'Indicizzabile',
'pageinfo-robot-noindex' => 'Non indicizzabile',
'pageinfo-views' => 'Numero di visualizzazioni',
-'pageinfo-watchers' => 'Numero di utenti che hanno la pagina nei loro Osservati Speciali',
+'pageinfo-watchers' => 'Numero di utenti che hanno la pagina nei loro osservati speciali',
'pageinfo-redirects-name' => 'Redirect a questa pagina',
'pageinfo-subpages-name' => 'Sottopagine di questa pagina',
'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirect}}; $3 {{PLURAL:$3|non redirect}})',
'duration-centuries' => '$1 {{PLURAL:$1|secolo|secoli}}',
'duration-millennia' => '$1 {{PLURAL:$1|millennio|millenni}}',
+# Unknown messages
+'mytalk-parenthetical' => 'discussioni',
);
'newwindow' => '(新しいウィンドウで開きます)',
'cancel' => '中止',
'moredotdotdot' => '続き...',
-'mypage' => '自分のページ',
-'mytalk' => '自分のトーク',
+'mypage' => 'ページ',
+'mytalk' => 'トーク',
'anontalk' => 'このIPアドレスのトーク',
'navigation' => '案内',
'and' => ' および ',
この情報は公開されます。',
'email' => 'メール',
'prefs-help-realname' => '本名は省略できます。
-入力すると、あなたの著作物の帰属表記に本名を使用します。',
+入力すると、あなたの著作物の帰属表示に使われます。',
'prefs-help-email' => 'メールアドレスは省略できますが、パスワードを忘れた際にパスワードをリセットするのに必要です。',
'prefs-help-email-others' => '利用者ページやトークページ上のリンクを通じて、他の利用者があなたにメールで連絡を取れるようにすることもできます。
他の利用者が連絡を取る際にあなたのメールアドレスが開示されることはありません。',
# Special:LinkSearch
'linksearch' => '外部リンクの検索',
-'linksearch-pat' => '検索パターン:',
+'linksearch-pat' => '検索パターン:',
'linksearch-ns' => '名前空間:',
'linksearch-ok' => '検索',
-'linksearch-text' => '"*.wikipedia.org" のようにワイルドカードを使用できます。
-少なくとも "*.org" のようなトップレベルドメインが必要です。<br />
-対å¿\9cã\83\97ã\83ã\83\88ã\82³ã\83«: <code>$1</code> (ã\81\93ã\82\8cã\82\89ã\82\92æ¤\9cç´¢ã\81«å\90«ã\82\81ã\81ªã\81\84ã\81§ã\81\8fã\81 ã\81\95ã\81\84)。',
+'linksearch-text' => '「*.wikipedia.org」のようにワイルドカードを使用できます。
+少なくとも「*.org」のようなトップレベルドメインが必要です。<br />
+対å¿\9cã\83\97ã\83ã\83\88ã\82³ã\83«: <code>$1</code> (ã\83\97ã\83ã\83\88ã\82³ã\83«ã\82\92ç\9c\81ç\95¥ã\81\97ã\81\9få ´å\90\88ã\81®æ\97¢å®\9aå\80¤ã\81¯ http:// )。',
'linksearch-line' => '$1 が $2 からリンクされています',
'linksearch-error' => 'ワイルドカードはホスト名の先頭でのみ使用できます。',
# Special:ListUsers
-'listusersfrom' => '最初に表示する利用者:',
+'listusersfrom' => '最初に表示する利用者:',
'listusers-submit' => '表示',
'listusers-noresult' => '利用者が見つかりませんでした。',
-'listusers-blocked' => '(ブロック中)',
+'listusers-blocked' => '(ブロック中)',
# Special:ActiveUsers
'activeusers' => '活動中の利用者一覧',
'activeusers-intro' => 'これは過去 $1 {{PLURAL:$1|日|日間}}に何らかの活動をした利用者の一覧です。',
'activeusers-count' => '過去 {{PLURAL:$3|1 日|$3 日間}}に $1 {{PLURAL:$1|回の編集}}',
-'activeusers-from' => '最初に表示する利用者:',
+'activeusers-from' => '最初に表示する利用者:',
'activeusers-hidebots' => 'ボットを隠す',
'activeusers-hidesysops' => '管理者を隠す',
'activeusers-noresult' => '利用者が見つかりませんでした。',
# Contributions
'contributions' => '利用者の投稿記録',
'contributions-title' => '$1の投稿記録',
-'mycontris' => '自分の投稿記録',
+'mycontris' => '投稿記録',
'contribsub2' => '利用者: $1 ($2)',
'nocontribs' => 'これらの条件に一致する変更は見つかりませんでした。',
'uctop' => '(最新)',
'whatlinkshere-hideredirs' => '転送ページを$1',
'whatlinkshere-hidetrans' => '参照読み込みを$1',
'whatlinkshere-hidelinks' => 'リンクを$1',
-'whatlinkshere-hideimages' => '画像リンクを$1',
+'whatlinkshere-hideimages' => 'ファイルへのリンクを$1',
'whatlinkshere-filters' => '絞り込み',
# Block/unblock
'unblockiptext' => '以下のフォームで利用者またはIPアドレスのブロックを解除できます。',
'ipusubmit' => 'このブロックを解除',
'unblocked' => '[[User:$1|$1]]のブロックを解除しました',
-'unblocked-range' => '$1ã\81®ã\83\96ã\83ã\83\83ã\82¯ã\81¯è§£é\99¤ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99',
+'unblocked-range' => '$1ã\81®ã\83\96ã\83ã\83\83ã\82¯ã\82\92解é\99¤ã\81\97ã\81¾ã\81\97ã\81\9f',
'unblocked-id' => 'ブロック$1は除去されました',
'blocklist' => 'ブロックされている利用者',
'ipblocklist' => 'ブロックされている利用者',
# Info page
'pageinfo-title' => '「$1」の情報',
-'pageinfo-not-current' => 'ç\8f¾å\9c¨ã\81®ã\83\90ã\83¼ã\82¸ã\83§ã\83³ã\81®æ\83\85å ±ã\81®ã\81¿ã\81\8c表示ã\81\95ã\82\8cã\82\8bå\8f¯è\83½æ\80§ã\81\8cã\81\82ã\82\8aã\81¾ã\81\99。',
+'pageinfo-not-current' => 'ç\94³ã\81\97訳ã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\81\8cã\80\81é\81\8eå\8e»ã\81®ç\89\88ã\81®æ\83\85å ±ã\81¯è¡¨ç¤ºã\81§ã\81\8dã\81¾ã\81\9bã\82\93。',
'pageinfo-header-basic' => '基本情報',
'pageinfo-header-edits' => '編集履歴',
'pageinfo-header-restrictions' => 'ページの保護',
'newwindow' => '(ახალ ფანჯარაში)',
'cancel' => 'გაუქმება',
'moredotdotdot' => 'ვრცლად...',
-'mypage' => 'á\83©á\83\94á\83\9bá\83\98 á\83\92á\83\95á\83\94á\83 á\83\93á\83\98',
+'mypage' => 'გვერდი',
'mytalk' => 'ჩემი განხილვა',
'anontalk' => 'ამ IP-ს განხილვა',
'navigation' => 'ნავიგაცია',
'moveddeleted-notice' => 'ھیہ ای حذف شدہ صفحہ شیر.
صفحو نوشتۂ حذف شدگی و منتقلی ذیلا بطورِ حوالہ دیونو بویان.',
+# Parser/template warnings
+'post-expand-template-inclusion-category' => 'ھش صفحات کہ ھتیرا ٹمپلیٹ یعنی سانچو ناپ لوٹ بیتی شیر۔',
+'post-expand-template-argument-category' => 'ھش صفحات کہ ھتیرا بوغینو بیرو سانچان یعنی(ٹمپلیٹان) لو شینی۔',
+
# History pages
'viewpagelogs' => 'ھیہ صفحہو بچے نوشتہ جاتن لوڑے',
'currentrev-asof' => 'حالیہ نظرثانی بمطابق $1',
# Statistics
'statistics' => 'اعداد و شمار',
+'disambiguationspage' => 'سانچہ: ڈسایمبگ',
+
# Miscellaneous special pages
'nbytes' => '$1 {{PLURAL:$1|بایٹ|بایٹس}}',
'nmembers' => '$1 {{PLURAL:$1|ممبار|ممباران}}',
'watchlisttools-edit' => 'لوڑے یا واچ لسٹہ ترمیم کورے',
'watchlisttools-raw' => 'نوغ واچ لسٹان ایڈیٹ کورے',
+# Core parser functions
+'duplicate-defaultsort' => '\'\'\'خبردار:\'\'\' ڈیفالٹ تاڑٰ(نغڑی) "$2" پروشٹیو ڈیفالٹ تاڑا "$1" لیگی شیر۔',
+
# Special:SpecialPages
'specialpages' => 'اسپیشل صفحہ',
'whatlinkshere-hideredirs' => 'peyser sono $1',
'whatlinkshere-hidetrans' => 'İlawekerdê çaprazi $1',
'whatlinkshere-hidelinks' => '$1 girey',
-'whatlinkshere-hideimages' => 'girê resmu $1',
+'whatlinkshere-hideimages' => 'Girê dosya $1',
'whatlinkshere-filters' => 'Filtrey',
# Block/unblock
'newwindow' => '(새 창으로 열림)',
'cancel' => '취소',
'moredotdotdot' => '더 보기...',
-'mypage' => 'ë\82´ ì\82¬ì\9a©ì\9e\90 문ì\84\9c',
-'mytalk' => '내 사용자 토론',
+'mypage' => '문서',
+'mytalk' => '토론',
'anontalk' => '익명 사용자 토론',
'navigation' => '둘러보기',
'and' => ',',
'mailerror' => '메일 보내기 오류: $1',
'acct_creation_throttle_hit' => '당신의 IP 주소를 이용한 방문자가 이전에 이미 계정을 $1개 만들어, 계정 만들기 한도를 초과하였습니다.
따라서 지금은 이 IP 주소로는 더 이상 계정을 만들 수 없습니다.',
-'emailauthenticated' => '당신의 이메일 주소는 $2 $3에 인증되었습니다.',
+'emailauthenticated' => '이메일 주소는 $2 $3에 인증되었습니다.',
'emailnotauthenticated' => '이메일 주소를 인증하지 않았습니다.
이메일 확인 절차를 거치지 않으면 다음 이메일 기능을 사용할 수 없습니다.',
'noemailprefs' => '이 기능을 사용하기 위해서는 사용자 환경 설정에서 이메일 주소를 설정해야 합니다.',
# Special:ChangeEmail
'changeemail' => '이메일 주소 바꾸기',
'changeemail-header' => '계정 메일 주소 바꾸기',
-'changeemail-text' => 'ì\9d´ë©\94ì\9d¼ 주ì\86\8c를 ë°\94ê¾¸ë ¤ë©´ ì\9d´ ì\96\91ì\8b\9dì\9d\84 ì±\84ì\9a°ì\84¸ì\9a\94. ë°\94ë\80\9c ë\82´ì\9a©ì\9d\84 í\99\95ì\9d¸í\95\98기 ì\9c\84í\95´ ë\8b¹ì\8b ì\9d\98 ë¹\84ë°\80ë²\88í\98¸ë¥¼ ì\9e\85ë ¥í\95´ì\95¼ í\95©ë\8b\88ë\8b¤.',
+'changeemail-text' => '이메일 주소를 바꾸려면 이 양식을 채우세요. 바뀜 내용을 확인하기 위해 비밀번호를 입력해야 합니다.',
'changeemail-no-info' => '이 특수 문서에 직접 접근하려면 반드시 로그인해야 합니다.',
'changeemail-oldemail' => '현재 이메일 주소 :',
'changeemail-newemail' => '새 이메일 주소:',
'summary-preview' => '요약 미리 보기:',
'subject-preview' => '주제/제목 미리 보기:',
'blockedtitle' => '차단됨',
-'blockedtext' => "'''당신의 계정 혹은 IP 주소가 차단되었습니다.'''
+'blockedtext' => "'''사용자 계정 또는 IP 주소가 차단되었습니다.'''
차단한 사람은 $1입니다.
차단한 이유는 다음과 같습니다: $2
'token_suffix_mismatch' => "'''저장하려는 내용의 문장 부호가 망가져 있습니다.'''
문서 보호를 위해 해당 내용을 저장하지 않습니다.
버그가 있는 익명 프록시 서비스 등을 사용할 때 이런 문제가 발생할 수 있습니다.",
-'edit_form_incomplete' => "'''편집의 일부 내용이 서버에 전달되지 않았습니다. 당신의 편집이 손상되지 않았는지 확인하고 다시 시도해 주십시오.'''",
+'edit_form_incomplete' => "'''편집의 일부 내용이 서버에 전달되지 않았습니다. 편집이 손상되지 않았는지 확인하고 다시 시도해 주십시오.'''",
'editing' => '$1 편집하기',
'creating' => '$1 만들기',
'editingsection' => '$1 편집하기 (부분)',
\"{{int:savearticle}}\"을 누르면 '''위쪽의 편집 내역만''' 저장됩니다.",
'yourtext' => '당신의 편집',
'storedversion' => '현재 문서',
-'nonunicodebrowser' => "'''경고: 당신의 웹 브라우저가 유니코드를 완벽하게 지원하지 않습니다.'''
+'nonunicodebrowser' => "'''경고: 웹 브라우저가 유니코드를 완벽하게 지원하지 않습니다.'''
아스키가 아닌 문자가 16진수 코드로 나타날 수 있습니다.",
'editingold' => "'''경고: 지금 이전 버전의 문서를 고치고 있습니다.'''
이것을 저장하면 최근에 편집된 부분이 사라질 수 있습니다.",
# Preferences page
'preferences' => '사용자 환경 설정',
-'mypreferences' => '사용자 환경 설정',
+'mypreferences' => '환경 설정',
'prefs-edits' => '편집 횟수:',
'prefsnologin' => '로그인하지 않음',
'prefsnologintext' => '사용자 환경 설정을 바꾸려면 먼저 <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} 로그인]</span>해야 합니다.',
'overwroteimage' => '사용자가 "[[$1]]" 파일의 새 판을 올렸습니다.',
'uploaddisabled' => '올리기 비활성화됨',
'copyuploaddisabled' => 'URL로 파일 올리기가 비활성화되어 있습니다.',
-'uploadfromurl-queued' => '당신의 올리기 명령이 기록되었습니다.',
+'uploadfromurl-queued' => '올리기 명령이 기록되었습니다.',
'uploaddisabledtext' => '파일 올리기 기능이 비활성화되어 있습니다.',
'php-uploaddisabledtext' => 'PHP 파일 올리기가 비활성화되었습니다. 파일 올리기 설정을 확인하십시오.',
'uploadscripted' => '이 파일에는 HTML이나 다른 스크립트 코드가 포함되어 있어, 웹 브라우저에서 오류를 일으킬 수 있습니다.',
'linksearch-pat' => '찾기 패턴:',
'linksearch-ns' => '이름공간:',
'linksearch-ok' => '찾기',
-'linksearch-text' => '"*.wikipedia.org"와 같이 와일드카드를 사용할 수 있습니다.
+'linksearch-text' => '"*.wikipedia.org"와 같이 와일드 카드를 사용할 수 있습니다.
적어도 "*.org"와 같이 최상위 도메인을 입력해야 합니다.<br />
-지원하는 프로토콜 목록: <code>$1</code> (찾을 때 이것을 추가하지 마세요)',
+지원하는 프로토콜: <code>$1</code> (프로토콜을 지정하지 않을 때 기본값은 http://)',
'linksearch-line' => '$2에서 $1 을 링크하고 있습니다.',
'linksearch-error' => '와일드카드는 주소의 처음 부분에만 사용될 수 있습니다.',
# Watchlist
'watchlist' => '주시문서 목록',
-'mywatchlist' => '내 주시문서 목록',
+'mywatchlist' => '주시문서 목록',
'watchlistfor2' => '사용자:$1 $2',
'nowatchlist' => '주시하는 문서가 아직 없습니다.',
'watchlistanontext' => '주시문서 목록을 보거나 고치려면 $1 하세요.',
# Contributions
'contributions' => '사용자 기여',
'contributions-title' => '$1 사용자의 기여 목록',
-'mycontris' => '내 기여 목록',
+'mycontris' => '기여 목록',
'contribsub2' => '$1($2)의 기여',
'nocontribs' => '이 사용자는 아무 것도 기여하지 않았습니다.',
'uctop' => '(최신)',
'whatlinkshere-hideredirs' => '넘겨주기를 $1',
'whatlinkshere-hidetrans' => '틀을 $1',
'whatlinkshere-hidelinks' => '링크를 $1',
-'whatlinkshere-hideimages' => '그림 포함을 $1',
+'whatlinkshere-hideimages' => '파일 링크를 $1',
'whatlinkshere-filters' => '필터',
# Block/unblock
'htmlform-int-invalid' => '지정한 값은 정수가 아닙니다.',
'htmlform-float-invalid' => '지정한 값은 수가 아닙니다.',
'htmlform-int-toolow' => '지정한 값은 최소값 $1 미만입니다.',
-'htmlform-int-toohigh' => '당신이 입력한 값은 최대값 $1 이상입니다.',
+'htmlform-int-toohigh' => '지정한 값은 최대값 $1 이상입니다.',
'htmlform-required' => '이 값은 필수 항목입니다',
'htmlform-submit' => '저장',
'htmlform-reset' => '바꾼 것을 되돌리기',
'api-error-duplicate-archive' => '같은 내용을 담고 있던 {{PLURAL:$1|[$2 다른 파일]}}이 있었지만 이 {{PLURAL:$1|파일}}은 삭제되었습니다.',
'api-error-duplicate-archive-popup-title' => '중복된 {{PLURAL:$1|파일}}이 이미 삭제되었습니다.',
'api-error-duplicate-popup-title' => '중복된 {{PLURAL:$1|파일}}입니다.',
-'api-error-empty-file' => '당신이 올리려는 파일이 비어 있습니다.',
+'api-error-empty-file' => '올리려는 파일이 비어 있습니다.',
'api-error-emptypage' => '새 문서로 빈 문서를 만들 수 없습니다.',
'api-error-fetchfileerror' => '내부 오류: 파일을 불러오는 중 문제가 발생했습니다.',
'api-error-fileexists-forbidden' => '"$1" 이름으로 된 파일은 이미 존재하고 덮어쓸 수 없습니다.',
'api-error-fileexists-shared-forbidden' => '"$1" 이름으로 된 파일이 이미 공용 저장소에 존재하며 덮어쓸 수 없습니다.',
-'api-error-file-too-large' => '당신이 올리려는 파일이 너무 큽니다.',
+'api-error-file-too-large' => '올리려는 파일이 너무 큽니다.',
'api-error-filename-tooshort' => '파일 이름이 너무 짧습니다.',
'api-error-filetype-banned' => '이런 파일 형식은 올릴 수 없습니다.',
'api-error-filetype-banned-type' => '$1 {{PLURAL:$4|파일 형식은 올릴 수 없습니다}}. $2 {{PLURAL:$3|파일 형식만 사용할 수 있습니다}}.',
'api-error-hookaborted' => '수정하려고 한 것이 확장 기능에 의해 중지되었습니다.',
'api-error-http' => '내부 오류: 서버에 연결할 수 없습니다.',
'api-error-illegal-filename' => '이 파일 이름을 사용할 수 없습니다.',
-'api-error-internal-error' => '내부 오류: 당신이 올린 파일을 위키에서 처리하는 중 문제가 발생했습니다.',
+'api-error-internal-error' => '내부 오류: 올린 파일을 위키에서 처리하는 중 어떤 문제가 발생했습니다.',
'api-error-invalid-file-key' => '내부 오류: 임시 저장소에서 파일을 찾지 못했습니다.',
'api-error-missingparam' => '내부 오류: 요청 중 매개변수가 누락되었습니다.',
'api-error-missingresult' => '내부 오류: 파일의 복제가 성공했는지 판단할 수 없습니다.',
'duration-centuries' => '$1{{PLURAL:$1|세기}}',
'duration-millennia' => '$1{{PLURAL:$1|천년}}',
+# Unknown messages
+'mytalk-parenthetical' => '토론',
);
# Dates
'sunday' => 'Ыйых кюн',
'monday' => 'Баш кюн',
-'tuesday' => 'Геурге кюн',
-'wednesday' => 'Барас кюн',
+'tuesday' => 'Гюрге кюн',
+'wednesday' => 'Бараз кюн',
'thursday' => 'Орта кюн',
'friday' => 'Байрым кюн',
'saturday' => 'Шабат кюн',
'sun' => 'Ыйых кюн',
'mon' => 'Баш кюн',
-'tue' => 'Геурге кюн',
-'wed' => 'Барас кюн',
+'tue' => 'Гр',
+'wed' => 'Брз',
'thu' => 'Орта кюн',
'fri' => 'Байрым кюн',
'sat' => 'Шабат кюн',
'youhavenewmessages' => 'Сизге $1 келдиле ($2).',
'newmessageslink' => 'джангы билдириуле',
'newmessagesdifflink' => 'сюзюу бетигизни ахыр тюрлениую',
+'youhavenewmessagesmanyusers' => 'Талай къошулуучудан $1 барды. ($2)',
+'newmessageslinkplural' => '{{PLURAL:$1|джангы билдириуюгюз|джангы билдириулеригиз}}',
+'newmessagesdifflinkplural' => 'ахыр {{PLURAL:$1|тюрлениу|тюрлениу}}',
'youhavenewmessagesmulti' => '$1 бетде джангы билдириуле бардыла.',
'editsection' => 'тюрлендир',
'editold' => 'тюрлендир',
'pageinfo-watchers' => 'Кёргенлени саны',
'pageinfo-edits' => 'Тюрлендириулени саны',
'pageinfo-authors' => 'Авторланы саны',
+'pageinfo-toolboxlink' => 'Бетни юсюнден',
# Skin names
'skinname-standard' => 'Стандарт',
'yourgender' => 'Do bes *',
'gender-unknown' => 'wesse mer nit',
'gender-male' => 'Kääl odder Jung',
-'gender-female' => 'Möhn, Weech odder Mädche',
+'gender-female' => 'Möhn, Weesch odder Mädsche',
'prefs-help-gender' => '* Moß mer nit aanjevve, un wann et aanjejovve eß, dann kallt et Wiki övver Desch als „dä Pitter“ udder „dat Tiina“, sönß uns „Metmaacher Pütz“. Dat kritt de janne Welt ze sinn, nit nur Do allein.',
'email' => '<i lang="en">e-mail</i>',
'prefs-help-realname' => '* Dinge richtije Name — kanns De fott looße — wann De en ävver nenne wells, dann weed dä jebruch, öm Ding Beidräch domet ze schmöcke.',
'rightslogtext' => 'Hee sin de Änderunge an Metmaacher ehre Räächde opjeliss. Op de Sigge üvver Metmaacher, Wiki-Köbesse, Bürrokrade, Stewards, un esu, kanns De nohlese, wat domet es.',
'rightslogentry' => 'hät däm Metmaacher „$1“ sing Räächde vun „$2“ op „$3“ ömjestallt.',
'rightslogentry-autopromote' => 'wood automattesch vun $2 zohm $3 jemaat.',
+'logentry-rights-rights-legacy' => '{{GENDER:$1|Dä|Et|Dä Metmaacher|De|Dat}} $1 hät däm Metmaacher $3 sing Räääschte-Jroppe verändert.',
+'logentry-rights-autopromote' => '{{GENDER:$1|Dä|Et|Dä Metmaacher|De|Dat}} $1 wood automattesch vum $4 zom $5 jemaat.',
'rightsnone' => '(nix)',
# Associated actions - in the sentence "You do not have permission to X"
'emailuser-title-target' => '<i lang="en">E-mail</i> aan {{GENDER:$1|dä Metmaacher|di Metmaacherėn|dä Metmaacher|di Metmaacherėn|dä Metmaacher}} $1',
'emailuser-title-notarget' => 'Verschegg en <i lang="en">e-mail</i> aan ene Metmaacher',
'emailpage' => 'Verscheck <i lang="en">e-mail</i> aan ene Metmaacher',
-'emailpagetext' => 'Wann heh dä Metmaacher en Adräß för sing <i lang="en">e-mail</i> aanjejovve hätt en singe Enstellunge,
-un die deit et och, dann kanns De met däm Fomular hee unge en einzel <i lang="en">e-mail</i> aan dä Metmaacher schecke.
+'emailpagetext' => 'Wann {{GENDER:$1|dä Metmaacher heh|dat heh|heh dä Metmaacher|sei|dat heh}} en Adräß för sing <i lang="en">e-mail</i> aanjejovve hätt en singe Enstellunge, un die deit et och, dann kanns De met däm Fomular heh unge en einzel <i lang="en">e-mail</i> aan {{GENDER:$1|inn|it|dä Metmaacher|heh di Metmaacherėn|et}} schecke.
Ding <i lang="en">e-mail</i>-Adräß, di De en [[Special:Preferences|Ding eije Enstellunge]] aanjejovve häs,
-di weed als em Afsender sing Adräß en Ding <i lang="en">e-mail</i> enjedrage.
+di weed als em Afsender sing Adräß enjedrare.
Domet kann, wä di <i lang="en">e-mail</i> kritt, drop antwoote, un di Antwood jeiht tirek aan Desch.
Alles klor?',
'usermailererror' => 'Dat E-Mail-Objek jov ene Fähler us:',
'undeletedrevisions' => '{{PLURAL:$1|ein Version|$1 Versione}} zeröckjehollt',
'undeletedrevisions-files' => 'Zesammejenomme {{PLURAL:$1|Ein Version|<strong>$1</strong> Versione|<strong>Kein</strong> Version}} vun {{PLURAL:$2|eine Datei|<strong>$2</strong> Dateie|<strong>nix</strong>}} zeröckjehollt',
'undeletedfiles' => '{{PLURAL:$1|Ein Datei|<strong>$1</strong> Dateie|<strong>Kein</strong> Dateie}} zeröckjehollt',
-'cannotundelete' => '<strong>Dä.</strong> Et Zeröckholle jing donevve. Maach sinn, dat ene andere Metmaacher flöcker wor, un et et eets jedon hät, un jetz es die Sigg ald widder do jewäse.',
+'cannotundelete' => '<strong>Dä.</strong> Et Zeröckholle jing donävve.
+
+$1',
'undeletedpage' => '<strong>De Sigg „$1“ es jetz widder do</strong>
Luur Der et [[Special:Log/delete|Logboch met de fottjeschmesse Sigge]] aan, do häs De de Neuste fottjeschmesse
un widder herjehollte Sigge.',
'pageinfo-default-sort' => 'Shtandattmääßesch zottiere met däm Schlößel',
'pageinfo-length' => 'Bytes en dä Sigg',
'pageinfo-article-id' => 'Dä Sigg ier Nommer en dä Daatebangk',
+'pageinfo-language' => 'De Schprooch vum Sigge-Enhallt',
'pageinfo-robot-policy' => 'Eijeschaffte för de Söhkmaschiine',
'pageinfo-robot-index' => 'kammer opnämme',
'pageinfo-robot-noindex' => 'kammer nit opnämme',
'version-license' => 'Lizänz',
'version-poweredby-credits' => "Dat Wiki heh löp met '''[//www.mediawiki.org/ MediaWiki]''', copyright © 2001–$1 $2.",
'version-poweredby-others' => 'sönß wää',
+'version-credits-summary' => 'Mer bedanke ons för iehr Beidrähsch zom [[Special:Version|MediaWiki]] bei:',
'version-license-info' => 'MediaWiki es e frei Projramm. Mer kann et unmolesteet wigger verdeile, un mer kann et verändere, wi mer löstich es, wam_mer sesch dobei aan de <i lang="en">GNU General Public License</i> (jenerälle öffentlesche Lizänz noh GNU) hallde deiht, wi se vun der <i lang="en">Free Software Foundation</i> (Steftung för frei Soffwäer) veröffentlesch woode es. Dobei kam_mer sesch ußsöhke of mer sesch aan de Version 2 dovun hallde deiht, udder öhnz en späädere Fassung.
MediaWiki weed verdeilt met dä Hoffnung, dat et för jet jood es, ävver <span style="text-transform:uppercase">der ohne jeede Jarantie</span>, un esujaa ohne ene unjesaate Jedangke, et künnt <span style="text-transform:uppercase">ze verkoufe</span> sin udder <span style="text-transform:uppercase;">för öhndsene bestemmpte Zweck ze jebruche</span>. Loor Der de jenannte Lizänz aan, wann De mieh Einzelheite weße wells.
'youhavenewmessages' => '$1 yên te hene ($2).',
'newmessageslink' => 'Peyamên nû',
'newmessagesdifflink' => 'cudayî ji guhertoya berê',
+'youhavenewmessagesfromusers' => 'Ji {{PLURAL:$3|bikarhênereke/î din|$3 bikarhêneran}}, ji bo te $1 hene ($2).',
+'newmessageslinkplural' => '{{PLURAL:$1|peyameke nû|peyamên nû}}',
+'newmessagesdifflinkplural' => '{{PLURAL:$1|guherandin|guherandinên dawî}}',
'youhavenewmessagesmulti' => 'Peyamên nû li $1 ji te re hene.',
'editsection' => 'biguherîne',
'editold' => 'biguherîne',
'last' => 'berê',
'page_first' => 'ya pêşîn',
'page_last' => 'ya paşîn',
-'histlegend' => 'Rênîşan: (cudahî) = cudahiya nav vê û versiyona niha,
-(berê) = cudahiya nav vê û ya berî vê, B = guhertina biçûk',
+'histlegend' => "Rênîşan: ({{int:cur}}) = cudahiya nav vê û versiyona niha, ({{int:last}}) = cudahiya nav vê û ya berî vê, '''{{int:minoreditletter}}''' = guhertina biçûk",
'history-fieldset-title' => 'Li dîrokê bigere',
'history-show-deleted' => 'Tenê yên jêbirî',
'histfirst' => 'Kevintirîn',
* @author Aidabishkek
* @author Amire80
* @author Chorobek
+ * @author Growingup
* @author Muratjumashev
* @author Ztimur
*/
'tog-editondblclick' => 'Эки басып баракты оңдоо (JavaScript талап кылынат)',
'tog-editsection' => 'Ар бир секция үчүн «оңдоо» шилтемеси',
-'underline-always' => 'Дайым',
+'underline-always' => 'Дайыма',
'underline-never' => 'Эч качан',
# Font style option in Special:Preferences
'and' => ' жана',
# Cologne Blue skin
-'qbfind' => 'Ð\98зде',
+'qbfind' => 'ТабÑ\83Ñ\83',
'qbbrowse' => 'Сереп сал',
'qbedit' => 'Оңдоо',
'qbpageoptions' => 'Бул барак',
# Vector skin
'vector-action-addsection' => 'Тема кошумчала',
-'vector-action-delete' => 'Өчүр',
+'vector-action-delete' => 'Өчүрүү',
'vector-action-move' => 'Аталышын өзгөрт',
-'vector-action-protect' => 'Корго',
+'vector-action-protect' => 'Коргоо',
'vector-action-undelete' => 'Калыбына келтирүү',
'vector-action-unprotect' => 'Коргоону өзгөртүү',
-'vector-view-create' => 'Ð\91аÑ\88Ñ\82а',
-'vector-view-edit' => 'Оңдо',
+'vector-view-create' => 'Ð\96аÑ\80аÑ\82Ñ\83Ñ\83',
+'vector-view-edit' => 'Оңдоо',
'vector-view-history' => 'Тарыхын кара',
-'vector-view-view' => 'Оку',
+'vector-view-view' => 'Окуу',
'vector-view-viewsource' => 'Кайнарын кара',
'actions' => 'Аракеттер',
'namespaces' => 'Аталыш топтому',
'returnto' => '$1 барагына кайт.',
'tagline' => '{{SITENAME}} дан',
'help' => 'Жардам',
-'search' => 'Изде',
-'searchbutton' => 'Изде',
-'go' => 'Таап бер',
+'search' => 'Издөө',
+'searchbutton' => 'Издөө',
+'go' => 'Өтүү',
'searcharticle' => 'Алга',
'history' => 'Барактын тарыхы',
-'history_short' => 'Тарыхы',
+'history_short' => 'Тарых',
'printableversion' => 'Басма үлгүсү',
'permalink' => 'Туруктуу шилтеме',
'print' => 'Басып чыгаруу',
'view' => 'Кароо',
'edit' => 'Оңдоо',
-'create' => 'Ð\91аÑ\88Ñ\82а',
+'create' => 'Ð\96аÑ\80аÑ\82Ñ\83Ñ\83',
'editthispage' => 'Бул баракты оңдо',
'create-this-page' => 'Бул баракты түзүү',
'delete' => 'Өчүрүү',
-'deletethispage' => 'Бул баракты өчүрүп кой',
+'deletethispage' => 'Бул баракты өчүрүү',
'protect' => 'Коргоо',
-'protect_change' => 'өзгөрт',
+'protect_change' => 'өзгөртүү',
'protectthispage' => 'Бул баракты коргоо',
'unprotect' => 'Коргоону өзгөртүү',
'newpage' => 'Жаңы барак',
'articlepage' => 'Макаланы кароо',
'talk' => 'Талкуу',
'views' => 'Көрсөтүүлөр',
-'toolbox' => 'Аспап кутусу',
+'toolbox' => 'Аспаптар',
'userpage' => 'Катышуучунун барагын кароо',
'projectpage' => 'Долбоор барагын кароо',
'imagepage' => 'Файлдын барагын кароо',
'lastmodifiedat' => 'Бул барак соңку жолу $1, $2 өзгөртүлгөн.',
'viewcount' => 'Бул барак {{PLURAL:$1|$1|$1}} жолу ачылды.',
'protectedpage' => 'Корголгон барак',
-'jumpto' => 'Атта:',
+'jumpto' => 'Өтүү:',
'jumptonavigation' => 'багыттоо',
'jumptosearch' => 'издөө',
'disclaimerpage' => 'Project:Жалпы жоопкерчиликтен баш тартуу',
'edithelp' => 'Оңдоого жардам',
'edithelppage' => 'Help:Оңдоо',
-'helppage' => 'Help:Мазмуну',
+'helppage' => 'Help:Мазмун',
'mainpage' => 'Башбарак',
'mainpage-description' => 'Башбарак',
'portal' => 'Жамаат порталы',
'newmessageslink' => 'жаңы билдирүүлөр',
'newmessagesdifflink' => 'соңку өзгөрүү',
'youhavenewmessagesmulti' => 'Сизге $1 жаңы кат бар.',
-'editsection' => 'оңдо',
-'editold' => 'оңдо',
+'editsection' => 'оңдоо',
+'editold' => 'оңдоо',
'viewsourceold' => 'байкоо',
-'editlink' => 'оңдо',
+'editlink' => 'оңдоо',
'viewsourcelink' => 'Байкоо',
-'editsectionhint' => '$1 бөлүмүн оңдо',
-'toc' => 'Мазмуну',
-'showtoc' => 'Ð\9aÓ©Ñ\80Ñ\81Ó©Ñ\82',
-'hidetoc' => 'Жашыр',
+'editsectionhint' => '$1 бөлүмүн оңдоо',
+'toc' => 'Мазмун',
+'showtoc' => 'көÑ\80Ñ\81Ó©Ñ\82Ò¯Ò¯',
+'hidetoc' => 'Жашыруу',
'site-rss-feed' => '$1 RSS тилкеси',
'site-atom-feed' => '$1 Atom агымы',
'page-atom-feed' => '"$1" Atom агымы',
# Short words for each namespace, by default used in the namespace tab in monobook
'nstab-main' => 'Макала',
'nstab-user' => 'Колдонуучунун барагы',
+'nstab-media' => 'Мультимедиа',
'nstab-special' => 'Атайын барак',
'nstab-project' => 'Долбоордун барагы',
'nstab-image' => 'Файл',
-'nstab-mediawiki' => 'Билдирүү',
-'nstab-template' => 'Ð\9aалÑ\8bп',
+'nstab-mediawiki' => 'Билдирме',
+'nstab-template' => 'Шаблон',
'nstab-help' => 'Жардам',
'nstab-category' => 'Категория',
# General errors
-'error' => 'Ð\96аңÑ\8bлÑ\8bÑ\88',
+'error' => 'Ð\9aаÑ\82а',
'missing-article' => 'Табылууга тийиш «$1» $2 деп аталган баракта текст маалыматтар базасында табылган жок.
Бул сыяктуу абал өчүрүлгөн барактын өзгөрүүлөрдүн тарыхына эски шилтеме менен өткөндө учурайт.
'filecopyerror' => '"$1" файлы "$2" файлына көчүрүлбөдү.',
'filedeleteerror' => '"$1" файлын өчүрүүгө болбоду.',
'directorycreateerror' => '"$1" каталогун түзүүгө болбоду.',
-'filenotfound' => '"$1" файлы табылбады.',
+'filenotfound' => '"$1" файлын табууга мүмкүн эмес.',
'fileexistserror' => '"$1" файлына жазууга болбоду: Мурдатан бар.',
'unexpected' => 'Күтүлбөгөн маани: "$1"="$2".',
'formerror' => 'Ката: Форманы жөнөтүүгө болбоду.',
'badtitle' => 'Ыксыз аталыш',
'badtitletext' => 'Талап кылынган барак аталышы туура эмес, бош, же тилдер-аралык же уики-аралык аталышы туура эмес шилтемеленген.
Балким аталышта колдонулбай турган бир же андан көп белги камтылган.',
-'viewsource' => 'Кайнарын кара',
+'viewsource' => 'Кароо',
# Login and logout pages
'welcomecreation' => '== Кош келиңиз, $1! ==
'logout' => 'Чыгуу',
'userlogout' => 'Чыгуу',
'notloggedin' => 'Сиз системага кире элексиз',
-'nologin' => 'Ð\9aаÑ\82Ñ\82ала элексизби? $1.',
+'nologin' => 'Ð\9aаÑ\82Ñ\82ай элексизби? $1.',
'nologinlink' => 'Каттоону башта',
-'createaccount' => 'Ð\96аңÑ\8b колдонÑ\83Ñ\83Ñ\87Ñ\83нÑ\83 каÑ\82Ñ\82а',
+'createaccount' => 'ÐÑ\81еп жазÑ\83Ñ\83Ñ\81Ñ\83н жаÑ\80аÑ\82Ñ\83Ñ\83',
'gotaccount' => 'Катталгансызбы? $1.',
'gotaccountlink' => 'Кирүү',
'userlogin-resetlink' => 'Кирүүчү маалыматарыңызды унутуп калдыңызбы?',
'loginsuccesstitle' => 'Сиз ийгиликтүү кирдиңиз',
'wrongpassword' => 'Ката сырсөз киргизилди. Кайтадан аракет кылып көрүңүз.',
'wrongpasswordempty' => 'Сырсөз киргизилген жок. Кайтадан аракет кылып көрүңүз.',
-'mailmypassword' => 'Жаңы сырсөздү электрондук дарекке жибер',
+'mailmypassword' => 'Жаңы сырсөздү e-mail аркылуу жиберүү',
'emailconfirmlink' => 'Электрондук дарегиңизди ырастаңыз',
-'accountcreated' => 'Ð\9aаÑ\82Ñ\82алды',
+'accountcreated' => 'ÐÑ\81еп жазÑ\83Ñ\83Ñ\81Ñ\83 жаÑ\80аÑ\82Ñ\8bлды',
'loginlanguagelabel' => 'Тил: $1',
# Change password dialog
'oldpassword' => 'Эски сырсөз:',
'newpassword' => 'Жаңы сырсөз:',
+# Special:PasswordReset
+'passwordreset-emailelement' => 'Колдонуучу аты: $1
+Убактылуу сырсөз: $2',
+
+# Special:ChangeEmail
+'changeemail' => 'E-mail даректи өзгөртүү',
+'changeemail-oldemail' => 'Кезектеги e-mail дарек:',
+'changeemail-newemail' => 'Жаңы e-mail дарек:',
+'changeemail-none' => '(жок)',
+'changeemail-submit' => "E-mail'ди өзгөртүү",
+'changeemail-cancel' => 'Айнуу',
+
# Edit page toolbar
-'bold_sample' => 'Калың тамга',
-'bold_tip' => 'Калың тамга',
-'italic_sample' => 'Ð\96анÑ\82Ñ\8bк Ñ\82амга',
-'italic_tip' => 'Ð\96анÑ\82Ñ\8bк Ñ\82амга',
-'link_sample' => 'Шилтеменин аталышы',
+'bold_sample' => 'Кара текст',
+'bold_tip' => 'Кара текст',
+'italic_sample' => 'Ð\9aÑ\83Ñ\80Ñ\81ив Ñ\82екÑ\81Ñ\82',
+'italic_tip' => 'Ð\9aÑ\83Ñ\80Ñ\81ив Ñ\82екÑ\81Ñ\82',
+'link_sample' => 'Шилтеме аты',
'link_tip' => 'Ички шилтеме',
'extlink_sample' => 'http://www.example.com шилтеме аталышы',
'extlink_tip' => 'Сырткы шилтемелерге (http:// префиксин койгонду унутпаңыз)',
-'headline_sample' => 'Аталыштын тексти',
+'headline_sample' => 'Ат тексти',
'headline_tip' => '2-деңгээлдеги баш аты',
'nowiki_sample' => 'Форматталбаган текстти бул жерге киргизиңиз',
'nowiki_tip' => 'Уики-форматтоого көңүл бөлбө',
# Edit pages
'summary' => 'Кыска түшүндүрүү:',
'minoredit' => 'Майда оңдоо',
-'watchthis' => 'Бул баракты көзөмөлдө',
-'savearticle' => 'Ð\91аÑ\80акÑ\82Ñ\8b Ñ\81акÑ\82ап кой',
+'watchthis' => 'Бул баракты көзөмөлдөө',
+'savearticle' => 'Ð\91аÑ\80акÑ\82Ñ\8b Ñ\81акÑ\82оо',
'preview' => 'Алдын ала көрүү',
-'showpreview' => 'Алдын ала көрсөт',
+'showpreview' => 'Алдын ала көрсөтүү',
'showlivepreview' => 'Ылдам карап чыгуу',
-'showdiff' => 'Өзгөртүүлөрдү көрсөт',
+'showdiff' => 'Өзгөртүүлөрдү көрсөтүү',
'anoneditwarning' => "'''Эскертүү:''' Сиз каттоодон өткөн жоксуз.
IP дарегиңиз бул барактын оңдоо тарыхына жазылат.",
'blockedtext' => 'Сиздин колдонуучу атыңыз же IP дарегиңиз тосмолонгон',
-'blockednoreason' => 'себеби көрсөтүлгөн эмес',
+'blockednoreason' => 'себеби көрсөтүлгөн жок',
'loginreqtitle' => 'Колдонуучунун аты талап кылынат',
'loginreqlink' => 'Кирүү',
'accmailtitle' => 'Сырсөз жөнөтүлдү.',
Сиз башка барактардан [[Special:Search/{{PAGENAME}}|ушул аталыш менен баракты издөө]] салып,
же <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} тийиштүү жазууларды таба аласыз]</span>.',
'userpage-userdoesnotexist' => '"$1" Мындай колдонуучу катталган эмес. Ушул баракты түзүүнү же оңдогонду каалганыңыз анык болсун',
+'updated' => '(Жаңыртылды)',
'previewnote' => "'''Бул алдын ала көрүнүшү гана болгонун эсиңизге алыңыз.'''
Өзгөртүүлөрүңүз сактала элек!",
'continue-editing' => 'Өзгөртүүүлөрдү улантабыз',
'edit-conflict' => 'Өзгөртүүлөрдүн конфликти',
'edit-already-exists' => 'Жаңы барак түзүү мүмкүн эмес. Мындай барак бар',
+# Content models
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
+
# Parser/template warnings
'post-expand-template-inclusion-warning' => "'''Эскертүү:''' Камтылган калыптардын өлчөмү өтө чоң.
Кээ бир калыптар камтылбайт.",
'parser-template-loop-warning' => 'Калыптарда айланма бар:[[$1]]',
# History pages
-'viewpagelogs' => 'Бул барак үчүн тизмелерди кара',
+'viewpagelogs' => 'Бул барак үчүн журналды көрсөтүү',
'nohistory' => 'Бул барактын өзгөртүүлөр тарыхы жок',
'currentrev' => 'Акыркы версиясы',
'currentrev-asof' => '$1 -га соңку версиясы',
'page_last' => 'акыркы',
'histlegend' => "Айырмаларды тандоо: Салыштырыла турган версияларлын тушундагы тегеректерди белгилеп туруп \"Enter\"-ди же астындагы баскычты бас.<br />
Түшүндүрүү: '''({{int:cur}})''' = соңку версиясынан айырма, '''({{int:last}})''' = мурунку версиясынан айырма, '''{{int:minoreditletter}}''' = майда оңдоо.",
-'history-fieldset-title' => 'ТаÑ\80Ñ\8bÑ\85Ñ\8bн каÑ\80а',
+'history-fieldset-title' => 'ТаÑ\80Ñ\8bÑ\85Ñ\8bн каÑ\80оо',
'history-show-deleted' => 'Өчүрүлгөндөрдү гана',
'histfirst' => 'Эң эски',
'histlast' => 'Соңку',
'revdel-restore' => 'көрүнүшүн өзгөрт',
'revdel-restore-deleted' => 'өчүрүлгөн версиялар',
'revdel-restore-visible' => 'көрүнүүчү версиялары',
+'revdelete-reasonotherlist' => 'Башка себеп',
+'revdelete-offender' => 'Барак версиясынын автору:',
+
+# History merging
+'mergehistory-from' => 'Баштапкы барак:',
+'mergehistory-submit' => 'Версияларды бириктирүү',
+'mergehistory-reason' => 'Себеп',
# Merge log
-'revertmerge' => 'Бөл',
+'revertmerge' => 'Бөлүү',
# Diffs
'history-title' => '"$1" өзгөрүүлөр тарыхы',
'lineno' => '$1 -сап:',
-'compareselectedversions' => 'Тандалган версияларды салыштыр',
-'editundo' => 'жокко чыгар',
+'compareselectedversions' => 'Тандалган версияларды салыштыруу',
+'editundo' => 'жокко чыгаруу',
'diff-multi' => '({{PLURAL:$2|колдонуучу|$2 колдонуучу}} тарабынан жасалган {{PLURAL:$1|аралык версия|$1 аралык версия}} көрсөтүлгөн жок)',
# Search results
'searchresults-title' => '"$1" үчүн издөө жыйынтыктары',
'prevn' => 'мурунку {{PLURAL:$1|$1}}',
'nextn' => 'кийинки{{PLURAL:$1|$1}}',
-'prevn-title' => 'Мурунку $1 {{PLURAL:$1|жыйынтык|жыйынтык}}',
-'nextn-title' => 'Кийинки $1 {{PLURAL:$1|жыйынтык|жыйынтык}}',
-'shown-title' => 'Бир баракка $1 {{PLURAL:$1|жыйынтык|жыйынтык}} көрсөт',
-'viewprevnext' => '($1 {{int:pipe-separator}} $2) ($3) кара',
+'prevn-title' => 'Мурунку $1 {{PLURAL:$1|жыйынтык}}',
+'nextn-title' => 'Кийинки $1 {{PLURAL:$1|жыйынтык}}',
+'shown-title' => 'Барактан $1 {{PLURAL:$1|жыйынтыкты}} көрсөтүү',
+'viewprevnext' => '($1 {{int:pipe-separator}} $2) ($3) кароо',
+'searchmenu-legend' => 'Издөө опциялары',
'searchmenu-exists' => "'''Бул Уикиде \"[[:\$1]]\" деп аталган барак бар.'''",
'searchmenu-new' => "'''Бул Уикиде \"[[:\$1]]\" барагын түз!'''",
+'searchhelp-url' => 'Help:Мазмун',
'searchprofile-articles' => 'Негизги барактар',
-'searchprofile-project' => 'Ð\96аÑ\80дам жана Ð\94олбоор барактары',
+'searchprofile-project' => 'Ð\96аÑ\80дам жана долбоор барактары',
'searchprofile-images' => 'Мултимедиа',
'searchprofile-everything' => 'Баары',
'searchprofile-advanced' => 'Кеңейтилген',
-'searchprofile-articles-tooltip' => '$1 -де изде',
-'searchprofile-project-tooltip' => '$1 -де изде',
-'searchprofile-images-tooltip' => 'Файлдарды изде',
+'searchprofile-articles-tooltip' => '$1 -де издөө',
+'searchprofile-project-tooltip' => '$1 -де издөө',
+'searchprofile-images-tooltip' => 'Файлдарды издөө',
'searchprofile-everything-tooltip' => 'Бардык барактарда (талкуу барактарды кошо) изде',
'searchprofile-advanced-tooltip' => 'Белгиленген аталыш топтомдорунда изде',
'search-result-size' => '$1 ({{PLURAL:$2|1 сөз|$2 сөз}})',
'showingresultsheader' => "'''$4''' үчүн {{PLURAL:$5|'''$3''' жыйынтыктан '''$1'''-и|'''$1 - $2''' -дан '''$3''' жыйынтык}}",
'search-nonefound' => 'Талапка төп маалымат табылган жок.',
'powersearch' => 'Издөө',
-'powersearch-legend' => 'Кеңиртип изде',
+'powersearch-legend' => 'Кеңейтилген издөө',
+
+# Quickbar
+'qbsettings-none' => 'Көрсөтпөө',
# Preferences page
'preferences' => 'Ыңгайлаштыруу',
'changepassword' => 'Сырсөздү өзгөртүү',
'prefs-datetime' => 'Дата жана убакыт',
'prefs-rc' => 'Соңку өзгөрүүлөр',
-'prefs-watchlist' => 'Байкоо тизме',
-'saveprefs' => 'СакÑ\82ап кой',
+'prefs-watchlist' => 'Байкоо тизмеси',
+'saveprefs' => 'СакÑ\82оо',
'prefs-editing' => 'Оңдоо',
'searchresultshead' => 'Издөө',
'localtime' => 'Жергиликтүү убакыт',
+'servertime' => 'Сервер убагы:',
+'timezoneregion-africa' => 'Африка',
+'timezoneregion-america' => 'Америка',
+'timezoneregion-antarctica' => 'Антарктика',
+'timezoneregion-arctic' => 'Арктика',
+'timezoneregion-asia' => 'Азия',
+'timezoneregion-atlantic' => 'Атлантика океаны',
+'timezoneregion-australia' => 'Австралия',
+'timezoneregion-europe' => 'Европа',
+'timezoneregion-indian' => 'Индий океаны',
+'timezoneregion-pacific' => 'Тынч океаны',
+'prefs-searchoptions' => 'Издөө',
+'default' => 'жарыяланбасча',
'prefs-files' => 'Файлдар',
'youremail' => 'Электрондук дарек:',
'username' => 'Колдонуучунун аты:',
'yourlanguage' => 'Тил:',
'yourvariant' => 'Вариант:',
'yournick' => 'Такма атыңыз:',
+'yourgender' => 'Жыныс:',
+'gender-male' => 'Эркек',
+'gender-female' => 'Аял',
+'email' => 'Электрондук дарек',
'prefs-help-email' => 'Электрондук дарек милдетүү эмес, бирок сырсөздү унутуп калсаңыз ал сырсөздү жиберүүгө керек.',
'prefs-help-email-others' => 'Ошондой эле башкалар сиз менен колдонуучу же талкуу барактарыңыздагы шилтеме аркылуу байланыш түзүүгө уруксат берүүнү тандай аласыз.
Электрондук дарегиңиз башка кодонуучуларга байланыш түзгөндө көрүнбөйт.',
+'prefs-info' => 'Негизги маалыматтары',
'prefs-advancedediting' => 'Кеңейтилген',
'prefs-advancedrc' => 'Кеңейтилген',
'prefs-advancedrendering' => 'Кеңейтилген',
'prefs-advancedwatchlist' => 'Кеңейтилген',
'prefs-displayrc' => 'Көрсөтүүнү тууралоо',
+# User rights
+'userrights-reason' => 'Себеп:',
+
# Groups
'group' => 'Топ:',
+'group-user' => 'Катышуучулар',
+'group-sysop' => 'Администраторлор',
'group-bureaucrat' => 'Бюрократтар',
'group-bureaucrat-member' => 'Бюрократ',
# Associated actions - in the sentence "You do not have permission to X"
-'action-edit' => 'бул баракты оңдо',
+'action-edit' => 'бул баракты оңдоо',
# Recent changes
'nchanges' => '$1 {{PLURAL:$1|өзгөрүү|өзгөрүү}}',
'recentchanges-label-unpatrolled' => 'Бул оңдоо көзөмөлдөн өтө элек.',
'rcnote' => "Ылдый жакта $5, $4 карата соңку {{PLURAL:$2|күндө|'''$2''' күндө}} жасалган {{PLURAL:$1| '''1''' өзгөрүү| '''$1''' өзгөрүү}}.",
'rcnotefrom' => "'''$2''' -тан өзгөрүүлөр ылдый жакта ('''$1''' чейин көрсөтүлдү).",
-'rclistfrom' => '$1 күнүнөн баштап жаңы өзгөртүүлөрдү көрсөт',
+'rclistfrom' => '$1 күнүнөн баштап жаңы өзгөртүүлөрдү көрсөтүү',
'rcshowhideminor' => 'Майда оңдоолорду $1',
'rcshowhidebots' => 'ботторду $1',
'rcshowhideliu' => '$1 катталган колдонуучу',
'rcshowhideanons' => 'Жашыруун колдонуучулар $1',
'rcshowhidepatr' => 'Көзөмөл алдындагы оңдоолорду $1',
'rcshowhidemine' => 'Оңдоолорумду $1',
-'rclinks' => 'Соңку $2 кундө жасалган акыркы $1 өзгөртүүлөрдү көрсөт<br />$3',
+'rclinks' => 'Соңку $2 күндө жасалган акыркы $1 өзгөртүүлөрдү көрсөтүү<br />$3',
'diff' => 'айырма',
-'hist' => 'тарыхы',
-'hide' => 'Жашыр',
-'show' => 'Көрсөт',
+'hist' => 'тарых',
+'hide' => 'Жашыруу',
+'show' => 'Көрсөтүү',
'minoreditletter' => 'м',
'newpageletter' => 'Ж',
'boteditletter' => 'б',
-'rc-enhanced-expand' => 'Ð\91өлүкÑ\82Ó©Ñ\80үн көÑ\80Ñ\81Ó©Ñ\82 (JavaScript талап кылынат)',
-'rc-enhanced-hide' => 'Ð\91өлүкÑ\82Ó©Ñ\80үн жаÑ\88Ñ\8bÑ\80',
+'rc-enhanced-expand' => 'Ð\9aоÑ\88Ñ\83мÑ\87а маалÑ\8bмаÑ\82Ñ\82аÑ\80дÑ\8b көÑ\80Ñ\81Ó©Ñ\82Ò¯Ò¯ (JavaScript талап кылынат)',
+'rc-enhanced-hide' => 'Ð\9aоÑ\88Ñ\83мÑ\87а маалÑ\8bмаÑ\82Ñ\82аÑ\80дÑ\8b жаÑ\88Ñ\8bÑ\80Ñ\83Ñ\83',
# Recent changes linked
'recentchangeslinked' => 'Тиешелүү өзгөрүүлөр',
'recentchangeslinked-summary' => 'Бул көрсөтүлгөн (же көрсөтүлгөн категорияга кирген) барактан шилтемеленген барактардагы жакын арада жасалган өзгөрүүлөрдүн тизмеси.
[[Special:Watchlist|Байкоо тизмеңиз]]деги барактар калын арип менен белгиленген.',
'recentchangeslinked-page' => 'Барактын аталышы',
-'recentchangeslinked-to' => 'Белгиленген барактан шилтемеленген барактардын ордуна өзгөртүулөрдү көрсөт',
+'recentchangeslinked-to' => 'Белгиленген барактан шилтемеленген барактардын ордуна өзгөртүулөрдү көрсөтүү',
# Upload
-'upload' => 'Файл жүктөө',
-'uploadbtn' => 'Файл жүктөө',
+'upload' => 'Файлды жүктөө',
+'uploadbtn' => 'Файлды жүктөө',
+'uploaderror' => 'Жүктөө катасы',
'uploadlogpage' => 'Жүктөөлөрдүн тизмеси',
'filedesc' => 'Кыска түшүндүрмө',
'fileuploadsummary' => 'Кыска түшүндүрмө:',
'sharedupload-desc-here' => 'Бул файл $1 -дан жана башка долбоорлордо пайдаланылышы мүмкүн.
Төмөндө анын [$2 файлды сыпаттоо барагы]нан сыпаттамасы көрсөтүлгөн.',
+# File reversion
+'filerevert-comment' => 'Себеп:',
+
+# File deletion
+'filedelete-legend' => 'Файлды өчүрүү',
+'filedelete-comment' => 'Себеп:',
+'filedelete-submit' => 'Өчүрүү',
+
# Unused templates
'unusedtemplates' => 'Колдонулбаган нускалар',
'unusedtemplateswlh' => 'Башка шилтемелер',
# Statistics
'statistics' => 'Статистика',
'statistics-header-users' => 'Колдонуучулардын статистикасы',
+'statistics-pages' => 'Барак',
'disambiguationspage' => 'Template:көп маанилүү',
+'brokenredirects-delete' => 'өчүрүү',
+
+'withoutinterwiki-submit' => 'Көрсөтүү',
+
# Miscellaneous special pages
'nbytes' => '$1 {{PLURAL:$1|байт|байт}}',
'nmembers' => '$1{{PLURAL:$1|мүчө|мүчө}}',
'unusedcategories' => 'Колдонулбаган категориялар',
'unusedimages' => 'Колдонулбаган файлдар',
+'popularpages' => 'Популярдуу барактар',
'prefixindex' => 'Префикс менен бардык барактар',
'shortpages' => 'Кыска макалалар',
'listusers' => 'Колдонуучулар тизмеси',
'booksources-go' => 'Алга',
# Special:Log
-'specialloguserlabel' => 'Ð\9aолдонуучу:',
+'specialloguserlabel' => 'Ð\90Ñ\82каÑ\80уучу:',
'speciallogtitlelabel' => 'Аталышы:',
'log' => 'Тизмелер',
'allpages' => 'Бардык барактар',
'alphaindexline' => '$1 -дан $2 чейин',
'nextpage' => 'Кийинки барак ($1)',
-'allpagesfrom' => '-дан башталган барактарды көрсөт:',
+'allpagesfrom' => '-дан башталган барактарды көрсөтүү:',
'allarticles' => 'Бардык макалалар',
-'allpagesprev' => 'Ð\9cÑ\83Ñ\80Ñ\83нкÑ\83',
+'allpagesprev' => 'Ð\90балкÑ\8b',
'allpagesnext' => 'Кийинки',
'allpagessubmit' => 'Алга',
-'allpagesprefix' => '- префикси менен барактарды көрсөт',
+'allpagesprefix' => '- префикси менен барактарды көрсөтүү',
# Special:Categories
'categories' => 'Категориялар',
# Special:LinkSearch
+'linksearch-ok' => 'Издөө',
'linksearch-line' => '$1-га $2-дан шилтеме берилди',
+# Special:ListUsers
+'listusers-submit' => 'Көрсөтүү',
+
# Special:Log/newusers
'newuserlogpage' => 'Жаңы колдонуучулардын тизмеси',
'listgrouprights-members' => '(мүчөлөрдүн тизмеси)',
# E-mail user
-'emailuser' => 'Бул колдонуучуга кат жибер',
+'emailuser' => 'Бул колдонуучуга кат жиберүү',
'emailfrom' => '- дан',
-'emailmessage' => 'Кат',
+'emailto' => 'Кимге:',
+'emailsubject' => 'Тема:',
+'emailmessage' => 'Билдирме',
# Watchlist
'watchlist' => 'Көзөмөл тизмем',
'mywatchlist' => 'Көзөмөл тизмем',
'watchlistfor2' => '$1 үчүн $2',
'watchnologin' => 'Катталган жок',
-'watch' => 'Көзөмөлдө',
-'unwatch' => 'Көзөлдөбө',
+'watch' => 'Көзөмөлдөө',
+'unwatch' => 'Көзөлдөбөө',
'watchlist-details' => 'Талкуу барактарын эсепке албаганда көзөмөл тизмеңизде {{PLURAL:$1|$1 барак|$1 барак}} бар.',
'watchlistcontains' => 'Байкоо тизмеңизде $1 {{PLURAL:$1|барак бар|барак бар}}.',
-'wlshowlast' => 'Соңку $1 саат $2 күн $3 көрсөт.',
+'wlshowlast' => 'Соңку $1 саат $2 күн $3 көрсөтүү.',
'watchlist-options' => 'Көзөмөл тизменин ырастоолору',
'changed' => 'өзгөртүлдү',
'created' => 'түзүлдү',
# Delete
-'deletepage' => 'Баракты өчүрүп кой',
+'deletepage' => 'Баракты өчүрүү',
'confirm' => 'Ырастоо',
'actioncomplete' => 'Иш-аракет жыйынтыкталды',
'actionfailed' => 'Аракет натыйжасыз болду',
'deletecomment' => 'Себеп',
# Rollback
-'rollbacklink' => 'кайтар',
+'rollbacklink' => 'кайтаруу',
# Protect
'protectlogpage' => 'Коргоо тизмеси',
'protectedarticle' => '"[[$1]]" корголгон',
+'restriction-type' => 'Укуктар:',
# Restrictions (nouns)
'restriction-edit' => 'Оңдоо',
+'restriction-create' => 'Жаратуу',
+'restriction-upload' => 'Жүктөө',
# Undelete
-'undeletebtn' => 'Калыбына келтир',
-'undeletelink' => 'көрсөт/калыбына келтир',
-'undeleteviewlink' => 'көрсөт',
-'undeletecomment' => 'Түшүндүрмө:',
+'undeletebtn' => 'Калыбына келтирүү',
+'undeletelink' => 'кароо/калыбына келтирүү',
+'undeleteviewlink' => 'кароо',
+'undeletereset' => 'Түшүрүү',
+'undeletecomment' => 'Себеп:',
+'undelete-search-submit' => 'Издөө',
# Namespace form on various pages
'namespace' => 'Аталыштар мейкиндиги:',
-'invert' => 'Белгиленгенди кайтар',
+'invert' => 'Белгиленгенди текскерилетүү',
'blanknamespace' => '(Негизги)',
# Contributions
'sp-contributions-uploads' => 'жүктөөлөр',
'sp-contributions-logs' => 'тизме',
'sp-contributions-talk' => 'талкуу',
-'sp-contributions-search' => 'СалÑ\8bмдаÑ\80Ñ\8bн изде',
+'sp-contributions-search' => 'СалÑ\8bмдаÑ\80Ñ\8bмдÑ\8b издөө',
'sp-contributions-username' => 'IP дареги же колдонуучунун аты:',
'sp-contributions-toponly' => 'Соңку версиялары болгон оңдоолорду гана көрсөт',
-'sp-contributions-submit' => 'Изде',
+'sp-contributions-submit' => 'Издөө',
# What links here
'whatlinkshere' => 'Жетелеме шилтемелер',
'linkshere' => "'''[[:$1]]''' барагына шилтеме берген барактар:",
'nolinkshere' => "'''[[:$1]]''' барагына шилтеме берген барак жок.",
'isredirect' => 'кайра багыттоо барагы',
-'istemplate' => 'кошкуч',
+'istemplate' => 'кошуу',
'isimage' => 'файл шилтемеси',
'whatlinkshere-prev' => '{{PLURAL:$1|мурунку|мурунку $1}}',
'whatlinkshere-next' => '{{PLURAL:$1|кийинки|кийинки $1}}',
'whatlinkshere-links' => '← шилтемелер',
'whatlinkshere-hideredirs' => 'Багыттоолорду $1',
-'whatlinkshere-hidetrans' => 'Кошкучтарды $1',
+'whatlinkshere-hidetrans' => '$1 кошуулары',
'whatlinkshere-hidelinks' => 'Шилтемелерди $1',
'whatlinkshere-hideimages' => 'Сүрөт шилтемелерин $1',
'whatlinkshere-filters' => 'Чыпкалар',
'ipboptions' => '2 саат:2 hours,1 күн:1 day,3 күн:3 days,1 жума:1 week,2 жума:2 weeks,1 ай:1 month,3 ай:3 months,6 ай:6 months,1 жыл:1 year,мөөнөтсүз:infinite',
'ipbotheroption' => 'башка',
'ipblocklist' => 'Тосмолонгон колдонуучулар',
-'blocklink' => 'тосмоло',
-'unblocklink' => 'тосмолоону алып сал',
-'change-blocklink' => 'тосмолоону өзгөрт',
-'contribslink' => 'салымдары',
+'blocklist-reason' => 'Себеп',
+'ipblocklist-submit' => 'Издөө',
+'blocklink' => 'тосмолоо',
+'unblocklink' => 'тосмолоону алуу',
+'change-blocklink' => 'тосмолоону өзгөртүү',
+'contribslink' => 'салым',
+'emaillink' => 'кат жиберүү',
'blocklogpage' => 'Тосмоолордун тизмеси',
'blocklogentry' => '[[$1]] тосмолонду, тосмолоо мөөнөтү: $2 $3',
'block-log-flags-nocreate' => 'Каттоо мүмкүн эмес',
# Move page
'movelogpage' => 'Өзгөртүлгөн аталыштардын тизмеси',
'movereason' => 'Себеп',
-'revertmove' => 'кайÑ\82аÑ\80Ñ\8bп ал',
-'delete_and_move_confirm' => 'Ооба, бул баракты өчүр',
+'revertmove' => 'кайÑ\82аÑ\80Ñ\83Ñ\83',
+'delete_and_move_confirm' => 'Ооба, бул баракты өчүрөм',
# Export
-'export' => 'Барактарды чыгар',
+'export' => 'Барактарды экспорттоо',
+'export-addcat' => 'Кошуу',
+'export-addns' => 'Кошуу',
# Namespace 8 related
'allmessages' => 'Система билдирүүлөрү',
'allmessages-filter-submit' => 'Алга',
# Thumbnails
-'thumbnail-more' => 'Чоңойт',
+'thumbnail-more' => 'Чоңойтуу',
'thumbnail_error' => 'Кичирейтилген сүрөттү түзүүдө ката: $1',
+# Special:Import
+'import-interwiki-submit' => 'Импорттоо',
+
# Tooltip help for the actions
-'tooltip-pt-userpage' => 'Ð\9aолдонуучу барагыңыз',
-'tooltip-pt-mytalk' => 'Талкуу барагыңыз',
+'tooltip-pt-userpage' => 'Ð\9aаÑ\82Ñ\8bÑ\88уучу барагыңыз',
+'tooltip-pt-mytalk' => 'Талкуулоо барагыңыз',
'tooltip-pt-preferences' => 'Ырастоолоруңуз',
'tooltip-pt-watchlist' => 'Өзгөрүүлөрүн көзөмөлгө алган барактардын тизмеси',
'tooltip-pt-mycontris' => 'Салымдарыңыздын тизмеси',
'tooltip-pt-logout' => 'Чыгуу',
'tooltip-ca-talk' => 'Барактын мазмуну боюнча талкуу',
'tooltip-ca-edit' => 'Сиз бул баракты оңдой аласыз. Кичи пейилдикке, сактоодон мурда алдын ала көрсөтүү нукуурун колдонуңуз.',
-'tooltip-ca-addsection' => 'Жаңы бөлүм башта',
+'tooltip-ca-addsection' => 'Жаңы бөлүмдү баштөө',
'tooltip-ca-viewsource' => 'Бул барак корголгон.
Сиз анын кайнарын көрө аласыз',
'tooltip-ca-history' => 'Бул барактын мурунку оңдоолору',
-'tooltip-ca-protect' => 'Бул баракты корго',
-'tooltip-ca-delete' => 'Бул баракты өчүр',
-'tooltip-ca-move' => 'Барак аталышын өзгөрт',
+'tooltip-ca-protect' => 'Бул баракты коргоо',
+'tooltip-ca-delete' => 'Бул баракты өчүрүү',
+'tooltip-ca-move' => 'Баракты көчүрүү',
'tooltip-ca-watch' => 'Бул баракты көзөмөл тизмеңизге кошуңуз',
'tooltip-ca-unwatch' => 'Бул баракты көзөмөл тизмеңизден алып салыңыз',
-'tooltip-search' => '{{SITENAME}} изде',
-'tooltip-search-go' => 'Так ушундай аталыштагы баракты көрсөт',
-'tooltip-search-fulltext' => 'Ушул текст менен барактарды изде',
-'tooltip-p-logo' => 'Башбаракка кайрыл',
-'tooltip-n-mainpage' => 'Башбаракка кайрыл',
-'tooltip-n-mainpage-description' => 'Башбаракка кайрыл',
-'tooltip-n-portal' => 'Ð\94олбооÑ\80 Ñ\82Ñ\83Ñ\83Ñ\80алÑ\83Ñ\83, Ñ\8dмне жаÑ\81ай алаÑ\81Ñ\8bз, кайÑ\81Ñ\8b жеÑ\80де Ñ\82абÑ\8bлаÑ\82',
-'tooltip-n-currentevents' => 'УÑ\87Ñ\83Ñ\80дагÑ\8b окÑ\83Ñ\8fлаÑ\80 Ñ\82Ñ\83Ñ\83Ñ\80алÑ\83Ñ\83 коÑ\88Ñ\83мÑ\87а маалÑ\8bмаÑ\82 Ñ\82ап',
+'tooltip-search' => '{{SITENAME}} издөө',
+'tooltip-search-go' => 'Так ушундай аталыштагы баракты көрсөтүү',
+'tooltip-search-fulltext' => 'Ушул текст менен барактарды издөө',
+'tooltip-p-logo' => 'Башбаракка өтүү',
+'tooltip-n-mainpage' => 'Башбаракка өтүү',
+'tooltip-n-mainpage-description' => 'Башбаракка өтүү',
+'tooltip-n-portal' => 'Ð\94олбооÑ\80 Ñ\82Ñ\83Ñ\83Ñ\80алÑ\83Ñ\83, Ñ\8dмне жаÑ\81ай алаÑ\81Ñ\8bз, кайÑ\81Ñ\8b жеÑ\80де Ñ\8dмне баÑ\80 жөнүндө',
+'tooltip-n-currentevents' => 'УÑ\87Ñ\83Ñ\80дагÑ\8b окÑ\83Ñ\8fлаÑ\80 Ñ\82Ñ\83Ñ\83Ñ\80алÑ\83Ñ\83 коÑ\88Ñ\83мÑ\87а маалÑ\8bмаÑ\82 Ñ\82абÑ\83Ñ\83',
'tooltip-n-recentchanges' => 'Уикидеги соңку өзгөртүүлөрдүн тизмеси',
-'tooltip-n-randompage' => 'ТÑ\83Ñ\88 келди баÑ\80акÑ\82Ñ\8b жүкÑ\82Ó©',
+'tooltip-n-randompage' => 'Ð\98Ñ\80еÑ\82Ñ\81из Ñ\82Ò¯Ñ\80дө биÑ\80 баÑ\80акÑ\82Ñ\8b аÑ\87Ñ\83Ñ\83',
'tooltip-n-help' => 'Маалымат алуу үчүн',
'tooltip-t-whatlinkshere' => 'Ушул жерге шилтемеси бар бардык уики барактардын тизмеси',
'tooltip-t-recentchangeslinked' => 'Бул барактан шилтеме берилген барактардагы соңку өзгөрүүлөр',
'tooltip-feed-atom' => 'Бул барак үчүн Atom агымы',
'tooltip-t-contributions' => 'Бул колдонуучунун салымдарынын тизмеси',
-'tooltip-t-emailuser' => 'Бул колдонуучуга кат жибер',
-'tooltip-t-upload' => 'Файлдарды жүктө',
+'tooltip-t-emailuser' => 'Бул колдонуучуга кат жиберүү',
+'tooltip-t-upload' => 'Файлдарды жүктөө',
'tooltip-t-specialpages' => 'Бардык атайын барактардын тизмеси',
'tooltip-t-print' => 'Бул барактын басып чыгарууга ылайыктуу түрү',
'tooltip-t-permalink' => 'Барактын бул версиясына туруктуу шилтеме',
-'tooltip-ca-nstab-main' => 'Ð\91аÑ\80акÑ\82Ñ\8bн мазмÑ\83нÑ\83н каÑ\80а',
-'tooltip-ca-nstab-user' => 'Ð\9aолдонÑ\83Ñ\83Ñ\87Ñ\83нÑ\83н жеке баÑ\80агÑ\8bн көÑ\80Ñ\81Ó©Ñ\82',
+'tooltip-ca-nstab-main' => 'Ð\91аÑ\80акÑ\82Ñ\8bн мазмÑ\83нÑ\83н каÑ\80оо',
+'tooltip-ca-nstab-user' => 'Ð\9aаÑ\82Ñ\8bÑ\88Ñ\83Ñ\83Ñ\87Ñ\83нÑ\83н баÑ\80агÑ\8bн көÑ\80Ñ\81Ó©Ñ\82Ò¯Ò¯',
'tooltip-ca-nstab-special' => 'Бул атайын барак, аны оңдой албайсыз',
-'tooltip-ca-nstab-project' => 'Долбоор барагын кара',
-'tooltip-ca-nstab-image' => 'Файл барагын көрсөт',
-'tooltip-ca-nstab-template' => 'Ð\9aалÑ\8bпÑ\82Ñ\8b көÑ\80Ñ\81Ó©Ñ\82',
-'tooltip-ca-nstab-category' => 'Категория барагын көрсөт',
-'tooltip-minoredit' => 'Муну майда оңдоо деп белгиле',
-'tooltip-save' => 'ӨзгөÑ\80Ñ\82үүлөÑ\80дү Ñ\81акÑ\82ап кой',
+'tooltip-ca-nstab-project' => 'Долбоор барагын көрүү',
+'tooltip-ca-nstab-image' => 'Файл барагын көрүү',
+'tooltip-ca-nstab-template' => 'ШаблондÑ\83 көÑ\80Ò¯Ò¯',
+'tooltip-ca-nstab-category' => 'Категория барагын көрүү',
+'tooltip-minoredit' => 'Муну майда оңдоо деп белгилөө',
+'tooltip-save' => 'ӨзгөÑ\80Ñ\82үүлөÑ\80дү Ñ\81акÑ\82оо',
'tooltip-preview' => 'Кичи пейлдикке, өзгөртүүлөрдү алдын ала көрсөтүүнү сактоодон мурун колдонуңуз!',
-'tooltip-diff' => 'Тексттке киргизген өзгөртүүлөрдү көрсөт',
-'tooltip-compareselectedversions' => 'Ð\91Ñ\83л баÑ\80акÑ\82Ñ\8bн Ñ\82андалган Ñ\8dки веÑ\80Ñ\81иÑ\8fÑ\81Ñ\8bнÑ\8bн айÑ\8bÑ\80малаÑ\80Ñ\8bн каÑ\80а',
+'tooltip-diff' => 'Тексттке киргизген өзгөртүүлөрдү көрсөтүү',
+'tooltip-compareselectedversions' => 'Ð\91Ñ\83л баÑ\80акÑ\82Ñ\8bн Ñ\82андалган Ñ\8dки веÑ\80Ñ\81иÑ\8fÑ\81Ñ\8bнÑ\8bн айÑ\8bÑ\80малаÑ\80Ñ\8bн каÑ\80оо',
'tooltip-watch' => 'Бул баракты көзөмөл тизмеңизге кошуңуз',
'tooltip-rollback' => '"Кайтар" бир баскыч менен бул барактын соңку оңдоочусунун өзгөртүүлөрүн алып салат',
'tooltip-undo' => 'Киргизилген оңдоону алып салат жана жокко чыгаруунун себебин белгилөөгө мүмкүнчүлүк берип алдын ала көрсөтүүнү ачат',
-'tooltip-summary' => 'Ð\9aÑ\8bÑ\81ка коÑ\80Ñ\83Ñ\82Ñ\83ндÑ\83 киÑ\80гиз',
+'tooltip-summary' => 'Ð\9aÑ\8bÑ\81ка баÑ\8fндаманÑ\8b киÑ\80гизиңиз',
# Attribution
'others' => 'башкалар',
# Browsing diffs
-'previousdiff' => 'â\86\90 Ð\9cÑ\83Ñ\80Ñ\83нкÑ\83 оңдоо',
-'nextdiff' => 'Жаңы түзөтүү →',
+'previousdiff' => 'â\86\90 ÐÑ\81киÑ\81ин оңдоо',
+'nextdiff' => 'Жаңысын оңдоо →',
# Media information
-'file-info-size' => '$1 × $2 пиксел, файлдын көлөмү: $3, MIME тиби: $4',
+'file-info-size' => '$1 × $2 пиксель, файлдын көлөмү: $3, MIME түрү: $4',
'file-nohires' => 'Мындан дагы толук чечилиши жок.',
'svg-long-desc' => 'SVG файл, шарттуу түрдө $1 × $2 пиксел, файлдын көлөмү: $3',
-'show-big-image' => 'ТолÑ\83к Ñ\87еÑ\87илиÑ\88и',
+'show-big-image' => 'ТолÑ\83к Ñ\87еÑ\87ими',
# Special:NewFiles
'newimages' => 'Жаңы файлдардын галлереясы',
'exif-focalplaneresolutionunit-2' => 'дюйм',
# External editor support
-'edit-externally' => 'Бул файлды сырткы программа колдонуу аркылуу оңдо',
+'edit-externally' => 'Бул файлды сырткы программа колдонуу аркылуу оңдоо',
'edit-externally-help' => '(Толук маалымат алуу үчүн [//www.mediawiki.org/wiki/Manual:External_editors setup instructions] барагына кайрылсаңыз болот)',
# 'all' in various places, this might be different for inflected languages
'confirmemail_loggedin' => 'Электрондук дарегиңиз ырасталды.',
# Watchlist editing tools
-'watchlisttools-view' => 'Тийиштүү өзгөрүүлөрдү көрсөт',
-'watchlisttools-edit' => 'Көзөмөл тизмени кара жана оңдо',
-'watchlisttools-raw' => 'Жетиле элек көзөмөл тизмени оңдо',
+'watchlisttools-view' => 'Тийиштүү өзгөрүүлөрдү көрсөтүү',
+'watchlisttools-edit' => 'Көзөмөл тизмени кара жана оңдоо',
+'watchlisttools-raw' => 'Жетиле элек көзөмөл тизмени оңдоо',
# Core parser functions
'duplicate-defaultsort' => '\'\'\'Эскертүү:\'\'\' "$2" белгиленген ылгоочу ачкыч "$1" мурунку белгиленген ылгоочу ачкычты жокко чыгарат.',
'specialpages' => 'Атайын барактар',
# External image whitelist
-'external_image_whitelist' => ' #Бул сапты болгондой калтыр<pre>
-#Туруктуу айтылыштардын бөлүмдөрүн (// арасындагы бөлүмүн гана) астына жайгаштыр
+'external_image_whitelist' => ' #Бул сапты болгондой калтыруу<pre>
+#Туруктуу айтылыштардын бөлүмдөрүн (// арасындагы бөлүмүн гана) астына жайгаштыру
#Алар сырткы сүрөттөрдүн URL менен байланыштырылат
#Ылайыктуулары сүрөт болуп көрсөтүлөт, калгандары сүрөттөргө шилтеме болуп көрсөтүлөт
## менен башталган саптар, түшүндүрмө болуп эсептелет
#Баш же кичине тамга айырмасыз
-#Туруктуу айтылыштардын бөлүмдөрүн ушул саптын үстүнө жайгаштыр. Бул сапты болгондой калтыр.</pre>',
+#Туруктуу айтылыштардын бөлүмдөрүн ушул саптын үстүнө жайгаштыр. Бул сапты болгондой калтыруу.</pre>',
# Special:Tags
'tag-filter' => '[[Special:Tags|Энбелги]] чыпкасы:',
+# Feedback
+'feedback-subject' => 'Тема:',
+'feedback-message' => 'Билдирме:',
+'feedback-cancel' => 'Айнуу',
+'feedback-close' => 'Даяр',
+
+# Search suggestions
+'searchsuggest-search' => 'Издөө',
+
);
'newwindow' => '(in fenestra nova aperietur)',
'cancel' => 'Abrogare',
'moredotdotdot' => 'Plus...',
-'mypage' => 'Pagina mea',
-'mytalk' => 'Disputatio mea',
+'mypage' => 'Pagina',
+'mytalk' => 'Disputatio',
'anontalk' => 'Disputatio huius IP',
'navigation' => 'Navigatio',
'and' => ' et',
# Preferences page
'preferences' => 'Praeferentiae',
-'mypreferences' => 'Praeferentiae meae',
+'mypreferences' => 'Praeferentiae',
'prefs-edits' => 'Numerus recensionum:',
'prefsnologin' => 'Conventum non est apertum',
'prefsnologintext' => '<span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} Conventum aperire]</span> debes ad praeferentias tuas modificandum.',
# Contributions
'contributions' => 'Conlationes usoris',
'contributions-title' => 'Conlationes usoris $1',
-'mycontris' => 'Conlationes meae',
+'mycontris' => 'Conlationes',
'contribsub2' => 'Pro $1 ($2)',
'nocontribs' => 'Nullae mutationes inventae sunt ex his indiciis.',
'uctop' => ' (vertex)',
'newwindow' => '(geet an enger neier Fënster op)',
'cancel' => 'Zréck',
'moredotdotdot' => 'Méi …',
-'mypage' => 'Meng Säit',
-'mytalk' => 'Meng Diskussioun',
+'mypage' => 'Säit',
+'mytalk' => 'Diskussioun',
'anontalk' => 'Diskussioun fir dës IP Adress',
'navigation' => 'Navigatioun',
'and' => ' a(n)',
# Preferences page
'preferences' => 'Astellungen',
-'mypreferences' => 'Meng Astellungen',
+'mypreferences' => 'Astellungen',
'prefs-edits' => 'Zuel vun den Ännerungen:',
'prefsnologin' => 'Net ageloggt',
'prefsnologintext' => 'Dir musst <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}}ageloggt]</span> sinn, fir Är Astellungen änneren ze kënnen.',
'linksearch-pat' => 'Sich-Critère:',
'linksearch-ns' => 'Nummraum:',
'linksearch-ok' => 'Sichen',
-'linksearch-text' => 'Sougennante "Wildcards" wéi zum Beispill <code>*.example.com</code> kënne benotzt ginn.
+'linksearch-text' => '"Wildcards" wéi zum Beispill "*.example.com" kënne benotzt ginn.
Et muss mindestens en Top-Level-Domaine ugi ginn, wéi z. Bsp. ".org".<br />
-Ënnerstëtzte Protekoller: <code>$1</code>',
+Ënnerstëtzte Protekoller: <code>$1</code> (http:// gëtt benotzt wann näischt spezifizéiert gëtt).',
'linksearch-line' => '$1 verlinkt vun $2',
'linksearch-error' => 'Wildcards (*,?) kënnen nëmmen am Ufank vum Host-Numm benotzt ginn.',
# Watchlist
'watchlist' => 'Meng Iwwerwaachungslëscht',
-'mywatchlist' => 'Meng Iwwerwaachungslëscht',
+'mywatchlist' => 'Iwwerwaachungslëscht',
'watchlistfor2' => 'Vum $1 $2',
'nowatchlist' => 'Är Iwwerwaachungslëscht ass eidel.',
'watchlistanontext' => "Dir musst $1 fir Säiten op ärer Iwwerwaachungslëscht ze gesinn oder z'änneren.",
# Contributions
'contributions' => 'Kontributioune vum Benotzer',
'contributions-title' => 'Kontributioune vum $1',
-'mycontris' => 'Meng Kontributiounen',
+'mycontris' => 'Kontributiounen',
'contribsub2' => 'Fir $1 ($2)',
'nocontribs' => 'Et goufe keng Ännerunge fonnt, déi dëse Kritèren entspriechen.',
'uctop' => '(aktuell)',
'whatlinkshere-hideredirs' => 'Viruleedunge $1',
'whatlinkshere-hidetrans' => 'Agebonne Schabloune $1',
'whatlinkshere-hidelinks' => 'Linken $1',
-'whatlinkshere-hideimages' => '$1 Linken op de Fichier',
+'whatlinkshere-hideimages' => 'Linken op Fichiere $1',
'whatlinkshere-filters' => 'Filteren',
# Block/unblock
'mailnologin' => 'Tsy misy adiresy handefasana ny tenimiafina',
'mailnologintext' => "Mila [[Special:UserLogin|miditra]] ianao sady manana imailaka mandeha sy voamarina ao amin'ny [[Special:Preferences|mombamomba anao]] vao afaka mandefa imailaka amin'ny mpikambana hafa.",
'emailuser' => 'Andefaso imailaka io mpikambana io',
+'emailuser-title-target' => "Handefa mailaka any amin'ity mpikambana ity{{GENDER:$1}}",
'emailuser-title-notarget' => "Handefa imailaka an'ilay mpikambana",
'emailpage' => 'Andefaso imailaka io mpikambana io',
'emailpagetext' => "Raha nametraka adiresy tena miasa tao amin'ny [[Special:Preferences|mombamomba azy io mpikambana io]],
'rollback' => 'Foano indray ilay fanovana',
'rollback_short' => 'Aza ovaina indray',
'rollbacklink' => 'foano',
+'rollbacklinkcount' => 'hamoana fanovana{{PLURAL:$1}} $1',
'rollbackfailed' => "Tsy voaverina amin'ny teo aloha",
'cantrollback' => "Tsy afaka iverenana ny fanovana; ny mpanova farany ihany no tompon'ny pejy.",
'alreadyrolled' => "Tsy afaka foanana ny fanovana ny pejy « [[:$1]] » nataon'i [[User:$2|$2]] ([[User talk:$2|Dinika]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]])
'whatlinkshere-hideredirs' => '$1 ny fihodinana',
'whatlinkshere-hidetrans' => '$1 ny tsofo-pejy',
'whatlinkshere-hidelinks' => '$1 ny rohy',
-'whatlinkshere-hideimages' => '$1 rakitra mirohy',
+'whatlinkshere-hideimages' => '$1 ny rakitra mirohy',
'whatlinkshere-filters' => 'sivana',
# Block/unblock
'bydate' => 'araka ny daty',
'sp-newimages-showfrom' => "Aseho ny rakitra vaovao manomboka amin'ny $1 tamin'ny $2",
+# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
+'seconds' => 'segondra{{PLURAL:$1}}',
+'minutes' => 'minitra{{PLURAL:$1}}',
+'hours' => 'ora{{PLURAL:$1}}',
+'days' => 'andro{{PLURAL:$1}}',
+'ago' => '$1 lasa izay',
+
# Bad image list
'bad_image_list' => "Ity ny andrefiny :
'newwindow' => '(се отвора во нов прозорец)',
'cancel' => 'Откажи',
'moredotdotdot' => 'Повеќе...',
-'mypage' => 'Ð\9cоÑ\98а Ñ\81траница',
-'mytalk' => 'мои Ñ\80азговоÑ\80и',
+'mypage' => 'Страница',
+'mytalk' => 'РазговоÑ\80',
'anontalk' => 'Разговор за оваа IP-адреса',
'navigation' => 'Навигација',
'and' => ' и',
# Preferences page
'preferences' => 'Нагодувања',
-'mypreferences' => 'мои нагодувања',
+'mypreferences' => 'Ð\9dагодувања',
'prefs-edits' => 'Број на уредувања:',
'prefsnologin' => 'Не сте најавени',
'prefsnologintext' => 'Мора да бидете <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} најавени]</span> за да ги менувате вашите кориснички нагодувања.',
'linksearch-ns' => 'Именски простор:',
'linksearch-ok' => 'Барај',
'linksearch-text' => 'Може да се користат џокери, како на „*.wikipedia.org“.
-Бара највисок домен, како на пр. „*.org“.<br />
-Ð\9fоддÑ\80жани пÑ\80оÑ\82околи: <code>$1</code> (не ги Ñ\81Ñ\82аваÑ\98Ñ\82е во пÑ\80ебаÑ\80Ñ\83ваÑ\9aеÑ\82о).',
+Ð\91аÑ\80а баÑ\80ем наÑ\98виÑ\81ок домен, како на пÑ\80. â\80\9e*.orgâ\80\9c.<br />
+Ð\9fоддÑ\80жани пÑ\80оÑ\82околи: <code>$1</code> (задава http:// ако не Ñ\83кажеÑ\82е пÑ\80оÑ\82окол).',
'linksearch-line' => '$1 врска во $2',
'linksearch-error' => 'Џокер-знаците може да се користат само на почетокот во името на домаќинот.',
# Watchlist
'watchlist' => 'мои набљудувања',
-'mywatchlist' => 'мои набљудувања',
+'mywatchlist' => 'Ð\9dабљудувања',
'watchlistfor2' => 'За $1 $2',
'nowatchlist' => 'Немате ништо во списокот на набљудувања.',
'watchlistanontext' => 'Се бара $1 за да можете да го прегледувате и уредувате списокот на набљудувања.',
# Contributions
'contributions' => 'Кориснички придонеси',
'contributions-title' => 'Придонеси на корисникот $1',
-'mycontris' => 'мои придонеси',
+'mycontris' => 'Ð\9fридонеси',
'contribsub2' => 'За $1 ($2)',
'nocontribs' => 'Не се пронајдени промени што одговараат на овој критериум.',
'uctop' => ' (врв)',
'whatlinkshere-hideredirs' => '$1 пренасочувања',
'whatlinkshere-hidetrans' => '$1 превметнувања',
'whatlinkshere-hidelinks' => '$1 врски',
-'whatlinkshere-hideimages' => '$1 врски кон слика',
+'whatlinkshere-hideimages' => '$1 врски кон податотека',
'whatlinkshere-filters' => 'Филтри',
# Block/unblock
'duration-centuries' => '$1 {{PLURAL:$1|век|века}}',
'duration-millennia' => '$1 {{PLURAL:$1|милениум|милениуми}}',
+# Unknown messages
+'mytalk-parenthetical' => 'разговор',
);
'underline-always' => 'എല്ലായ്പ്പോഴും',
'underline-never' => 'ഒരിക്കലും അരുത്',
-'underline-default' => 'à´¬àµ\8dà´°àµ\97സറിലàµ\87à´¤àµ\81 à´ªàµ\8bà´²àµ\86',
+'underline-default' => 'à´¦àµ\83à´¶àµ\8dയരàµ\82പതàµ\8dതിൽ à´\85ഥവാ à´¬àµ\8dà´°àµ\97സറിൽ à´¸àµ\8dവതàµ\87à´¯àµ\81à´³àµ\8dà´³ à´¸àµ\8dà´µà´à´¾à´µà´\82',
# Font style option in Special:Preferences
'editfont-style' => 'തിരുത്തൽ മേഖലയിലെ ഫോണ്ടിന്റെ ശൈലി:',
'newwindow' => '(പുതിയ ജാലകത്തിൽ തുറന്നു വരും)',
'cancel' => 'റദ്ദാക്കുക',
'moredotdotdot' => 'കൂടുതൽ...',
-'mypage' => 'à´\8eà´¨àµ\8dà´±àµ\86 താൾ',
-'mytalk' => 'à´\8eà´¨àµ\8dà´±àµ\86 à´¸à´\82വാദതàµ\8dതാൾ',
+'mypage' => 'താൾ',
+'mytalk' => 'സംവാദത്താൾ',
'anontalk' => 'ഈ ഐ.പി.യുടെ സംവാദം താൾ',
'navigation' => 'ഉള്ളടക്കം',
'and' => ' ഒപ്പം',
'youhavenewmessages' => 'താങ്കൾക്ക് $1 ഉണ്ട് ($2).',
'newmessageslink' => 'പുതിയ സന്ദേശങ്ങൾ',
'newmessagesdifflink' => 'അവസാന മാറ്റം',
-'youhavenewmessagesfromusers' => 'താà´\99àµ\8dà´\95ൾà´\95àµ\8dà´\95àµ\8d {{PLURAL:$3|മറàµ\8dà´±àµ\8aà´°àµ\81 à´\89പയàµ\8bà´\95àµ\8dതാവàµ\8d|മറàµ\8dà´±àµ\8d $3 ഉപയോക്താക്കൾ}} $1 ചേർത്തിട്ടുണ്ട് ($2).',
+'youhavenewmessagesfromusers' => 'താà´\99àµ\8dà´\95ൾà´\95àµ\8dà´\95àµ\8d {{PLURAL:$3|à´\92à´°àµ\81 à´\89പയàµ\8bà´\95àµ\8dതാവàµ\8d|$3 ഉപയോക്താക്കൾ}} $1 ചേർത്തിട്ടുണ്ട് ($2).',
'youhavenewmessagesmanyusers' => 'താങ്കൾക്ക് പലർ $1 ചേർത്തിട്ടുണ്ട് ($2).',
'newmessageslinkplural' => '{{PLURAL:$1|പുതിയ സന്ദേശം|പുതിയ സന്ദേശങ്ങൾ}}',
'newmessagesdifflinkplural' => 'അവസാന {{PLURAL:$1|മാറ്റം|മാറ്റങ്ങൾ}}',
# Preferences page
'preferences' => 'ക്രമീകരണങ്ങൾ',
-'mypreferences' => 'à´\8eà´¨àµ\8dà´±àµ\86 à´\95àµ\8dà´°à´®àµ\80à´\95à´°à´£à´\99àµ\8dà´\99ൾ',
+'mypreferences' => 'ക്രമീകരണങ്ങൾ',
'prefs-edits' => 'ആകെ തിരുത്തലുകൾ:',
'prefsnologin' => 'ലോഗിൻ ചെയ്തിട്ടില്ല',
'prefsnologintext' => 'ഉപയോക്തൃക്രമീകരണങ്ങൾ മാറ്റാൻ താങ്കൾ <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} ലോഗിൻ]</span> ചെയ്തിരിക്കണം.',
'rightslogtext' => 'ഈ പ്രവർത്തനരേഖ ഉപയോക്തൃ അവകാശങ്ങൾക്കുണ്ടായ മാറ്റങ്ങളുടേതാണ്.',
'rightslogentry' => '$1 എന്ന ഉപയോക്താവിന്റെ സംഘ അംഗത്വം $2 എന്നതിൽ നിന്നു $3 എന്നതിലേക്കു മാറ്റിയിരിക്കുന്നു',
'rightslogentry-autopromote' => '$2 എന്നതിൽ നിന്ന് $3 എന്നതിലേയ്ക്ക് സ്വയം ഉയർത്തിയിരിക്കുന്നു',
+'logentry-rights-rights' => '$3 എന്ന ഉപയോക്താവിന്റെ സംഘ അംഗത്വം $1, $4 എന്നതിൽ നിന്നു $5 എന്നതിലേക്കു മാറ്റിയിരിക്കുന്നു',
+'logentry-rights-rights-legacy' => '$3 എന്ന ഉപയോക്താവിന്റെ സംഘ അംഗത്വം $1 മാറ്റിയിരിക്കുന്നു',
+'logentry-rights-autopromote' => '$1 എന്ന ഉപയോക്താവ് $4 എന്നതിൽ നിന്നും $5 എന്നതിലേയ്ക്ക് സ്വയം ഉയർത്തിയിരിക്കുന്നു',
'rightsnone' => '(ഒന്നുമില്ല)',
# Associated actions - in the sentence "You do not have permission to X"
'linksearch-ns' => 'നാമമേഖല:',
'linksearch-ok' => 'തിരയൂ',
'linksearch-text' => '"*.wikipedia.org" പോലുള്ള വൈൽഡ് കാർഡുകൾ ഉപയോഗിക്കാവുന്നതാണ്.
-കുറഞ്ഞത് "*.org" പോലുള്ള ടോപ്-ലെവൽ ഡൊമൈൻ എങ്കിലും ഉണ്ടായിരിക്കണം.<br />
-പിനàµ\8dതാà´\99àµ\8dà´\99àµ\81à´¨àµ\8dà´¨ à´ªàµ\8dà´°àµ\8bà´\9fàµ\8dà´\9fàµ\8bà´\95àµ\8dà´\95àµ\8bà´³àµ\81à´\95ൾ: <code>$1</code> (താà´\99àµ\8dà´\95à´³àµ\81à´\9fàµ\86 തിരà´\9aàµ\8dà´\9aിലിൽ à´\87à´µ à´\9aàµ\87ർà´\95àµ\8dà´\95à´°àµ\81à´¤്).',
+à´\95àµ\81à´±à´\9eàµ\8dà´\9eà´¤àµ\8d "*.org" à´ªàµ\8bà´²àµ\81à´³àµ\8dà´³ à´\92à´°àµ\81 à´\9fàµ\8bà´ªàµ\8d-à´²àµ\86വൽ à´¡àµ\8aà´®àµ\88ൻ à´\8eà´\99àµ\8dà´\95à´¿à´²àµ\81à´\82 à´\89à´£àµ\8dà´\9fായിരിà´\95àµ\8dà´\95à´£à´\82.<br />
+പിനàµ\8dà´¤àµ\81ണയàµ\81à´³àµ\8dà´³ à´ªàµ\8dà´°àµ\8bà´\9fàµ\8dà´\9fàµ\8bà´\95àµ\8dà´\95àµ\8bà´³àµ\81à´\95ൾ: <code>$1</code> (à´\92à´¨àµ\8dà´¨àµ\81à´\82 നൽà´\95ിയിലàµ\8dà´²àµ\86à´\99àµ\8dà´\95ിൽ à´¸àµ\8dവതàµ\87à´¯àµ\81à´³àµ\8dà´³ http:// à´\89പയàµ\8bà´\97à´¿à´\95àµ\8dà´\95àµ\81à´¨àµ\8dനതാണ്).',
'linksearch-line' => '$1, $2ൽ നിന്നു കണ്ണി ചേർക്കപ്പെട്ടിരിക്കുന്നു.',
'linksearch-error' => 'ഹോസ്റ്റ്നെയിമിന്റെ തുടക്കത്തിൽ മാത്രമേ വൈൽഡ് കാർഡുകൾ വരാവൂ.',
# Watchlist
'watchlist' => 'ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടിക',
-'mywatchlist' => 'à´\9eാൻ à´¶àµ\8dà´°à´¦àµ\8dധിà´\95àµ\8dà´\95àµ\81à´¨àµ\8dനവ',
+'mywatchlist' => 'ശ്രദ്ധിക്കുന്നവ',
'watchlistfor2' => 'ഉപയോക്താവ്:$1 $2',
'nowatchlist' => 'താങ്കൾ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിൽ ഇനങ്ങളൊന്നുമില്ല.',
'watchlistanontext' => 'താങ്കൾ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടിക കാണുവാനോ തിരുത്തുവാനോ $1.',
# Contributions
'contributions' => 'ഉപയോക്താവിന്റെ സംഭാവനകൾ',
'contributions-title' => '$1 എന്ന ഉപയോക്താവിന്റെ സംഭാവനകൾ',
-'mycontris' => 'à´\8eà´¨àµ\8dà´±àµ\86 à´¸à´\82à´à´¾à´µà´¨à´\95ൾ',
+'mycontris' => 'സംഭാവനകൾ',
'contribsub2' => '$1 എന്ന ഉപയോക്താവിന്റെ $2.',
'nocontribs' => 'ഈ മാനദണ്ഡങ്ങളുമായി യോജിക്കുന്ന മാറ്റങ്ങൾ ഒന്നും കണ്ടില്ല.',
'uctop' => '(അവസാനത്തെ തിരുത്തൽ)',
'whatlinkshere-hideredirs' => 'തിരിച്ചുവിടലുകൾ $1',
'whatlinkshere-hidetrans' => 'ഉൾപ്പെടുത്തലുകൾ $1',
'whatlinkshere-hidelinks' => 'കണ്ണികൾ $1',
-'whatlinkshere-hideimages' => 'à´\9aà´¿à´¤àµ\8dà´°à´\99àµ\8dà´\99ളിൽ നിനàµ\8dà´¨àµ\8d $1 à´\95à´£àµ\8dണിà´\95ൾ',
+'whatlinkshere-hideimages' => 'à´ªàµ\8dരമാണà´\99àµ\8dà´\99ളിൽ നിനàµ\8dà´¨àµ\81à´³àµ\8dà´³ à´\95à´£àµ\8dണിà´\95ൾ $1',
'whatlinkshere-filters' => 'അരിപ്പകൾ',
# Block/unblock
'newwindow' => '(dibuka di tetingkap baru)',
'cancel' => 'Batalkan',
'moredotdotdot' => 'Lagi...',
-'mypage' => 'Laman saya',
-'mytalk' => 'Perbualan saya',
+'mypage' => 'Halaman',
+'mytalk' => 'Perbualan',
'anontalk' => 'Perbualan bagi IP ini',
'navigation' => 'Pandu arah',
'and' => ' dan',
# Preferences page
'preferences' => 'Keutamaan',
-'mypreferences' => 'Keutamaan saya',
+'mypreferences' => 'Keutamaan',
'prefs-edits' => 'Jumlah suntingan:',
'prefsnologin' => 'Belum log masuk',
'prefsnologintext' => 'Anda hendaklah <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} log masuk]</span> terlebih dahulu untuk menetapkan keutamaan.',
'linksearch-ok' => 'Cari',
'linksearch-text' => 'Kad bebas seperti "*.wikipedia.org" dibenarkan.<br />
Memerlukan sekurang-kurangnya satu domain peringkat tinggi, cth. "*.org".<br />
-Protokol yang disokong: <code>$1</code> (jangan bubuh sebarang protokol ini dalam carian anda)',
+Protokol yang disokong: <code>$1</code> (menjadi http:// jika tiada protokol dinyatakan).',
'linksearch-line' => '$1 dipaut dari $2',
'linksearch-error' => 'Kad bebas hanya boleh digunakan pada permulaan nama hos.',
# Watchlist
'watchlist' => 'Senarai pantau',
-'mywatchlist' => 'Senarai pantau saya',
+'mywatchlist' => 'Senarai pantau',
'watchlistfor2' => 'Bagi $1 $2',
'nowatchlist' => 'Tiada item dalam senarai pantau anda.',
'watchlistanontext' => 'Sila $1 terlebih dahulu untuk melihat atau menyunting senarai pantau anda.',
# Contributions
'contributions' => 'Sumbangan pengguna',
'contributions-title' => 'Sumbangan oleh $1',
-'mycontris' => 'Sumbangan saya',
+'mycontris' => 'Sumbangan',
'contribsub2' => 'Oleh $1 ($2)',
'nocontribs' => 'Tiada sebarang perubahan yang sepadan dengan kriteria-kriteria ini.',
'uctop' => '(puncak)',
'whatlinkshere-hideredirs' => '$1 pelencongan',
'whatlinkshere-hidetrans' => '$1 penyertaan',
'whatlinkshere-hidelinks' => '$1 pautan',
-'whatlinkshere-hideimages' => '$1 pautan imej',
+'whatlinkshere-hideimages' => '$1 pautan fail',
'whatlinkshere-filters' => 'Penapis',
# Block/unblock
Timitztlātlauhtia xicchīhua occeppa.',
'wrongpasswordempty' => 'Ayāc motlahtōlichtacāyo.
Timitztlātlauhtia xicchīhua occeppa.',
-'mailmypassword' => 'E-mailīz yancuīc motlahtōlichtacāyo',
+'mailmypassword' => 'Notech moēhualtia maltzinteyōtl netitlaniztica yancuīc ichtacātlahtōlli',
'noemail' => '"$1" ahmo quipiya īe-mailcān.',
'passwordsent' => 'Ōmoihuah yancuīc motlahtōlichtacāyo īhuīc mo e-mail ("$1").
Occeppa xicalaqui niman ticmatīz.',
'defaultns' => 'Tlatēmōz inīn tōcātzimpan achtopa:',
'default' => 'ic default',
'prefs-files' => 'Tlahcuilōlli',
-'youremail' => 'E-mail:',
+'youremail' => 'Maltzinteyōtl netitlanizyeyāntli:',
'username' => 'Tlatequitiltilīltōcāitl:',
'uid' => 'Tlatequitiltilīlli ID:',
'prefs-memberingroups' => 'Tlācatl {{PLURAL:$1|olōlco|olōlco}}:',
'listgrouprights-rights' => 'Huelītiliztli',
# E-mail user
-'emailuser' => 'Tique-mailīz inīn tlatequitiltilīlli',
+'emailuser' => 'Tiquēhualtlīz maltzinteyōtl netitlaniztli inīn tlatequitiltilīlli',
'defemailsubject' => '{{SITENAME}} correo tlatequitiltilīlhuīc $1',
'emailfrom' => 'Īhuīcpa:',
'emailto' => 'Īhuīc:',
'whatlinkshere-links' => '← tzòwilistìn',
'whatlinkshere-hideredirs' => '$1 tlacuepaliztli',
'whatlinkshere-hidelinks' => '$1 tzòwilistìn',
-'whatlinkshere-hideimages' => '$1 ìxiptzòwilistli',
+'whatlinkshere-hideimages' => '$1 tlahcuilōltzonhuīliztli',
# Block/unblock
'blockip' => 'Tiquitzacuilīz tlatequitiltilīlli',
* @author Sjurhamre
* @author Stigmj
* @author Teak
+ * @author Wouterkoch
* @author לערי ריינהארט
*/
'underline-always' => 'Alltid',
'underline-never' => 'Aldri',
-'underline-default' => 'Bruk nettleserstandard',
+'underline-default' => 'Nettleserens standardinnstillinger',
# Font style option in Special:Preferences
'editfont-style' => 'Skrifttype i redigeringsboksen:',
'newwindow' => '(åpnes i et nytt vindu)',
'cancel' => 'Avbryt',
'moredotdotdot' => 'Mer …',
-'mypage' => 'Min side',
-'mytalk' => 'Min diskusjonsside',
+'mypage' => 'Egen brukerside',
+'mytalk' => 'Egen brukerdiskusjonsside',
'anontalk' => 'Brukerdiskusjon for denne IP-adressen',
'navigation' => 'Navigasjon',
'and' => ' og',
# Preferences page
'preferences' => 'Innstillinger',
-'mypreferences' => 'Innstillinger',
+'mypreferences' => 'Egne brukerinnstillinger',
'prefs-edits' => 'Antall redigeringer:',
'prefsnologin' => 'Ikke logget inn',
'prefsnologintext' => 'Du må være <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} logget inn]</span> for å endre brukerinnstillingene.',
'linksearch-pat' => 'Søkemønster:',
'linksearch-ns' => 'Navnerom:',
'linksearch-ok' => 'Søk',
-'linksearch-text' => 'Jokertegn som «*.wikipedia.org» kan brukes.
+'linksearch-text' => 'Jokertegn slik som i «*.wikipedia.org» kan brukes.
Det kreves at det oppgis minst et toppnivådomene, for eksempel «*.org».<br />
Støttede protokoller: <code>$1</code> (ikke legg til noen av disse i søket ditt).',
'linksearch-line' => '$1 lenkes fra $2',
# Watchlist
'watchlist' => 'Overvåkningsliste',
-'mywatchlist' => 'Overvåkningsliste',
+'mywatchlist' => 'Egen brukers overvåkningsliste',
'watchlistfor2' => 'For $1 $2',
'nowatchlist' => 'Du har ingenting i overvåkningslisten.',
'watchlistanontext' => 'Vennligst $1 for å vise eller redigere sider på overvåkningslisten din.',
# Contributions
'contributions' => 'Brukerbidrag',
'contributions-title' => 'Brukerbidrag av $1',
-'mycontris' => 'Mine bidrag',
+'mycontris' => 'Mine redigeringer',
'contribsub2' => 'For $1 ($2)',
'nocontribs' => 'Ingen endringer er funnet som passer disse kriteriene.',
'uctop' => '(siste)',
'underline-always' => 'Altijd',
'underline-never' => 'Nooit',
-'underline-default' => 'Webbrowser-standaard',
+'underline-default' => 'Standaard in uw vormgeving of webbrowser',
# Font style option in Special:Preferences
'editfont-style' => 'Lettertypestijl bewerkingsvenster:',
'newwindow' => '(opent in een nieuw venster)',
'cancel' => 'Annuleren',
'moredotdotdot' => 'Meer…',
-'mypage' => 'Mijn gebruikerspagina',
-'mytalk' => 'Mijn overleg',
+'mypage' => 'Gebruikerspagina',
+'mytalk' => 'Overleg',
'anontalk' => 'Overlegpagina voor dit IP-adres',
'navigation' => 'Navigatie',
'and' => ' en',
# Preferences page
'preferences' => 'Voorkeuren',
-'mypreferences' => 'Mijn voorkeuren',
+'mypreferences' => 'Voorkeuren',
'prefs-edits' => 'Aantal bewerkingen:',
'prefsnologin' => 'Niet aangemeld',
'prefsnologintext' => 'U moet <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} aangemeld]</span> zijn om uw voorkeuren te kunnen instellen.',
'rightslogtext' => 'Hieronder staan de wijzigingen in gebruikersrechten.',
'rightslogentry' => 'heeft de gebruikersrechten voor $1 gewijzigd van $2 naar $3',
'rightslogentry-autopromote' => 'is automatisch gepromoveerd van de groepen "$2" naar de groepen "$3"',
+'logentry-rights-rights' => '$1 heeft groepslidmaatschap voor $3 gewijzigd van $4 naar $5',
+'logentry-rights-rights-legacy' => '$1 heeft groepslidmaatschap voor $3 gewijzigd',
+'logentry-rights-autopromote' => '$1 is automatisch gepromoveerd van $4 naar $5',
'rightsnone' => '(geen)',
# Associated actions - in the sentence "You do not have permission to X"
'linksearch-ns' => 'Naamruimte:',
'linksearch-ok' => 'Zoeken',
'linksearch-text' => 'Wildcards zoals "*.wikipedia.org" of "*.org" zijn toegestaan.
-Heeft tenminste een topleveldomein, zoals bijvoorbeeld "*.org".<br />
-Ondersteunde protocollen: <code>$1</code> (voeg deze niet toe in uw zoekopdracht).',
+Heeft tenminste een topleveldomein nodig, zoals bijvoorbeeld "*.org".<br />
+Ondersteunde protocollen: <code>$1</code> (wordt "http://"als er geen protocol wordt opgegeven).',
'linksearch-line' => '$1 heeft een verwijzing in $2',
'linksearch-error' => 'Wildcards zijn alleen toegestaan aan het begin van een hostnaam.',
# Watchlist
'watchlist' => 'Volglijst',
-'mywatchlist' => 'Mijn volglijst',
+'mywatchlist' => 'Volglijst',
'watchlistfor2' => 'Voor $1 $2',
'nowatchlist' => 'Uw volglijst is leeg.',
'watchlistanontext' => 'Om uw volglijst te bekijken of te bewerken moet u zich $1.',
# Contributions
'contributions' => 'Gebruikersbijdragen',
'contributions-title' => 'Bijdragen van $1',
-'mycontris' => 'Mijn bijdragen',
+'mycontris' => 'Bijdragen',
'contribsub2' => 'Voor $1 ($2)',
'nocontribs' => 'Geen wijzigingen gevonden die aan de gestelde criteria voldoen.',
'uctop' => '(laatste wijziging)',
# Info page
'pageinfo-title' => 'Informatie over "$1"',
-'pageinfo-not-current' => 'Gegevens worden mogelijk alleen weergegeven voor de huidige versie.',
+'pageinfo-not-current' => 'Deze gegevens zijn alleen beschikbaar voor de huidige versie.',
'pageinfo-header-basic' => 'Basisgegevens',
'pageinfo-header-edits' => 'Bewerkingsgeschiedenis',
'pageinfo-header-restrictions' => 'Paginabeveiliging',
'duration-centuries' => '$1 {{PLURAL:$1|eeuw|eeuwen}}',
'duration-millennia' => '$1 {{PLURAL:$1|millennium|millennia}}',
+# Unknown messages
+'mytalk-parenthetical' => 'overleg',
);
'underline-always' => 'Alltid',
'underline-never' => 'Aldri',
-'underline-default' => 'Nettlesarstandard',
+'underline-default' => 'Drakt- eller nettlesarstandard',
# Font style option in Special:Preferences
'editfont-style' => 'Endre stilen for skrifttypen i området:',
'cancel' => 'Avbryt',
'moredotdotdot' => 'Meir …',
'mypage' => 'Sida mi',
-'mytalk' => 'Diskusjonssida mi',
+'mytalk' => 'Diskusjon',
'anontalk' => 'Diskusjonside for denne IP-adressa',
'navigation' => 'Navigering',
'and' => ' og',
Passordet for den nye kontoen kan verta endra på ''[[Special:ChangePassword|endra passord]]''-sida etter innlogging.",
'newarticle' => '(Ny)',
-'newarticletext' => "'''{{SITENAME}} har ikkje noka side med namnet {{PAGENAME}} enno.'''
-* For å opprette ei slik side kan du skrive i boksen under og klikke på «Lagre». Endringane vil vere synlege med det same.
-* Om du er ny her er det tilrådd å sjå på [[{{MediaWiki:Helppage}}|hjelpesida]] først.
-* Om du lagrar ei testside, vil du ikkje kunne slette henne sjølv.
-* Dersom du ikkje ønskjer å endre sida, kan du utan risiko klikke på '''attende'''-knappen i nettlesaren din.",
+'newarticletext' => "Du har følgt ei lenkje til ei side som ikkje finst enno.
+For å opprette sida, kan du skrive i boksen under (sjå [[{{MediaWiki:Helppage}}|hjelpesida]] for meir informasjon).
+Dersom du ikkje ønskjer å opprette sida, kan du utan risiko klikke på '''attende'''-knappen i nettlesaren din.",
'anontalkpagetext' => "----''Dette er ei diskusjonsside for ein anonym brukar som ikkje har oppretta konto eller ikkje har logga inn.
Vi er difor nøydde til å bruke den numeriske IP-adressa til å identifisere brukaren. Same IP-adresse kan vere knytt til fleire brukarar. Om du er ein anonym brukar og meiner at du har fått irrelevante kommentarar på ei slik side, [[Special:UserLogin/signup|opprett ein brukarkonto]] eller [[Special:UserLogin|logg inn]] slik at vi unngår framtidige forvekslingar med andre anonyme brukarar.''",
'noarticletext' => 'Det er nett no ikkje noko tekst på denne sida.
# Preferences page
'preferences' => 'Innstillingar',
-'mypreferences' => 'Innstillingane mine',
+'mypreferences' => 'Innstillingar',
'prefs-edits' => 'Tal på endringar:',
'prefsnologin' => 'Ikkje innlogga',
'prefsnologintext' => 'Du må vere <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} logga inn]</span> for å endre brukarinnstillingane.',
'rightslogtext' => 'Dette er ein logg over endringar av brukartilgang.',
'rightslogentry' => 'endra brukartilgangen til $1 frå $2 til $3',
'rightslogentry-autopromote' => '↓vart automatisk forfremja frå $2 til $3',
+'logentry-rights-rights' => '$1 endra gruppemedlemskap for $3 frå $4 til $5',
+'logentry-rights-rights-legacy' => '$1 endra gruppemedlemskap for $3',
+'logentry-rights-autopromote' => '$1 vart automatisk forfremja frå $4 til $5',
'rightsnone' => '(ingen)',
# Associated actions - in the sentence "You do not have permission to X"
'linksearch-ok' => 'Søk',
'linksearch-text' => 'Jokerteikn som «*.wikipedia.org» kan nyttast.
Det er påkravt med eit toppnivådomene, til dømes «*.org».<br />
-Støtta protokollar: <code>$1</code> (ikkje legg til nokon av desse i søket ditt)',
+Støtta protokollar: <code>$1</code> (nyttar http:// som standard om ingen protokoll er oppgjeven)',
'linksearch-line' => '$2 lenkjer til $1',
'linksearch-error' => 'Jokerteikn kan berre nyttast føre tenarnamnet.',
# Watchlist
'watchlist' => 'Overvakingsliste',
-'mywatchlist' => 'Overvakingslista mi',
+'mywatchlist' => 'Overvakingsliste',
'watchlistfor2' => 'For $1 $2',
'nowatchlist' => 'Du har ikkje noko i overvakingslista di.',
'watchlistanontext' => 'Du lyt $1 for å vise eller endre sider på overvakingslista di.',
# Contributions
'contributions' => 'Brukarbidrag',
'contributions-title' => 'Bidrag av $1',
-'mycontris' => 'Eigne bidrag',
+'mycontris' => 'Bidrag',
'contribsub2' => 'For $1 ($2)',
'nocontribs' => 'Det vart ikkje funne nokon endringar gjorde av denne brukaren.',
'uctop' => ' (øvst)',
'delete_and_move' => 'Slett og flytt',
'delete_and_move_text' => '== Sletting påkravd ==
-Målsida «[[:$1]]» finst alt. Vil du sletta henne for å gjeva rom for flytting?',
+Målsida «[[:$1]]» finst allereie. Vil du slette ho for å gje rom for flytting?',
'delete_and_move_confirm' => 'Ja, slett sida',
'delete_and_move_reason' => 'Sletta for å gje rom for flytting frå «[[$1]]»',
'selfmove' => 'Kjelde- og måltitlane er like; kan ikkje flytte sida over seg sjølv.',
# Info page
'pageinfo-title' => 'Informasjon om «$1»',
-'pageinfo-not-current' => 'Informasjon vert berre vist for den gjeldande versjonen.',
+'pageinfo-not-current' => 'Orsak, det er umogeleg å gjeva denne informasjonen for gamle versjonar.',
'pageinfo-header-basic' => 'Grunnleggjande informasjon',
'pageinfo-header-edits' => 'Endringshistorikk',
'pageinfo-header-restrictions' => 'Sidevern',
'exif-ycbcrpositioning-2' => 'Samanfallande',
'exif-dc-contributor' => 'Bidragsytarar',
+'exif-dc-coverage' => 'Rom- eller tidssutstrekning til medium',
'exif-dc-date' => 'Dato(ar)',
'exif-dc-publisher' => 'Utgjevar',
'exif-dc-relation' => 'Skylde medium',
'version-hook-subscribedby' => 'Brukt av',
'version-version' => '(versjon $1)',
'version-license' => 'Lisens',
-'version-poweredby-credits' => "Denne wikien er dreven av '''[//www.mediawiki.org/ MediaWiki]''', copyright © 2001-$1 $2.",
+'version-poweredby-credits' => "Denne wikien er driven av '''[//www.mediawiki.org/ MediaWiki]''', copyright © 2001-$1 $2.",
'version-poweredby-others' => 'andre',
'version-credits-summary' => 'Me ynskjer godskriva desse personane for tilskotet deira til [[Special:Version|MediaWiki]].',
+'version-license-info' => 'MediaWiki er fri programvare; du kan redistribuera det og/eller modifisera det under krava i GNU General Public License som publisert av Free Software Foundation; anten versjon 2 av lisensen, eller (om du ynskjer det) ein kvar seinare versjon.
+
+MediaWiki er distribuert i håp om at det vil vera nyttig, men UTAN NOKON GARANTI; ikkje eingong ein implisitt garanti for at det KAN SELJAST eller at det EIGNAR SEG TIL EIT VISST FØREMÅL. Sjå GNU General Public License for fleire detaljar.
+
+Du skal ha motteke [{{SERVER}}{{SCRIPTPATH}}/COPYING ein kopi av GNU General Public License] saman med dette programmet; om ikkje, skriv til Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA eller [//www.gnu.org/licenses/old-licenses/gpl-2.0.html les det på nettet].',
'version-software' => 'Installert programvare',
'version-software-product' => 'Produkt',
'version-software-version' => 'Versjon',
'duration-centuries' => '$1 {{PLURAL:$1|hundreår|hundreår}}',
'duration-millennia' => '$1 {{PLURAL:$1|tusenår|tusenår}}',
+# Unknown messages
+'mytalk-parenthetical' => 'diskusjon',
);
'whatlinkshere-hideredirs' => '$1 କୁ ଲେଉଟାଣି',
'whatlinkshere-hidetrans' => '$1 ଆଧାର ସହ ଭିତରେ ରଖିବା',
'whatlinkshere-hidelinks' => '$1 ଟି ଲିଙ୍କ',
-'whatlinkshere-hideimages' => '$1 à¬\9bବିର ଲିଙ୍କସବୁ',
+'whatlinkshere-hideimages' => '$1 ଫାà¬\87ଲର ଲିଙ୍କସବୁ',
'whatlinkshere-filters' => 'ଛଣା',
# Block/unblock
'category-file-count' => "{{PLURAL:$2|Chol catégorie o seulemint chol fichié-lo.|{{PLURAL:$1|Ech fichier-lo est|$1 Chés fichiés-lo sont}} din l'catégorie-lo, pou un total éd $2 fichiés.}}",
'category-file-count-limited' => "{{PLURAL:$1|Ech fichié d'apré est|Chés $1 fichiés d'apré sont}} dins l'catégorie-lo.",
'listingcontinuesabbrev' => 'cont.',
+'noindex-category' => 'Paches nin indécsées',
'broken-file-category' => "Paches aveuc des loïens d'fichiés bérzillés",
'about' => 'À pérpos',
'newwindow' => '(ouvrir din eune nouvèle fernéte)',
'cancel' => 'Canchler',
'moredotdotdot' => 'Plu...',
-'mypage' => 'Em pache',
+'mypage' => 'Pache',
'mytalk' => 'Min bavouér',
'anontalk' => "Bavouér pou chl'IP-lo",
'navigation' => 'Navigachon',
'createaccount' => 'Créer un conpte',
'gotaccount' => "Jou qu'os avez piécha un conpte? '''$1'''.",
'gotaccountlink' => 'Intrer',
+'userlogin-resetlink' => "Vos avez oblié vous détals d'connécsion ?",
'createaccountmail' => 'par imèle',
'badretype' => "Chés mots d'passe intrés, is sont poin bon.",
'userexists' => "Nom d’utilisateur entré déjà utilisé.
Os povez [[Special:Search/{{PAGENAME}}|foaire eune érchérche du tite del pache]] din chés eutes paches,
<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} érchércher din chés érliées opéracions]
ou [{{fullurl:{{FULLPAGENAME}}|action=edit}} créer chol pache]</span>.',
+'noarticletext-nopermission' => "Achteure i n’y o autchun teske dseur l'pache-lo.
+Os povez [[Special:Search/{{PAGENAME}}|foaire eune érchérche du tite del pache]] din chés eutes paches,
+o bin <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} érchércher din chés érliées gazètes]</span>
+mais vos n'avez poin l'droué d'créer chol pache.",
'previewnote' => "'''Afute! ch'teske-lo ch'est seulemint eune prévue.'''
Vos cangemints, is sont poin coèr inrégistrés!",
'template-semiprotected' => '(semi-garanti)',
'hiddencategories' => '{{PLURAL:$1|Catégorie muchée|Catégories muchées}} pou chol pache:',
'permissionserrorstext-withaction' => "Vos n’avez poin l'pérmichon éd $2, pou {{PLURAL:$1|ch'motif suivant|chés motifs suivants}}:",
+'recreate-moveddeleted-warn' => "'''Afute ! : Os ètes in route à ércréer eune pache qu'o té abolie édvant.'''
+
+Controler qu'ch'est pértinint d' porsuire chés modificacions édseur chol pache. L'jornal des défacions pi des déplachemints l'est affiké chi-édsous :",
+'moveddeleted-notice' => "Chol pache ale o té abolie. L'jornal des défacions pi des déplachemints il est affiké chi-édsous pour référinche.",
# Parser/template warnings
'post-expand-template-inclusion-warning' => "Affute : Chèle pache ale a trop d’modèles. Des inclusions n'sront poin foaites.",
'post-expand-template-inclusion-category' => "Paches aveuc granmint d'modèles",
+'post-expand-template-argument-warning' => "Afute : Chol pache ale o au moins un paramète d'modèle dont l'inclusion est rindue impossibe. Apré éstinsion, chti-chi il éroait produit un résultat trop long, i n'a donc poin té inclus.",
+'post-expand-template-argument-category' => "Paches aveuc des paramètes d'modèle mie évalués",
# History pages
'viewpagelogs' => 'Vir chés gasètes del pache-lo',
'histlegend' => "Diff séléccion: buke chés boétes d'chés canjemints à comparète pi détriquer intrer ou ch'bouton édsou.<br />
Léginde : ({{MediaWiki:Cur}}) = différinches aveuc el vérchon à ch'momint-chi, ({{MediaWiki:Last}}) = différinches aveuc el vérchon édvant, <b>m</b> = tiot canjemint.",
'history-fieldset-title' => "S'déplacher din l'historique",
+'history-show-deleted' => 'Défacés seulemint',
'histfirst' => 'preumières paches',
'histlast' => 'Darin',
+# Revision feed
+'history-feed-item-nocomment' => '$1 à $2',
+
# Revision deletion
'rev-delundel' => 'montrer/mucher',
'revdel-restore' => 'cange écmint vir',
'revertmerge' => "N'poin mélinger",
# Diffs
-'history-title' => 'Histoère des cangemints éd "$1"',
+'history-title' => 'Historike des canjemints éd "$1"',
'lineno' => 'Line $1:',
'compareselectedversions' => 'Compérer chés couésies contérbuchons',
'editundo' => "n'poin foaire",
+'diff-multi' => '({{PLURAL:$1|Un canjemint intarmédiaire|$1 canjemints intarmédiaires}} par {{PLURAL:$2|un uzeu|$2 uzeus}} {{PLURAL:$1|est muché|sont muchées}})',
# Search results
'searchresults' => 'Tracher chés résultats',
'prevn' => 'dvant {{PLURAL:$1|$1}}',
'nextn' => 'apreu {{PLURAL:$1|$1}}',
'prevn-title' => 'Dvant $1 {{PLURAL:$1|résultat|résultats}}',
+'nextn-title' => "$1 {{PLURAL:$1|résultat d'apré|résultats d'apré}}",
+'shown-title' => 'Montrer $1 résultat{{PLURAL:$1||s}} pèr pache',
'viewprevnext' => 'Vir ($1 {{int:pipe-separator}} $2) ($3)',
+'searchmenu-exists' => "'''Il y o eune pache lonmée « [[:$1]] » édseur ch'wiki'''",
'searchmenu-new' => "'''Créer l'pache « [[:$1|$1]] » édseur ech wiki !'''",
'searchprofile-articles' => "Paches d'étnu",
'searchprofile-project' => "Paches d’aïude et pi d'prodjé",
'searchprofile-everything-tooltip' => "Tracher dins tout ch'wikipédia (et ochi dins chés paches éd distchucion)",
'searchprofile-advanced-tooltip' => "Couésir chés éspaches d'noms pour l'értrache",
'search-result-size' => '$1 ({{PLURAL:$2|1 mot|$2 mots}})',
+'search-result-category-size' => '$1 mimbe{{PLURAL:$1||s}} ($2 édsous-catégorie{{PLURAL:$2||s}}, $3 fichié{{PLURAL:$3||s}})',
'search-redirect' => '(érdirection $1)',
'search-section' => '(sekchon $1)',
'search-suggest' => 'Cha vo ti dire: $1',
'search-interwiki-caption' => 'Proujé analocq',
'search-interwiki-default' => '$1 résultats:',
'search-interwiki-more' => '(pus)',
+'searchrelated' => 'relaté',
'searchall' => 'tout',
+'showingresultsheader' => "{{PLURAL:$5|Résultat '''$1'''|Résultats '''$1–$2'''}} éd '''$3''' pour '''$4'''",
'nonefound' => "'''Note''': il y o tasseulemint quéques éspaces éd noms éq sont trachés pèr défeut. <br /> Pou tracher din tous chés contnus (paches éd pérlache, modéles, etc... comprins) insséyer in imploéyant ch'préfixe ''all:'' o bin imploéyer echl éspace éd noms édmindé conme préfixe.",
'search-nonefound' => 'Y a autchun résultat pour chol dmanne.',
'powersearch' => 'Érvue avanchée',
'gender-male' => 'Marle',
'gender-female' => 'Femelle',
'email' => 'Imèle',
+'prefs-help-email' => "L’adrèche du courrièl est facultative, mais ale est nécessaire pour artreuver vote mot d'passe, si vos vnoète à l’oblier.",
+'prefs-help-email-others' => "Os pouvez auchi couésir d'laicher les eutes vos contacter par imèle aveuc un loïen édseur vote pache éd distchussion d'uzeu sans qu'i soèche nécessaire ed révéler vote idintité.",
'prefs-help-email-required' => 'I feut eune iméle adérche',
# User rights
'recentchanges' => 'Darins canjemints',
'recentchanges-legend' => 'Opchons éd chés nouvieus canjemints',
'recentchanges-feed-description' => 'Tracher chés pus darins cangemints du wiki din chol alimintachon.',
+'recentchanges-label-newpage' => 'Chol modificacion ale o créé eune nouvèle pache',
+'recentchanges-label-minor' => "C'est un tiot canjemint",
+'recentchanges-label-bot' => 'Chol modificacion ale o té foaite pèr un robot.',
+'recentchanges-label-unpatrolled' => 'Chol modificacion ale n’o poin coèr té controlée.',
'rcnote' => "Vlo {{PLURAL:$1|ech darin canjemint foait|chés $1 darins canjemints foaits}} din {{PLURAL:$2|l'darinne jornèe|chés <b>$2</b> darins jours}} dusque l' $4 à $5.",
+'rcnotefrom' => "Vlo chés modificacions foaites édpuis l' '''$2''' (dousqu'à '''$1''' au plus).",
'rclistfrom' => "Montrer chés nouvieus cangemints d'puis $1",
'rcshowhideminor' => '$1 tiotes éditions',
'rcshowhidebots' => '$1 bots',
'rcshowhideliu' => '$1 lodjés uzeus',
'rcshowhideanons' => '$1 uzeus anonimes',
+'rcshowhidepatr' => '$1 chés modificacions wardées',
'rcshowhidemine' => '$1 ems éditions',
'rclinks' => 'Afiqher chés $1 darins canjemints din chés $2 darins jours<br />$3',
'diff' => 'dif',
# Recent changes linked
'recentchangeslinked' => 'Darins canjemints érliés',
+'recentchangeslinked-toolbox' => 'Suivi des paches loïées',
'recentchangeslinked-title' => 'Cangemints à pérpos éd "$1"',
+'recentchangeslinked-noresult' => "I n’y a poin d' modificacion des paches loïées pindant l'période couésie.",
'recentchangeslinked-summary' => "Ch'est eune lisse d'chés darins canjemints su chés paches qu'ont un loïen aveuc l'pache-lo. Chés paches din vote [[Special:Watchlist|''lisse à suire'']] il sont in '''cros'''.",
'recentchangeslinked-page' => 'Nom del pache:',
'recentchangeslinked-to' => "Vir putot chés canjemints d'chés paches aveuc un loïen su l'pache-lo",
# Upload
'upload' => 'Quértcher chés fichiés',
'uploadlogpage' => 'Jornal éd chés quértchémints',
+'filedesc' => 'Résumè',
'uploadedimage' => '"[[$1]]" quértchée',
+'license' => 'Licince',
+'license-header' => 'Licince',
+
# File description page
'file-anchor-link' => 'Fichié',
'filehist' => 'Histoère dech fichié',
'filehist-comment' => 'Fichié éd chés conmints',
'imagelinks' => 'Usage dech fichié',
'linkstoimage' => "{{PLURAL:$1|L'pache d'apreu est liée|Chés $1 paches d'apreu sont liées}} à ch'fichié-lo :",
+'nolinkstoimage' => "Autchune pache n'est loïée aveuc ch'fichié-lo",
'sharedupload' => "Cht'fichié vient éd $1 pi i put ète imploïé par d'eutes proujés.",
'sharedupload-desc-here' => "Ch'fichié i vient éd $1. I put ète uzer pèr d’eutes prodjés.
Vir apré ([$2 pache]).",
# Statistics
'statistics' => 'Éstatistikes',
+'disambiguationspage' => 'Template:Omonymie',
+
# Miscellaneous special pages
'nbytes' => '$1 {{PLURAL:$1|octé|octés}}',
'nmembers' => '$1 {{PLURAL:$1|mimbe|mimbes}}',
'allpagessubmit' => 'Aler',
'allpagesprefix' => "Foaire vir chés paches aveuc ch'préfix:",
+# Special:Categories
+'categories' => 'Lisse des catégories',
+
# Special:LinkSearch
'linksearch' => 'Loïens éstérieurs',
+'linksearch-line' => '$1 est loïé édpuis $2',
# Special:Log/newusers
'newuserlogpage' => "Jornal éd chés créachons d'comptes d'uzeu",
'deletepage' => "Défacer l'pache",
'confirmdeletetext' => "Vos alez défacer eune pache ou un fichié aveuc toutes chés antieusses vérchons.<br /> Confreumer éq ch'est cho éq vos voulez foaire, éq vos conprindez chés consécanches et pi éq ch'est bin s'lon el [[{{MediaWiki:Policy-url}}|politique éd MédiaWiki]].",
'actioncomplete' => 'Plònne acchon',
+'actionfailed' => "L’action n'a poin réussi",
'deletedtext' => "« $1 » o té défacé.
Vir $2 pou eune lisse d'chés darinnes défachons.",
'dellogpage' => 'jornal éd chés défacions',
'sp-contributions-newbies' => 'Montrer chés contérbuchons éd chés nouvieus conptes seulemint',
'sp-contributions-blocklog' => 'jornal éd chés blotcåjhes',
+'sp-contributions-uploads' => "téléquértch'mints",
'sp-contributions-logs' => 'Gasètes',
'sp-contributions-talk' => 'Dviser',
'sp-contributions-search' => 'Tracher pou chés contérbuchons',
'nolinkshere-ns' => "i n'y o poin d'pache aveuc un loïen vers '''[[:$1]]''' dins echl'éspace d'noms coési.",
'isredirect' => 'pache érdirigée',
'istemplate' => 'transclusion',
-'isimage' => "Loïen aveuc l'imache",
+'isimage' => "Loïen aveuc l'fichié",
'whatlinkshere-prev' => '{{PLURAL:$1|édvant|édvants $1}}',
'whatlinkshere-next' => "{{PLURAL:$1|d'apreu|d'apreu $1}}",
'whatlinkshere-links' => '← loïens',
# Namespace 8 related
'allmessagesname' => 'Nom',
+'allmessagesdefault' => 'Messache pèr défeut',
# Thumbnails
'thumbnail-more' => 'Pu grand',
+'thumbnail_error' => "Bérlurage tandir l'créachon éd la miniature : $1",
# Tooltip help for the actions
'tooltip-pt-userpage' => 'Vote pache éd uzeu',
'watchlisttools-edit' => "Vir pi éditer l'lisse à suire",
'watchlisttools-raw' => 'Éditer eune brute lisse à suire',
+# Core parser functions
+'duplicate-defaultsort' => "Afute : él cleu d'tri pèr défeut « $2 » écrase l'précédinte « $1 ».",
+
# Special:Version
'version-specialpages' => 'Paches éspéchiales',
# Special:BlankPage
'blankpage' => 'Blanke pache',
+# External image whitelist
+'external_image_whitelist' => " #Laicher chol line egzactemint telle quelle.<pre>
+#Dire chés bérlukes d’éspressions rationnelles (juste l'partie désignée inte chés //) chi-édsous.
+#I correspondront aveuc chés URL des images éstérnes.
+#Chelles qui corresponde'te s’affikeront conme des images, sinon seul un loïen vers l’image i s'ra affiké.
+#Les lines conmençant par un # s'ront considérées conme des conmintaires.
+#Chol lisse n’est mie sensibe à la casse.
+
+#Mettez tous chés bérlukes d’éspressions rationnelles au-d'sus éd chol line. Laichez chol darin.ne line telle quelle.</pre>",
+
+# Special:Tags
+'tag-filter' => 'Filtrer chés [[Special:Tags|balises]] :',
+
# Special:ComparePages
'compare-page1' => 'Pache 1',
'compare-page2' => 'Pache 2',
'cancel' => 'Zerick',
'moredotdotdot' => 'Mehner…',
'mypage' => 'Mei Blatt',
-'mytalk' => 'Mei Gschwetz-Blatt',
+'mytalk' => 'Mei Dischbedutt',
'anontalk' => 'Gschwetz-Blatt fer die IP',
'navigation' => 'Faahre-Gnepp',
'and' => ' unn',
'protectthispage' => 'Des Blatt schitze',
'newpage' => 'Neies Blatt',
'talkpage' => 'Sell Blatt dischbediere',
-'talkpagelinktext' => 'Gschwetz',
+'talkpagelinktext' => 'Dischbedutt',
'specialpage' => 'Besunneres Blatt',
'personaltools' => 'Paerseenlich Gscharr',
'articlepage' => 'Inhalt vun dem Blatt aagucke',
# Preferences page
'preferences' => 'Paerseenlich Profil',
-'mypreferences' => 'Mei Uffschtelling',
+'mypreferences' => 'Uffschtellinge',
'changepassword' => 'Paesswatt ennere',
'skin-preview' => 'Aagucke',
'prefs-personal' => 'Yuuser Profile',
# Watchlist
'watchlist' => 'Mei Watsch-Lischt',
-'mywatchlist' => 'Mei Watsch-Lischt',
+'mywatchlist' => 'Watsch-Lischt',
'watchlistfor2' => 'Vun $1 $2',
'watch' => 'watsche',
'watchthispage' => 'watsch des Blatt',
'month' => 'unn Munet:',
'year' => 'bis Yaahr:',
-'sp-contributions-talk' => 'Gschwetz',
+'sp-contributions-talk' => 'Dischbedutt',
'sp-contributions-search' => 'Guck fer Ardickel',
'sp-contributions-username' => 'IP-Adress odder Yuusernaame:',
'sp-contributions-submit' => 'Guck uff',
'newwindow' => '(otwiera się w nowym oknie)',
'cancel' => 'Anuluj',
'moredotdotdot' => 'Więcej...',
-'mypage' => 'Moja strona',
-'mytalk' => 'Moja dyskusja',
+'mypage' => 'Strona',
+'mytalk' => 'Dyskusja',
'anontalk' => 'Dyskusja tego IP',
'navigation' => 'Nawigacja',
'and' => ' oraz',
'newwindow' => '(as deurb ant na fnestra neuva)',
'cancel' => 'Scancela',
'moredotdotdot' => 'Dë pì...',
-'mypage' => 'Mia pàgina',
-'mytalk' => 'Mie ciaciarade',
+'mypage' => 'Pàgina',
+'mytalk' => 'Ciaciarade',
'anontalk' => "Ciaciarade për st'adrëssa IP-sì",
'navigation' => 'Navigassion',
'and' => ' e',
# Preferences page
'preferences' => 'Mè gust',
-'mypreferences' => 'mè gust',
+'mypreferences' => 'Gust',
'prefs-edits' => 'Nùmer ëd modìfiche fàite:',
'prefsnologin' => "A l'é ancó pa rintrà ant ël sistema",
'prefsnologintext' => 'A deuv esse <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} intrà ant ël sistema]</span> për amposté ij sò gust.',
'linksearch-ok' => 'Sërché',
'linksearch-text' => 'As peulo dovresse dij ciapatut com "*.wikipedia.org".
A-i é dabzògn almanch d\'un domini a livel pi àut, për esempi "*.org".<br />
-Protocòj ch\'as peulo dovresse: <code>$1</code> (ch\'a gionta gnun ëd costi an soa arserca).',
+Protocòj ch\'as peulo dovresse: <code>$1</code> (predefinì http:// se gnun protocòj a son specificà).',
'linksearch-line' => "$1 a l'ha n'anliura ch'a-j riva dzora da $2",
'linksearch-error' => 'Ij ciapatut as peulo butesse mach an prinsipi dël nòm dël sërvent.',
# Watchlist
'watchlist' => 'Ròba che im ten-o sot-euj',
-'mywatchlist' => 'Ròba che im ten-o sot-euj',
+'mywatchlist' => 'Ròba che as ten sot euj',
'watchlistfor2' => 'Për $1 $2',
'nowatchlist' => "A l'ha ancó pa marcà dj'artìcoj coma ròba da tnì sot-euj.",
'watchlistanontext' => "Për piasì, $1 për ës-ciairé ò pura modifiché j'element ëd soa lista dla ròba che as ten sot-euj.",
# Contributions
'contributions' => "Contribussion dë st'Utent-sì",
'contributions-title' => 'Contribussion ëd $1',
-'mycontris' => 'Mie contribussion',
+'mycontris' => 'Contribussion',
'contribsub2' => 'Për $1 ($2)',
'nocontribs' => "A l'é pa trovasse gnun-a modìfica che a fussa conforma a costi criteri-sì",
'uctop' => ' (ùltima dla pàgina)',
'whatlinkshere-hideredirs' => '$1 le ridiression',
'whatlinkshere-hidetrans' => '$1 anclusion',
'whatlinkshere-hidelinks' => '$1 anliura',
-'whatlinkshere-hideimages' => '$1 anliure ëd figure',
+'whatlinkshere-hideimages' => "$1 j'archivi lijà",
'whatlinkshere-filters' => 'Filtr',
# Block/unblock
# External editor support
'edit-externally' => "Modifiché st'archivi con un programa estern",
-'edit-externally-help' => "(Lese [//www.mediawiki.org/wiki/Manual:External_editors setup j'anstrussion d'anstalassion] për avèj pì d'anformassion)",
+'edit-externally-help' => "(Lese [//www.mediawiki.org/wiki/Manual:External_editors j'anstrussion d'anstalassion] për avèj pì d'anformassion)",
# 'all' in various places, this might be different for inflected languages
'watchlistall2' => 'tute',
# E-mail address confirmation
'confirmemail' => "Confermé l'adrëssa postal",
'confirmemail_noemail' => "A l'ha pa butà gnun-a adrëssa vàlida ëd pòsta eletrònica ant ij [[Special:Preferences|sò gust]].",
-'confirmemail_text' => "Costa wiki a ciama che chiel a convalida n'adrëssa postal anans che
-dovré lòn che toca la pòsta. Che a sgnaca ël boton ambelessì sota
-për fesse mandé un messa ëd conferma a soa adrëssa eletrònica.
-Andrinta al messagi a-i sara n'anliura (URL) con andrinta un còdes.
-Che a deurba st'anliura andrinta a sò programa ëd navigassion (browser)
+'confirmemail_text' => "Costa wiki a ciama che chiel a convàlida n'adrëssa ëd pòsta eletrònica anans che
+dovré lòn che a toca la pòsta. Che a sgnaca ël boton ambelessì-sota
+për fesse mandé un mëssage ëd conferma a soa adrëssa eletrònica.
+Andrinta al messagi a-i sara n'anliura con andrinta un còdes.
+Che a deurba st'anliura andrinta a sò programa ëd navigassion
për confermé che soa adrëssa a l'é pròpe cola.",
'confirmemail_pending' => "I l'oma già mandaje sò còdes ëd conferma;
-se a l'ha pen-a creasse sò cont, miraco a venta che a speta dontre minute che a-j riva ant la pòsta, nopà che ciamene un neuv.",
-'confirmemail_send' => 'Manda un còdes ëd conferma për pòsta eletrònica',
-'confirmemail_sent' => "Ël messagi ëd conferma a l'é stait mandà.",
-'confirmemail_oncreate' => "Un còdes ëd conferma a l'é stait mandà a soa adrëssa ëd pòsta eletrònica.
-D'ës còdes a fa pa dë manca për rintré ant ël sistema, ma a ventrà che a lo mostra al sistema për podej abilité cole funsion dla wiki che a son basà ant sla pòsta eletrònica.",
-'confirmemail_sendfailed' => "{{SITENAME}} a l'ha pa podù mandete l'e-mail ëd conferma.
+se a l'ha pen-a creasse sò cont, miraco a venta che a speta dontré minute che a-j riva ant la pòsta, nopà che ciamene un neuv.",
+'confirmemail_send' => 'Mandé un còdes ëd conferma për pòsta eletrònica',
+'confirmemail_sent' => "Ël mëssagi ëd conferma a l'é stàit mandà.",
+'confirmemail_oncreate' => "Un còdes ëd conferma a l'é stàit mandà a soa adrëssa ëd pòsta eletrònica.
+D'ës còdes a fa pa dë manca për rintré ant ël sistema, ma a ventrà che a lo mostra al sistema për podèj abilité cole funsion dla wiki che a son basà ant sla pòsta eletrònica.",
+'confirmemail_sendfailed' => "{{SITENAME}} a l'ha pa podù mandeje ël mëssagi ëd conferma.
Che a controla l'adrëssa che a l'ha dane, mai che a-i fusso dij caràter nen vàlid.
-Ël programa ëd pòsta a l'ha arspondù: $1",
+Ël programa ëd pòsta a l'ha rëspondù: $1",
'confirmemail_invalid' => 'Còdes ëd conferma nen vàlid. A podrìa ëdcò mach esse scadù.',
-'confirmemail_needlogin' => 'A venta che a fasa $1 për confermé soa addrëssa postal eletrònica.',
-'confirmemail_success' => "Soa adrëssa postal a l'é staita confermà, adess a peul rintré ant ël sistema e i-j auguroma da fessla bin ant la wiki!",
+'confirmemail_needlogin' => 'A venta $1 për confermé soa adrëssa ëd pòsta eletrònica.',
+'confirmemail_success' => "Soa adrëssa a l'é stàita confermà, adess a peul [[Special:UserLogin|rintré ant ël sistema]] e i-j auguroma da fessla bin ant la wiki!",
'confirmemail_loggedin' => "Motobin mersì. Soa adrëssa ëd pòsta eletrònica adess a l'é confermà.",
-'confirmemail_error' => "Cheich-còs a l'é andà mal ën salvand soa conferma.",
+'confirmemail_error' => "Cheicòs a l'é andà mal ën salvand soa conferma.",
'confirmemail_subject' => "Conferma dl'adrëssa postal da 'nt la {{SITENAME}}",
-'confirmemail_body' => "Cheidun, a l'é belfé che a sia stait pròpe chiel (ò chila), da 'nt l'adrëssa IP \$1,
-a l'ha doertà un cont utent \"\$2\" ansima a {{SITENAME}}, lassand-ne st'adrëssa ëd pòsta eletrònica-sì.
+'confirmemail_body' => "Cheidun, a l'é belfé che a sia stàit pròpe chiel, da 'nt l'adrëssa IP $1,
+a l'ha duvertà un cont utent «$2» ansima a {{SITENAME}}, lassand-ne st'adrëssa ëd pòsta eletrònica-sì.
Për confermé che ës cont a l'é da bon sò e për ativé
-le possibilità corelà a la pòsta eletrònica ansima a {{SITENAME}}, che a deurba st'adrëssa-sì andrinta a sò programa ëd navigassion (browser):
+le possibilità gropà a la pòsta eletrònica ansima a {{SITENAME}}, che a deurba st'adrëssa-sì andrinta a sò programa ëd navigassion:
-\$3
+$3
-Se a fussa *nen* stait chiel a deurbe ël cont, anlora che a vada daré a sto colegament-sì
-për scanselé la conferma ëd l'adrëssa e-mail:
+Se a fussa *nen* stàit chiel a deurbe ël cont, anlora che a vada dapress a la liura sì-sota
+për scancelé la conferma ëd l'adrëssa ëd pòsta eletrònica:
-\$5
+$5
-Cost còdes ëd conferma a l'é bon fin-a al \$4.",
-'confirmemail_body_changed' => "Cheidun, a l'é belfé ch'a sia chiel, da l'adrëssa IP \$1,
-a l'ha cangià l'adrëssa ëd pòsta eletrònica dël cont \"\$2\" con st'adrëssa-sì dzora a {{SITENAME}}.
+Cost còdes ëd conferma a l'é bon fin-a al $4.",
+'confirmemail_body_changed' => "Cheidun, a l'é belfé ch'a sia chiel, da l'adrëssa IP $1,
+a l'ha cangià l'adrëssa ëd pòsta eletrònica dël cont «$2» con st'adrëssa-sì dzora a {{SITENAME}}.
Për confirmé che sto cont-sì a l'é pròpi sò e për riativé
-le possibilità ëd pòsta eletrònica dzora a {{SITENAME}}, ch'a deurba sto colegament-sì an sò navigador:
+le fonsion ëd pòsta eletrònica dzora a {{SITENAME}}, ch'a deurba costa liura-sì an sò navigador:
-\$3
+$3
-Se ël cont a l'é *nen* sò, ch'a vada andré a sto colegament-sì
+Se ël cont a l'é *nen* sò, ch'a-i vada dapress a costa liura-sì
për scancelé la conferma dl'adrëssa ëd pòsta eletrònica:
-\$5
+$5
-Ës còdes ëd conferma a scadrà a \$4.",
-'confirmemail_body_set' => "Quaidun, miraco chiel, da l'adrëssa IP \$1,
-a l'ha ampostà l'adrëssa ëd pòsta eletrònica dël cont \"\$2\" con costa adrëssa su {{SITENAME}}.
+Ës còdes ëd conferma a scadrà ël $4.",
+'confirmemail_body_set' => "Quaidun, miraco chiel, da l'adrëssa IP $1,
+a l'ha ampostà l'adrëssa ëd pòsta eletrònica dël cont «$2» con costa adrëssa su {{SITENAME}}.
Për confirmé che sto cont a l'é pròpi sò e ativé torna
le funsion ëd pòsta eletrònica su {{SITENAME}}, ch'a duverta cost'anliura an sò navigador:
-\$3
+$3
Se ël cont a l'é *pa* sò, ch'a-j vada dapress a st'anliura
për scancelé la conferma ëd l'adrëssa ëd pòsta eletrònica:
-\$5
+$5
-Cost còdes ëd conferma a scad ai \$4.",
+Cost còdes ëd conferma a scad ai $4.",
'confirmemail_invalidated' => "Conferma ëd l'adrëssa e-mail scanselà",
'invalidateemail' => "Scansela l'e-mail ëd conferma",
'newwindow' => '(abre numa janela nova)',
'cancel' => 'Cancelar',
'moredotdotdot' => 'Mais...',
-'mypage' => 'Utilizador',
+'mypage' => 'Página',
'mytalk' => 'Discussão',
'anontalk' => 'Discussão para este IP',
'navigation' => 'Navegação',
'newwindow' => '(abre em uma nova janela)',
'cancel' => 'Cancelar',
'moredotdotdot' => 'Mais...',
-'mypage' => 'Minha página',
-'mytalk' => 'Minha discussão',
+'mypage' => 'Página',
+'mytalk' => 'Discussão',
'anontalk' => 'Discussão para este IP',
'navigation' => 'Navegação',
'and' => ' e',
# Preferences page
'preferences' => 'Preferências',
-'mypreferences' => 'Minhas preferências',
+'mypreferences' => 'Preferências',
'prefs-edits' => 'Número de edições:',
'prefsnologin' => 'Não autenticado',
'prefsnologintext' => 'É necessário estar <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} autenticado]</span> para definir as suas preferências.',
# Contributions
'contributions' => 'Contribuições {{GENDER:{{BASEPAGENAME}}|do usuário|da usuária}}',
'contributions-title' => 'Contribuições {{GENDER:$1|do usuário|da usuária}} $1',
-'mycontris' => 'Minhas contribuições',
+'mycontris' => 'Contribuições',
'contribsub2' => 'Para $1 ($2)',
'nocontribs' => 'Não foram encontradas mudanças com este critério.',
'uctop' => '(atual)',
{{Identical|Cancel}}',
'moredotdotdot' => '{{Identical|More...}}',
-'mytalk' => 'In the personal urls page section - right upper corner.',
+'mypage' => "A text for the link to the user's user page in the links at the top of the page.",
+'mytalk' => 'In the personal urls page section - right upper corner.
+
+Used as link title in "Personal tools" toolbar.',
'anontalk' => 'Link to the talk page appearing in [[mw:Help:Navigation#User_Links|user links]] for each anonymous users when [[mw:Manual:$wgShowIPinHeader|$wgShowIPinHeader]] is true.',
'navigation' => 'This is shown as a section header in the sidebar of most skins.
'preferences' => 'Title of the Special:Preferences page.
{{Identical|Preferences}}',
-'mypreferences' => 'Action link label that leads to Special:Preferences; appears in the top menu (e.g. "Username My talk My preferences My watchlist My contributions Log out").
+'mypreferences' => 'Action link label that leads to Special:Preferences; appears in the top menu (e.g. "Username Talk Preferences Watchlist Contributions Log out").
{{Identical|My preferences}}',
'prefs-edits' => 'In user preferences.',
'logentry-rights-rights' => '*$1 - username
*$3 - username
*$4 - list of user groups or {{msg-mw|Rightsnone}}
-*$5 - list of user groups or {{msg-mw|Rightsnone}}',
+*$5 - list of user groups or {{msg-mw|Rightsnone}}
+
+{{Logentry}}',
'logentry-rights-rights-legacy' => '*$1 - username
-*$3 - username',
+*$3 - username
+
+{{Logentry}}',
+'logentry-rights-autopromote' => '*$1 - username
+*$4 - comma separated list of old user groups or {{msg-mw|Rightsnone}}
+*$5 - comma separated list of new user groups
+
+{{Logentry}}',
'rightsnone' => 'Default rights for registered users.
{{Identical|None}}',
'whatlinkshere-hidelinks' => 'Filter option in [[Special:WhatLinksHere]]. Parameters:
* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}',
'whatlinkshere-hideimages' => 'Filter option in [[Special:WhatLinksHere]]. Parameters:
-* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}',
+* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}
+
+See also:
+*{{msg-mw|Isimage}}
+*{{msg-mw|Media_tip}}',
'whatlinkshere-filters' => '{{Identical|Filter}}',
# Block/unblock
'api-error-uploaddisabled' => 'API error message that can be used for client side localisation of API errors.',
'api-error-verification-error' => 'The word "extension" refers to the part behind the last dot in a file name, that by convention gives a hint about the kind of data format which a files contents are in.',
+# Unknown messages
+'mytalk-parenthetical' => 'When user page and talk combined into single label, link title for talk label',
);
'newwindow' => '(se deschide într-o fereastră nouă)',
'cancel' => 'Revocare',
'moredotdotdot' => 'Mai mult…',
-'mypage' => 'Pagina mea',
+'mypage' => 'Pagină',
'mytalk' => 'Discuții',
'anontalk' => 'Discuția pentru această adresă IP',
'navigation' => 'Navigare',
'linksearch-ok' => 'Caută',
'linksearch-text' => 'Pot fi folosite metacaractere precum „*.wikipedia.org”.
Necesită cel puțin un domeniu de nivel superior, cum ar fi „*.org”.<br />
-Protocoale suportate: <code>$1</code> (nu adăugați niciunul dintre acestea în câmpul de căutare).',
+Protocoale suportate: <code>$1</code> (se trece implicit la http:// dacă nu este specificat niciun protocol).',
'linksearch-line' => '$1 este legat de $2',
'linksearch-error' => 'Metacaracterele pot să apară doar la începutul hostname-ului.',
'whatlinkshere-hideredirs' => '$1 redirecționările',
'whatlinkshere-hidetrans' => '$1 transcluderile',
'whatlinkshere-hidelinks' => '$1 legăturile',
-'whatlinkshere-hideimages' => '$1 legăturile către imagine',
+'whatlinkshere-hideimages' => '$1 legăturile către fișier',
'whatlinkshere-filters' => 'Filtre',
# Block/unblock
'duration-centuries' => '$1 {{PLURAL:$1|secol|secole|de secole}}',
'duration-millennia' => '$1 {{PLURAL:$1|mileniu|milenii|de milenii}}',
+# Unknown messages
+'mytalk-parenthetical' => 'discuție',
);
'category-empty' => "''Эта категория в данный момент пуста.''",
'hidden-categories' => '{{PLURAL:$1|Скрытая категория|Скрытые категории}}',
'hidden-category-category' => 'Скрытые категории',
-'category-subcat-count' => '{{PLURAL:$2|Данная категория содержит только следующую подкатегорию.|{{PLURAL:$1|Показана $1 подкатегория|Показано $1 подкатегории|Показано $1 подкатегорий}} из $2.}}',
+'category-subcat-count' => '{{PLURAL:$2|Данная категория содержит только следующую подкатегорию.|{{PLURAL:$1|Показана $1 подкатегория|Показано $1 подкатегории|Показано $1 подкатегорий}} из $2, находящихся в этой категории.}}',
'category-subcat-count-limited' => 'В этой категории {{PLURAL:$1|$1 подкатегория|$1 подкатегории|$1 подкатегорий}}.',
-'category-article-count' => '{{PLURAL:$2|Эта категория содержит только одну страницу.|{{PLURAL:$1|Показана $1 страница|Показано $1 страницы|Показано $1 страниц}} этой категории из $2.}}',
+'category-article-count' => '{{PLURAL:$2|Эта категория содержит только одну страницу.|{{PLURAL:$1|Показана $1 страница|Показано $1 страницы|Показано $1 страниц}} из $2, находящихся в этой категории.}}',
'category-article-count-limited' => 'В этой категории {{PLURAL:$1|$1 страница|$1 страницы|$1 страниц}}.',
-'category-file-count' => '{{PLURAL:$2|Эта категория содержит только один файл.|{{PLURAL:$1|Показан $1 файл|Показано $1 файла|Показано $1 файлов}} этой категории из $2.}}',
+'category-file-count' => '{{PLURAL:$2|Эта категория содержит только один файл.|{{PLURAL:$1|Показан $1 файл|Показано $1 файла|Показано $1 файлов}} из $2, находящихся в этой категории.}}',
'category-file-count-limited' => 'В этой категории {{PLURAL:$1|$1 файл|$1 файла|$1 файлов}}.',
'listingcontinuesabbrev' => '(продолжение)',
'index-category' => 'Индексируемые страницы',
'cancel' => 'Отменить',
'moredotdotdot' => 'Далее…',
'mypage' => 'Личная страница',
-'mytalk' => 'Ð\9cоÑ\8f Ñ\81Ñ\82Ñ\80аниÑ\86а обсуждения',
+'mytalk' => 'Ð\9eбсуждения',
'anontalk' => 'Обсуждение для этого IP-адреса',
'navigation' => 'Навигация',
'and' => ' и',
'vector-view-create' => 'Создание',
'vector-view-edit' => 'Правка',
'vector-view-history' => 'История',
-'vector-view-view' => 'Чтение',
+'vector-view-view' => 'Читать',
'vector-view-viewsource' => 'Просмотр разметки',
'actions' => 'Действия',
'namespaces' => 'Пространства имён',
'talkpage' => 'Обсудить эту страницу',
'talkpagelinktext' => 'обсуждение',
'specialpage' => 'Служебная страница',
-'personaltools' => 'Ð\9bиÑ\87ные инструменты',
+'personaltools' => 'Ð\9fеÑ\80Ñ\81оналÑ\8cные инструменты',
'postcomment' => 'Новый раздел',
'articlepage' => 'Просмотреть статью',
'talk' => 'Обсуждение',
'mainpage' => 'Заглавная страница',
'mainpage-description' => 'Заглавная страница',
'policy-url' => 'Project:Правила',
-'portal' => 'СообÑ\89еÑ\81Ñ\82во',
+'portal' => 'Ð\9fоÑ\80Ñ\82ал Ñ\81ообÑ\89еÑ\81Ñ\82ва',
'portal-url' => 'Project:Портал сообщества',
'privacy' => 'Политика конфиденциальности',
'privacypage' => 'Project:Политика конфиденциальности',
'viewsourceold' => 'просмотреть исходный код',
'editlink' => 'править',
'viewsourcelink' => 'просмотреть исходный код',
-'editsectionhint' => 'Ð\9fÑ\80авиÑ\82Ñ\8c Ñ\81екÑ\86иÑ\8e «$1»',
+'editsectionhint' => 'РедакÑ\82иÑ\80оваÑ\82Ñ\8c Ñ\80аздел «$1»',
'toc' => 'Содержание',
'showtoc' => 'показать',
'hidetoc' => 'убрать',
'delete-hook-aborted' => 'Правка отменена процедурой-перехватчиком.
Дополнительных пояснений не приведено.',
'badtitle' => 'Недопустимое название',
-'badtitletext' => 'Ð\97апÑ\80аÑ\88иваемое название Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\8b непÑ\80авилÑ\8cно, пÑ\83Ñ\81Ñ\82о, либо непÑ\80авилÑ\8cно указано межъязыковое или интервики название. Возможно, в названии используются недопустимые символы.',
+'badtitletext' => 'Ð\97апÑ\80аÑ\88иваемое название Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\8b непÑ\80авилÑ\8cно, пÑ\83Ñ\81Ñ\82о, либо невеÑ\80но указано межъязыковое или интервики название. Возможно, в названии используются недопустимые символы.',
'perfcached' => 'Следующие данные взяты из кэша и могут не учитывать последних изменений. В кэше хранится не более $1 {{PLURAL:$1|записи|записей|записей}}.',
'perfcachedts' => 'Следующие данные взяты из кэша, последний раз он обновлялся в $1. В кэше хранится не более $4 {{PLURAL:$4|записи|записей|записей}}.',
'querypage-no-updates' => 'Обновление этой страницы сейчас отключено.
'welcomecreation' => '== Добро пожаловать, $1! ==
Ваша учётная запись создана.
Не забудьте провести [[Special:Preferences|персональную настройку]] сайта.',
-'yourname' => 'Имя участника:',
+'yourname' => 'Имя учётной записи:',
'yourpassword' => 'Пароль:',
'yourpasswordagain' => 'Повторный набор пароля:',
'remembermypassword' => 'Помнить мою учётную запись на этом компьютере (не более $1 {{PLURAL:$1|дня|дней|дней}})',
'logout' => 'Завершение сеанса',
'userlogout' => 'Завершение сеанса',
'notloggedin' => 'Вы не представились системе',
-'nologin' => "Нет учётной записи? '''$1'''.",
+'nologin' => 'Нет учётной записи? $1.',
'nologinlink' => 'Создать учётную запись',
-'createaccount' => 'Ð\97аÑ\80егиÑ\81Ñ\82Ñ\80иÑ\80оваÑ\82Ñ\8c нового Ñ\83Ñ\87аÑ\81Ñ\82ника',
+'createaccount' => 'СоздаÑ\82Ñ\8c Ñ\83Ñ\87Ñ\91Ñ\82нÑ\83Ñ\8e запиÑ\81Ñ\8c',
'gotaccount' => "Вы уже зарегистрированы? '''$1'''.",
'gotaccountlink' => 'Представьтесь',
'userlogin-resetlink' => 'Забыли данные для входа?',
'showpreview' => 'Предварительный просмотр',
'showlivepreview' => 'Быстрый предпросмотр',
'showdiff' => 'Внесённые изменения',
-'anoneditwarning' => "'''Внимание:''' Вы не представились системе.
-Ваш IP-адрес будет записан в историю изменений этой страницы.",
+'anoneditwarning' => "'''Внимание!''' Вы не авторизовались на сайте.
+В истории изменений этой страницы будет записан ваш IP-адрес.",
'anonpreviewwarning' => "''Вы не представились системе. Сохранение приведёт к записи вашего IP-адреса в историю изменений страницы.''",
'missingsummary' => "'''Напоминание.''' Вы не дали краткого описания изменений. При повторном нажатии на кнопку «{{int:savearticle}}», ваши изменения будут сохранены без комментария.",
'missingcommenttext' => 'Пожалуйста, введите ниже ваше сообщение.',
'cascadeprotectedwarning' => "'''Предупреждение:''' Данную страницу могут редактировать только участники группы «Администраторы», поскольку она включена {{PLURAL:$1|в следующую страницу, для которой|в следующие страницы, для которых}} включена каскадная защита:",
'titleprotectedwarning' => "'''Предупреждение. Это название защищено. Создать эту страницу могут только участники с [[Special:ListGroupRights|соответствующими правами]].'''
Ниже для справки приведена последняя запись журнала:",
-'templatesused' => '{{PLURAL:$1|Шаблон, иÑ\81полÑ\8cзованнÑ\8bй|ШаблонÑ\8b, иÑ\81полÑ\8cзованнÑ\8bе}} на Ñ\82екÑ\83Ñ\89ей веÑ\80Ñ\81ии Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\8b:',
+'templatesused' => '{{PLURAL:$1|Шаблон, иÑ\81полÑ\8cзованнÑ\8bй|ШаблонÑ\8b, иÑ\81полÑ\8cзованнÑ\8bе}} на Ñ\8dÑ\82ой Ñ\81Ñ\82Ñ\80аниÑ\86е:',
'templatesusedpreview' => '{{PLURAL:$1|Шаблон, используемый|Шаблоны, используемые}} в предпросматриваемой странице:',
'templatesusedsection' => '{{PLURAL:$1|Шаблон, используемый|Шаблоны, использованные}} в этом разделе:',
'template-protected' => '(защищено)',
'template-semiprotected' => '(частично защищено)',
-'hiddencategories' => 'Эта страница относится к $1 {{PLURAL:$1|скрытой категории|скрытым категориям|скрытым категориям}}:',
+'hiddencategories' => 'Эта страница относится к $1 {{PLURAL:$1|скрытой категории|скрытым категориям}}:',
'edittools' => '<!-- Расположенный здесь текст будет показываться под формой редактирования и формой загрузки. -->',
'nocreatetitle' => 'Создание страниц ограничено',
'nocreatetext' => 'На этом сайте ограничена возможность создания новых страниц.
'sectioneditnotsupported-text' => 'На этой странице не поддерживается редактирование разделов',
'permissionserrors' => 'Ошибки прав доступа',
'permissionserrorstext' => 'У вас нет прав на выполнение этой операции по {{PLURAL:$1|следующей причине|следующим причинам}}:',
-'permissionserrorstext-withaction' => "У вас нет разрешения на «'''$2'''» по {{PLURAL:$1|следующей причине|следующим причинам}}:",
+'permissionserrorstext-withaction' => 'У вас нет прав на $2 по {{PLURAL:$1|следующей причине|следующим причинам}}:',
'recreate-moveddeleted-warn' => "'''Внимание. Вы пытаетесь воссоздать страницу, которая ранее удалялась.'''
Проверьте, действительно ли вам нужно воссоздавать эту страницу.
'content-model-css' => 'CSS',
# Parser/template warnings
-'expensive-parserfunction-warning' => 'Внимание. Эта страница содержит слишком много вызовов ресурсоёмких функций.
+'expensive-parserfunction-warning' => "'''Внимание!''' Эта страница содержит слишком много вызовов ресурсоёмких функций.
-Ð\9eгÑ\80аниÑ\87ение на колиÑ\87еÑ\81Ñ\82во вÑ\8bзовов Ñ\83Ñ\81Ñ\82ановлено на Ñ\83Ñ\80овне $2 {{PLURAL:$2|вÑ\8bзова|вÑ\8bзовов|вÑ\8bзовов}}, в данном Ñ\81лÑ\83Ñ\87ае Ñ\82Ñ\80ебÑ\83еÑ\82Ñ\81Ñ\8f Ñ\81делаÑ\82Ñ\8c $1 {{PLURAL:$1|вÑ\8bзов|вÑ\8bзова|вÑ\8bзовов}}.',
+Ð\94олжно бÑ\8bÑ\82Ñ\8c не более $2 {{PLURAL:$2|вÑ\8bзова|вÑ\8bзовов}}, в Ñ\82о вÑ\80емÑ\8f как Ñ\81ейÑ\87аÑ\81 здеÑ\81Ñ\8c $1 {{PLURAL:$1|вÑ\8bзов|вÑ\8bзова|вÑ\8bзовов}}.",
'expensive-parserfunction-category' => 'Страницы со слишком большим количеством вызовов ресурсоёмких функций',
'post-expand-template-inclusion-warning' => 'Предупреждение: суммарный размер включаемых шаблонов слишком велик.
Некоторые шаблоны не будут включены.',
** Потенциально клеветнические сведения',
'revdelete-otherreason' => 'Другая/дополнительная причина:',
'revdelete-reasonotherlist' => 'Другая причина',
-'revdelete-edit-reasonlist' => 'Ð\9fÑ\80авить список причин',
+'revdelete-edit-reasonlist' => 'РедакÑ\82иÑ\80овать список причин',
'revdelete-offender' => 'Автор версии страницы:',
# Suppression log
'diff-multi-manyusers' => '(не {{PLURAL:$1|показана $1 промежуточная версия|показаны $1 промежуточные версии|показаны $1 промежуточных версий}}, сделанные более чем $2 {{PLURAL:$2|участником|участниками}})',
'difference-missing-revision' => '{{PLURAL:$2|$2 версия|$2 версии|$2 версий}} для этого сравнения ($1) {{PLURAL:$2|не обнаружена|не обнаружены}}.
-ÐÑ\82о обÑ\8bÑ\87но бÑ\8bваеÑ\82, еÑ\81ли поÑ\81ледоваÑ\82Ñ\8c по Ñ\83Ñ\81Ñ\82аÑ\80евÑ\88ей Ñ\81Ñ\81Ñ\8bлке на Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83, которая была удалена.
+ÐÑ\82о обÑ\8bÑ\87но бÑ\8bваеÑ\82, еÑ\81ли пеÑ\80ейÑ\82и по Ñ\83Ñ\81Ñ\82аÑ\80евÑ\88ей Ñ\81Ñ\81Ñ\8bлке Ñ\81Ñ\80авнениÑ\8f веÑ\80Ñ\81ий длÑ\8f Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\8b, которая была удалена.
Подробности могут быть в [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале удалений].',
# Search results
'searchresulttext' => 'Для получения более подробной информации о поиске на страницах проекта, см. [[{{MediaWiki:Helppage}}|справочный раздел]].',
'searchsubtitle' => 'По запросу «[[:$1]]» ([[Special:Prefixindex/$1|страницы, начинающиеся с этого названия]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|ссылающиеся на это название]])',
'searchsubtitleinvalid' => 'По запросу «$1»',
-'toomanymatches' => 'Найдено слишком много соответствий, пожалуйста, попробуйте другой запрос',
+'toomanymatches' => 'Найдено слишком много соответствий; пожалуйста, попробуйте сформулировать запрос иначе',
'titlematches' => 'Совпадения в названиях страниц',
'notitlematches' => 'Нет совпадений в названиях страниц',
'textmatches' => 'Совпадения в текстах страниц',
'shown-title' => 'Показывать $1 {{PLURAL:$1|запись|записи|записей}} на странице',
'viewprevnext' => 'Просмотреть ($1 {{int:pipe-separator}} $2) ($3)',
'searchmenu-legend' => 'Настройки поиска',
-'searchmenu-exists' => "'''Ð\92 Ñ\8dÑ\82ом вики-пÑ\80оекÑ\82е есть страница «[[:$1]]»'''",
+'searchmenu-exists' => "'''Ð\92 Ñ\8dÑ\82ой вики есть страница «[[:$1]]»'''",
'searchmenu-new' => "'''Создать страницу «[[:$1]]» в этом вики-проекте!'''",
'searchhelp-url' => 'Help:Содержание',
'searchmenu-prefix' => '[[Special:PrefixIndex/$1|Показать страницы с этим префиксом]]',
'searchprofile-articles-tooltip' => 'Поиск в $1',
'searchprofile-project-tooltip' => 'Поиск в $1',
'searchprofile-images-tooltip' => 'Поиск файлов',
-'searchprofile-everything-tooltip' => 'Поиск на всех страницах (включая страницы обсуждения)',
+'searchprofile-everything-tooltip' => 'Поиск на всех страницах (включая страницы обсуждений)',
'searchprofile-advanced-tooltip' => 'Искать в заданных пространствах имён',
'search-result-size' => '$1 ({{PLURAL:$2|$2 слово|$2 слова|$2 слов}})',
-'search-result-category-size' => '$1 {{PLURAL:$1|член|члена|членов}} ($2 {{PLURAL:$2|подкатегория|подкатегории|подкатегорий}}, $3 {{PLURAL:$3|файл|файла|файлов}}).',
+'search-result-category-size' => '$1 {{PLURAL:$1|вхождение|вхождения|вхождений}} ($2 {{PLURAL:$2|подкатегория|подкатегории|подкатегорий}}, $3 {{PLURAL:$3|файл|файла|файлов}}).',
'search-result-score' => 'Релевантность: $1%.',
'search-redirect' => '(перенаправление с $1)',
'search-section' => '(раздел «$1»)',
'timezoneregion-europe' => 'Европа',
'timezoneregion-indian' => 'Индийский океан',
'timezoneregion-pacific' => 'Тихий океан',
-'allowemail' => 'Разрешить приём электронной почты от других участников',
+'allowemail' => 'Разрешить получение электронной почты от других участников',
'prefs-searchoptions' => 'Поиск',
'prefs-namespaces' => 'Пространства имён',
'defaultns' => 'Иначе искать в следующих пространствах имён:',
'prefs-emailconfirm-label' => 'Подтверждение электронной почты:',
'prefs-textboxsize' => 'Размер окна редактирования',
'youremail' => 'Электронная почта:',
-'username' => 'РегиÑ\81Ñ\82Ñ\80аÑ\86ионное имÑ\8f:',
+'username' => 'Ð\98мÑ\8f Ñ\83Ñ\87Ñ\91Ñ\82ной запиÑ\81и:',
'uid' => 'Идентификатор участника:',
'prefs-memberingroups' => 'Член {{PLURAL:$1|группы|групп}}:',
'prefs-registration' => 'Время регистрации:',
-'yourrealname' => 'Ð\92аÑ\88е настоящее имя:',
+'yourrealname' => 'Ð\9dастоящее имя:',
'yourlanguage' => 'Язык интерфейса:',
'yourvariant' => 'Вариант языка содержания:',
'prefs-help-variant' => 'Предпочитаемый для отображения содержимого страниц вики вариант языка или орфография.',
'prefs-help-realname' => 'Настоящее имя (необязательное поле).
Если вы укажете его, то оно будет использовано для того, чтобы показать, кем была внесена правка страницы.',
'prefs-help-email' => 'Адрес электронной почты указывать необязательно, но он будет необходим в том случае, если вы забудете пароль.',
-'prefs-help-email-others' => 'Он также позволит другим участникам связаться с вами через ссылку на вашей личной странице без необходимости раскрытия адреса вашей электронной почты.',
+'prefs-help-email-others' => 'Он также позволит другим участникам связаться с вами по электронной почте с помощью ссылки на вашей персональной странице или на вашей странице обсуждения. При этом ваш адрес электронной почты не будет никому раскрыт.',
'prefs-help-email-required' => 'Необходимо указать адрес электронной почты.',
'prefs-info' => 'Основные сведения',
'prefs-i18n' => 'Интернационализация',
# User preference: e-mail validation using jQuery
'email-address-validity-valid' => 'Выглядит корректно',
-'email-address-validity-invalid' => 'ТÑ\80ебÑ\83еÑ\82Ñ\81Ñ\8f коÑ\80Ñ\80екÑ\82нÑ\8bй адÑ\80еÑ\81!',
+'email-address-validity-invalid' => 'Ð\92ведиÑ\82е коÑ\80Ñ\80екÑ\82нÑ\8bй адÑ\80еÑ\81 Ñ\8dлекÑ\82Ñ\80онной поÑ\87Ñ\82Ñ\8b!',
# User rights
'userrights' => 'Управление правами участника',
'userrights-lookup-user' => 'Управление группами участников',
-'userrights-user-editname' => 'Введите имя участника:',
+'userrights-user-editname' => 'Введите имя учётной записи:',
'editusergroup' => 'Изменить членство в группах',
'editinguser' => "Изменение прав {{GENDER:$1|участника|участницы}} '''[[User:$1|$1]]''' $2",
'userrights-editusergroup' => 'Изменение членства в группах',
'saveusergroups' => 'Сохранить группы участника',
-'userrights-groupsmember' => 'Член гÑ\80Ñ\83пп:',
-'userrights-groupsmember-auto' => 'Неявный член:',
+'userrights-groupsmember' => 'СоÑ\81Ñ\82оиÑ\82 в гÑ\80Ñ\83ппаÑ\85:',
+'userrights-groupsmember-auto' => 'Неявно состоит в группах:',
'userrights-groups-help' => 'Вы можете изменить группы, в которые входит этот участник.
* Если около названия группы стоит отметка, значит участник входит в эту группу.
* Если отметка не стоит — участник не относится к соответствующей группе.
-* Знак * отмечает, что вы не можете удалить из группы участника, если добавите его в неё или наоборот.',
+* Знак * отмечает, что вы не сможете удалить участника из группы, если добавите его в неё, или наоборот.',
'userrights-reason' => 'Причина:',
'userrights-no-interwiki' => 'У вас нет разрешения изменять права участников на других вики.',
'userrights-nodatabase' => 'База данных $1 не существует или не является локальной.',
'right-undelete' => 'восстановление страниц',
'right-suppressrevision' => 'просмотр и восстановление скрытых от администраторов версий страниц',
'right-suppressionlog' => 'просмотр частных журналов',
-'right-block' => 'Ñ\83Ñ\81Ñ\82ановка запÑ\80еÑ\82а на Ñ\80едакÑ\82иÑ\80ование дÑ\80Ñ\83гим Ñ\83Ñ\87аÑ\81Ñ\82никам',
+'right-block' => 'Ñ\83Ñ\81Ñ\82ановка огÑ\80аниÑ\87ений на Ñ\80едакÑ\82иÑ\80ование длÑ\8f дÑ\80Ñ\83гиÑ\85 Ñ\83Ñ\87аÑ\81Ñ\82ников',
'right-blockemail' => 'установка запрета на отправку электронной почты',
'right-hideuser' => 'запрет имени участника и его сокрытие',
'right-ipblock-exempt' => 'обход блокировок по IP, автоблокировок и блокировок диапазонов',
'action-edit' => 'редактирование этой страницы',
'action-createpage' => 'создание страниц',
'action-createtalk' => 'создание страниц обсуждений',
-'action-createaccount' => 'создание этой учётной записи участника',
-'action-minoredit' => 'оÑ\82меÑ\82ка этой правки как малой',
+'action-createaccount' => 'создание этой учётной записи',
+'action-minoredit' => 'помеÑ\82кÑ\83 этой правки как малой',
'action-move' => 'переименование этой страницы',
'action-move-subpages' => 'переименование этой страницы со всеми её подстраницами',
'action-move-rootuserpages' => 'переименование корневых страниц участников',
'action-movefile' => 'переименовать этот файл',
-'action-upload' => 'загрузка этого файла',
+'action-upload' => 'загрузку этого файла',
'action-reupload' => 'перезапись существующего файла',
'action-reupload-shared' => 'перекрытие файла из общего хранилища',
-'action-upload_by_url' => 'загрузка этого файла с адреса URL',
+'action-upload_by_url' => 'загрузку этого файла с адреса URL',
'action-writeapi' => 'использование API для правок',
'action-delete' => 'удаление этой страницы',
'action-deleterevision' => 'удаление этой версии страницы',
'action-undelete' => 'восстановление этой страницы',
'action-suppressrevision' => 'просмотр и восстановление этой скрытой версии страницы',
'action-suppressionlog' => 'просмотр этого частного журнала',
-'action-block' => 'блокиÑ\80овка участника',
+'action-block' => 'огÑ\80аниÑ\87иваÑ\82Ñ\8c возможноÑ\81Ñ\82Ñ\8c Ñ\80едакÑ\82иÑ\80ованиÑ\8f длÑ\8f Ñ\8dÑ\82ого участника',
'action-protect' => 'изменение уровня защиты этой страницы',
-'action-rollback' => 'быстрый откат изменений последнего пользователя, который редактировал страницу',
+'action-rollback' => 'быстрый откат изменений участника, который последним редактировал страницу',
'action-import' => 'импорт этой страницы из другой вики',
'action-importupload' => 'импорт этой страницы из загруженного файла',
'action-patrol' => 'отметка чужих правок как отпатрулированных',
'recentchanges' => 'Свежие правки',
'recentchanges-legend' => 'Настройки свежих правок',
'recentchanges-summary' => 'Ниже в хронологическом порядке перечислены последние изменения на страницах {{grammar:genitive|{{SITENAME}}}}.',
-'recentchanges-feed-description' => 'Ð\9eÑ\82Ñ\81леживаÑ\82Ñ\8c поÑ\81ледние изменениÑ\8f в вики в Ñ\8dÑ\82ом поÑ\82оке.',
+'recentchanges-feed-description' => 'Ð\9eÑ\82Ñ\81леживаÑ\82Ñ\8c в Ñ\8dÑ\82ом поÑ\82оке поÑ\81ледние изменениÑ\8f в вики.',
'recentchanges-label-newpage' => 'Этой правкой была создана новая страница.',
'recentchanges-label-minor' => 'Это незначительное изменение',
'recentchanges-label-bot' => 'Эта правка сделана ботом',
-'recentchanges-label-unpatrolled' => 'Эту правку ещё не отпатрулировали',
+'recentchanges-label-unpatrolled' => 'Эта правку ещё никем не патрулировалась',
'rcnote' => "{{PLURAL:$1|Последнее '''$1''' изменение|Последние '''$1''' изменения|Последние '''$1''' изменений}} за '''$2''' {{PLURAL:$2|день|дня|дней}}, на момент времени $5 $4.",
-'rcnotefrom' => 'Ниже перечислены изменения с <strong>$2</strong> (по <strong>$1</strong>).',
+'rcnotefrom' => "Ниже перечислены изменения с '''$2''' (не более '''$1''').",
'rclistfrom' => 'Показать изменения с $1.',
'rcshowhideminor' => '$1 малые правки',
'rcshowhidebots' => '$1 ботов',
'withoutinterwiki' => 'Страницы без интервики-ссылок',
'withoutinterwiki-summary' => 'Следующие страницы не имеют интервики-ссылок:',
-'withoutinterwiki-legend' => 'Ð\9fÑ\80иÑ\81Ñ\82авка',
+'withoutinterwiki-legend' => 'Ð\9fÑ\80еÑ\84икÑ\81',
'withoutinterwiki-submit' => 'Показать',
'fewestrevisions' => 'Страницы с наименьшим количеством версий',
'listgrouprights-group' => 'Группа',
'listgrouprights-rights' => 'Права',
'listgrouprights-helppage' => 'Help:Права групп',
-'listgrouprights-members' => '(список группы)',
+'listgrouprights-members' => '(список участников)',
'listgrouprights-right-display' => '<span class="listgrouprights-granted">$1 (<code>$2</code>)</span>',
'listgrouprights-right-revoked' => '<span class="listgrouprights-revoked">$1 (<code>$2</code>)</span>',
'listgrouprights-addgroup' => 'может добавлять в {{PLURAL:$2|группу|группы}}: $1',
# Contributions
'contributions' => 'Вклад участника',
'contributions-title' => 'Вклад {{GENDER:$1|участника|участницы}} $1',
-'mycontris' => 'Ð\9cой вклад',
+'mycontris' => 'Ð\92клад',
'contribsub2' => 'Вклад $1 ($2)',
'nocontribs' => 'Изменений, соответствующих заданным условиям, найдено не было.',
-'uctop' => ' (последняя)',
+'uctop' => '(последняя)',
'month' => 'С месяца (и ранее):',
'year' => 'С года (и ранее):',
'isredirect' => 'страница-перенаправление',
'istemplate' => 'включение',
'isimage' => 'файловая ссылка',
-'whatlinkshere-prev' => '{{PLURAL:$1|предыдущая|предыдущие|предыдущие}} $1',
-'whatlinkshere-next' => '{{PLURAL:$1|следующая|следующие|следующие}} $1',
+'whatlinkshere-prev' => '{{PLURAL:$1|предыдущая|предыдущие}} $1',
+'whatlinkshere-next' => '{{PLURAL:$1|следующая|следующие}} $1',
'whatlinkshere-links' => '← ссылки',
'whatlinkshere-hideredirs' => '$1 перенаправления',
'whatlinkshere-hidetrans' => '$1 включения',
'whatlinkshere-hidelinks' => '$1 ссылки',
-'whatlinkshere-hideimages' => '$1 Ñ\81Ñ\81Ñ\8bлки длÑ\8f изобÑ\80ажений',
+'whatlinkshere-hideimages' => '$1 Ñ\84айловÑ\8bе Ñ\81Ñ\81Ñ\8bлки',
'whatlinkshere-filters' => 'Фильтры',
# Block/unblock
'allmessages-filter-unmodified' => 'Неизменённые',
'allmessages-filter-all' => 'Все',
'allmessages-filter-modified' => 'Изменённые',
-'allmessages-prefix' => 'ФилÑ\8cÑ\82Ñ\80 по пÑ\80иÑ\81Ñ\82авке:',
+'allmessages-prefix' => 'ФилÑ\8cÑ\82Ñ\80 по пÑ\80еÑ\84икÑ\81Ñ\83:',
'allmessages-language' => 'Язык:',
'allmessages-filter-submit' => 'Перейти',
'tooltip-pt-login' => 'Здесь можно зарегистрироваться в системе, но это необязательно.',
'tooltip-pt-anonlogin' => 'Здесь можно зарегистрироваться в системе, но это необязательно.',
'tooltip-pt-logout' => 'Завершить сеанс работы',
-'tooltip-ca-talk' => 'Обсуждение содержания страницы',
-'tooltip-ca-edit' => 'ÐÑ\82Ñ\83 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 можно изменÑ\8fÑ\82Ñ\8c. Ð\98Ñ\81полÑ\8cзÑ\83йÑ\82е, пожалÑ\83йÑ\81Ñ\82а, пÑ\80едваÑ\80иÑ\82елÑ\8cнÑ\8bй пÑ\80оÑ\81моÑ\82Ñ\80 пеÑ\80ед Ñ\81оÑ\85Ñ\80анением',
+'tooltip-ca-talk' => 'Обсуждение основной страницы',
+'tooltip-ca-edit' => 'Ð\92Ñ\8b можеÑ\82е Ñ\80едакÑ\82иÑ\80оваÑ\82Ñ\8c Ñ\8dÑ\82Ñ\83 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83. Ð\9fеÑ\80ед Ñ\82ем, как запиÑ\81аÑ\82Ñ\8c Ñ\81вои изменениÑ\8f, воÑ\81полÑ\8cзÑ\83йÑ\82еÑ\81Ñ\8c, пожалÑ\83йÑ\81Ñ\82а, кнопкой пÑ\80едваÑ\80иÑ\82елÑ\8cного пÑ\80оÑ\81моÑ\82Ñ\80а.',
'tooltip-ca-addsection' => 'Создать новый раздел',
'tooltip-ca-viewsource' => 'Эта страница защищена от изменений, но вы можете посмотреть и скопировать её исходный текст',
'tooltip-ca-history' => 'Журнал изменений страницы',
'tooltip-n-mainpage' => 'Перейти на заглавную страницу',
'tooltip-n-mainpage-description' => 'Перейти на заглавную страницу',
'tooltip-n-portal' => 'О проекте, о том, что вы можете сделать, где что находится',
-'tooltip-n-currentevents' => 'СпиÑ\81ок Ñ\82екÑ\83Ñ\89иÑ\85 Ñ\81обÑ\8bÑ\82ий',
+'tooltip-n-currentevents' => 'Ð\98нÑ\84оÑ\80маÑ\86иÑ\8f о Ñ\82екÑ\83Ñ\89иÑ\85 Ñ\81обÑ\8bÑ\82иÑ\8fÑ\85',
'tooltip-n-recentchanges' => 'Список последних изменений',
'tooltip-n-randompage' => 'Посмотреть случайную страницу',
'tooltip-n-help' => 'Справочник по проекту «{{SITENAME}}»',
-'tooltip-t-whatlinkshere' => 'Список всех страниц, которые ссылаются на эту страницу',
+'tooltip-t-whatlinkshere' => 'Список всех страниц, ссылающихся на данную',
'tooltip-t-recentchangeslinked' => 'Последние изменения в страницах, на которые ссылается эта страница',
'tooltip-feed-rss' => 'Трансляция в RSS для этой страницы',
'tooltip-feed-atom' => 'Трансляция в Atom для этой страницы',
'tooltip-t-contributions' => 'Список страниц, которые изменял этот участник',
'tooltip-t-emailuser' => 'Отправить письмо этому участнику',
-'tooltip-t-upload' => 'Загрузить изображения или мультимедиа-файлы',
+'tooltip-t-upload' => 'Загрузить файлы',
'tooltip-t-specialpages' => 'Список служебных страниц',
'tooltip-t-print' => 'Версия этой страницы для печати',
'tooltip-t-permalink' => 'Постоянная ссылка на эту версию страницы',
-'tooltip-ca-nstab-main' => 'СодеÑ\80жание Ñ\81Ñ\82аÑ\82Ñ\8cи',
+'tooltip-ca-nstab-main' => 'Ð\9fÑ\80оÑ\81моÑ\82Ñ\80 оÑ\81новной Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\8b',
'tooltip-ca-nstab-user' => 'Персональная страница участника',
'tooltip-ca-nstab-media' => 'Медиа-файл',
'tooltip-ca-nstab-special' => 'Это служебная страница, она недоступна для редактирования',
# Watchlist editing tools
'watchlisttools-view' => 'Изменения на страницах из списка',
-'watchlisttools-edit' => 'Смотреть/править список',
-'watchlisttools-raw' => 'Ð\9fÑ\80авиÑ\82Ñ\8c как текст',
+'watchlisttools-edit' => 'Смотреть и редактировать список',
+'watchlisttools-raw' => 'РедакÑ\82иÑ\80оваÑ\82Ñ\8c как обÑ\8bÑ\87нÑ\8bй текст',
# Iranian month names
'iranian-calendar-m1' => 'Фарвардин',
'sqlite-no-fts' => '$1 без поддержки полнотекстового поиска',
# New logging system
-'logentry-delete-delete' => '$1 {{GENDER:$1|удалил|удалила}} страницу $3',
+'logentry-delete-delete' => '$1 {{GENDER:$2|удалил|удалила}} страницу $3',
'logentry-delete-restore' => '$1 {{GENDER:$1|восстановил|восстановила}} страницу $3',
'logentry-delete-event' => '$1 {{GENDER:$1|изменил|изменила}} видимость {{PLURAL:$5|$5 записи|$5 записей|$5 записей}} журнала на $3: $4',
'logentry-delete-revision' => '$1 {{GENDER:$1|изменил|изменила}} видимость {{PLURAL:$5|$5 версии|$5 версий|$5 версий}} на странице $3: $4',
'underline-always' => 'Куруук',
'underline-never' => 'Аннынан тардыма',
-'underline-default' => 'Браузер настройкатынан',
+'underline-default' => 'Браузер туруоруутунан',
# Font style option in Special:Preferences
'editfont-style' => 'Эрэдээксийэлиир түннүк бичигэ:',
'vector-action-protect' => 'Уларыйбат гын',
'vector-action-undelete' => 'Төннөр',
'vector-action-unprotect' => 'Көмүскэлин уларыт',
-'vector-simplesearch-preference' => 'Ð\9aÓ©Ñ\80дөбүл Ñ\8dÑ\82Ñ\8dн биÑ\8dÑ\80иилÑ\8dÑ\80ин кÑ\8dÒ¥Ñ\8dÑ\82иллибиÑ\82 барылын туруор («Векторга» эрэ)',
+'vector-simplesearch-preference' => 'Ð\9aÓ©Ñ\80дөбүл Ñ\83Ñ\81Ñ\82Ñ\83Ñ\80Ñ\83окаÑ\82Ñ\8bн Ñ\81Ñ\83дÑ\83Ñ\80гÑ\83 барылын туруор («Векторга» эрэ)',
'vector-view-create' => 'Ай',
'vector-view-edit' => 'Уларыт',
'vector-view-history' => 'Устуоруйатын көрүү',
'newmessagesdifflink' => 'кэлиҥҥи уларытыы',
'youhavenewmessagesfromusers' => 'Маны $1 {{PLURAL:$3|соҕотох кыттааччыттан|$3 кыттааччыттан}} туппуккун ($2).',
'youhavenewmessagesmanyusers' => 'Маны $1 элбэх кыттааччыттан туппуккун ($2).',
+'newmessageslinkplural' => '{{PLURAL:$1|саҥа этии|саҥа этии}}',
'newmessagesdifflinkplural' => 'тиһэх {{PLURAL:$1|уларытыы|уларытыылар}}',
'youhavenewmessagesmulti' => '$1, саҥа суруктар кэллилэр',
'editsection' => 'уларыт',
'dberrortext' => 'Билии олоҕор ыйытык синтаксииһа сыыһалаах эбит.
Ол бырагырааммаҕар баар сыыһаттан буолуон сөп.
Билии олоҕор бүтэһик ыйытык маннык:
-<blockquote><tt>$1</tt></blockquote>
-(бу пуунсуйаттан тахсыбыт "<tt>$2</tt>").
-Билии олоҕо сыыһаны көрдөрдө "<tt>$3: $4</tt>".',
+: <code>$1</code>
+(бу пуунсуйаттан тахсыбыт «<code>$2</code>»).
+Билии олоҕо сыыһаны көрдөрдө «<code>$3: $4</code>».',
'dberrortextcl' => 'Билии олоҕор ыйытык синтаксииһын сыыһата таҕыста.
Билии олоҕор бүтэһик ыйытык:
"$1"
'protectedpagetext' => 'Бу сирэй уларытыллыбат.',
'viewsourcetext' => 'Эн бу сирэй төрдүн көрүөххүн уонна төгүллүөххүн сөп:',
'viewyourtext' => "'''Бэйэҥ көннөрүүлэриҥ''' исходнигын бу сирэйгэ көрүөххүн уонна хатылаан ылыаххын сөп:",
-'protectedinterface' => 'Бу сирэй бырагыраамма холбуурун хааччыйар, онон моһуогурууттан халытан хатанан турар',
-'editinginterface' => "'''Болҕой:''' Быраҕыраамма тас көстүүтүн (интерфейсын) хааччыйар тиэкиһи уларытаары гынан эрэҕин. Бу сирэйи уларыттаххына атын кыттааччылар көрөллөрүгэр бырагыраамма көстүүтэ уларыйыа. Тылбаастыыр буоллаххына Медиавики бырайыактарын сахалыы тылбааһын [//translatewiki.net/wiki/Main_Page?setlang=sah translatewiki.net] туһан.",
+'protectedinterface' => 'Бу сирэй бырагыраамма интерфейсын биллэриитин көрдөрөр, онон моһуогурууттан халытан хатанан турар.
+Тылбааһын уларытыаххын баҕарар буоллаххына онно аналлаах тылбаас ситим-сирин туһан: MediaWiki [//translatewiki.net/ translatewiki.net]',
+'editinginterface' => "'''Болҕой:''' Быраҕыраамма тас көстүүтүн (интерфейсын) хааччыйар тиэкиһи уларытаары гынан эрэҕин.
+Бу сирэйи уларыттаххына атын кыттааччылар көрөллөрүгэр бырагыраамма көстүүтэ уларыйыа.
+Тылбааһын уларытыаххын эбэтэр эбиэххин баҕарар буоллаххына Медиавики бырайыактарын тылбаастыыр сиргэ киир [//translatewiki.net/ translatewiki.net].",
'sqlhidden' => '(SQL ыйытык кистэммит)',
'cascadeprotected' => 'Бу сирэй уларыйар кыаҕа суох, тоҕо диэтэххэ уларыйара бобуллубут (каскаднай көмүскэл холбоммут) {{PLURAL:$1|сирэй бөлөҕөр|сирэйдэр бөлөхтөрүгэр}} киирэр:
$2',
'remembermypassword' => 'Миигин бу көмпүүтэргэ сигээ ($1 {{PLURAL:$1|күн|күнтэн ордуга суох}})',
'securelogin-stick-https' => 'Киирэн баран HTTPS нөҥүө холбонууну салгыырга',
'yourdomainname' => 'Эн дөмүөнүҥ:',
+'password-change-forbidden' => 'Бу биикигэ киирии тылы уоарытар табыллыбат.',
'externaldberror' => 'Тас киирии билиитин олоҕун сыыһата буолла, эбэтэр тас киирии билииҥ олоҕун саҥардар кыаҕыҥ суох.',
'login' => 'Киир',
'nav-login-createaccount' => 'Киир / бэлиэтэн',
# Contributions
'contributions' => 'Кыттааччы суруйуута (вклад)',
'contributions-title' => '$1 кыттааччы киллэрбит уларытыылара',
-'mycontris' => 'Суруйуум тиһигэ',
+'mycontris' => 'Суруйуу тиһигэ',
'contribsub2' => 'Вклад $1 ($2)',
'nocontribs' => 'Эппит критерийгэр эппиэттиир уларытыылар көстүбэтилэр.',
'uctop' => '(бүтэһик)',
'whatlinkshere-hideredirs' => '$1 утаарыы',
'whatlinkshere-hidetrans' => '$1 киллэриилэр',
'whatlinkshere-hidelinks' => '$1 сигэ (ыйынньык)',
-'whatlinkshere-hideimages' => '$1 ойÑ\83Ñ\83 сигэтэ',
+'whatlinkshere-hideimages' => '$1 билÑ\8d сигэтэ',
'whatlinkshere-filters' => 'Фильтрдар',
# Block/unblock
'version-software' => 'Туруоруллубут бырагырааммалар',
'version-software-product' => 'Бородуукта',
'version-software-version' => 'Барыл (торум)',
+'version-entrypoints' => 'Киирэр аадырыстар (URL)',
'version-entrypoints-header-entrypoint' => 'Киирии сирэ',
'version-entrypoints-header-url' => 'URL',
'api-error-file-too-large' => 'Ыыппыт билэҥ наһаа улахан эбит.',
'api-error-filename-tooshort' => 'Билэҥ аата наһаа кылгас.',
'api-error-filetype-banned' => 'Маннык көрүҥнээх билэлэр бобуулаахтар.',
-'api-error-filetype-banned-type' => '$1 — {{PLURAL:$4|билэ бобуллубут көрүҥэ|билэ бобуллубут көрүҥнэрэ}}.. Көҥүллэммит билэ {{PLURAL:$3|көрүҥэ маннык|көрүҥнэрэ манныктар}}: $2.',
+'api-error-filetype-banned-type' => '$1 — {{PLURAL:$4|билэ бобуллубут көрүҥэ|билэ бобуллубут көрүҥнэрэ}}.
+Көҥүллэммит билэ {{PLURAL:$3|көрүҥэ маннык|көрүҥнэрэ манныктар}}: $2.',
'api-error-filetype-missing' => 'Бу билэ тэнитиитэ (расширение) суох эбит.',
'api-error-hookaborted' => 'Эн киллэрбит уларытыыгын кэҥэтии таҥастааччыта оннугар төннөрбүт.',
'api-error-http' => 'Ис алҕас: Сиэрбэргэ холбонор табыллыбата.',
'hist' => 'história',
'hide' => 'skryť',
'show' => 'zobraziť',
-'minoreditletter' => 'D',
+'minoreditletter' => 'd',
'newpageletter' => 'N',
'boteditletter' => 'b',
'number_of_watching_users_pageview' => '[$1 {{PLURAL:$1|sledujúci používateľ|sledujúci používatelia|sledujúcich používateľov}}]',
'newwindow' => '(odpre se novo okno)',
'cancel' => 'Prekliči',
'moredotdotdot' => 'Več ...',
-'mypage' => 'Moja stran',
+'mypage' => 'Stran',
'mytalk' => 'Pogovor',
'anontalk' => 'Pogovorna stran IP',
'navigation' => 'Navigacija',
'rclinks' => 'Prikaži zadnjih $1 sprememb v zadnjih $2 dneh<br />$3',
'diff' => 'prim',
'hist' => 'zgod',
-'hide' => 'skrij',
+'hide' => 'Skrij',
'show' => 'Prikaži',
'minoreditletter' => 'm',
'newpageletter' => 'N',
'linksearch-pat' => 'Iskalni vzorec:',
'linksearch-ns' => 'Imenski prostor:',
'linksearch-ok' => 'Išči',
-'linksearch-text' => 'Nadomestne znake, kot je »*.wikipedia.org«, lahko uporabljate.
+'linksearch-text' => 'Uporabljate lahko nadomestne znake, kot je »*.wikipedia.org«.
Zahtevana je vsaj najvišja domena, na primer »*.org«.<br />
-Podprti protokoli: <code>$1</code> (teh ne dodajte v svoje iskanje).',
+Podprti protokoli: <code>$1</code> (če protokol ni določen, se privzame http://).',
'linksearch-line' => '$1 povezano iz $2',
'linksearch-error' => 'Jokerji se lahko pojavijo le na začetku gostiteljskega imena.',
'whatlinkshere-hideredirs' => '$1 preusmeritve',
'whatlinkshere-hidetrans' => '$1 vključitve',
'whatlinkshere-hidelinks' => '$1 povezave',
-'whatlinkshere-hideimages' => '$1 povezave slik',
+'whatlinkshere-hideimages' => '$1 povezave datotek',
'whatlinkshere-filters' => 'Filtri',
# Block/unblock
'underline-always' => 'увек подвлачи',
'underline-never' => 'никад не подвлачи',
-'underline-default' => 'по поставкама прегледача',
+'underline-default' => 'према теми или прегледачу',
# Font style option in Special:Preferences
'editfont-style' => 'Изглед фонта у уређивачком оквиру:',
'linksearch-ok' => 'Претражи',
'linksearch-text' => 'Могу се користити џокери попут „*.wikipedia.org“.<br />
Потребан је највиши домен, као „*.org“.<br />
-Ð\9fодÑ\80жани пÑ\80оÑ\82околи: <code>$1</code> (не Ñ\81Ñ\82авÑ\99аÑ\98Ñ\82е Ñ\83 пÑ\80еÑ\82Ñ\80агÑ\83)',
+Ð\9fодÑ\80жани пÑ\80оÑ\82околи: <code>$1</code> (задаÑ\98е http:// ако не наведеÑ\82е пÑ\80оÑ\82окол).',
'linksearch-line' => '$1 веза у $2',
'linksearch-error' => 'Џокери се могу појавити само на почетку адресе.',
'nolinkshere-ns' => "Ниједна страница не води до '''[[:$1]]''' у изабраном именском простору.",
'isredirect' => 'преусмерење',
'istemplate' => 'укључивање',
-'isimage' => 'веза ка даÑ\82оÑ\82еÑ\86и',
+'isimage' => 'веза до даÑ\82оÑ\82еке',
'whatlinkshere-prev' => '{{PLURAL:$1|претходни|претходних $1}}',
'whatlinkshere-next' => '{{PLURAL:$1|следећи|следећих $1}}',
'whatlinkshere-links' => '← везе',
'whatlinkshere-hideredirs' => '$1 преусмерења',
'whatlinkshere-hidetrans' => '$1 укључивања',
'whatlinkshere-hidelinks' => '$1 везе',
-'whatlinkshere-hideimages' => '$1 везе до слика',
+'whatlinkshere-hideimages' => '$1 везе до датотеке',
'whatlinkshere-filters' => 'Филтери',
# Block/unblock
'underline-always' => 'uvek podvlači',
'underline-never' => 'nikad ne podvlači',
-'underline-default' => 'po postavkama pregledača',
+'underline-default' => 'prema temi ili pregledaču',
# Font style option in Special:Preferences
'editfont-style' => 'Izgled fonta u uređivačkom okviru:',
'linksearch-ok' => 'Pretraži',
'linksearch-text' => 'Mogu se koristiti džokeri poput „*.wikipedia.org“.<br />
Potreban je najviši domen, kao „*.org“.<br />
-Podržani protokoli: <code>$1</code> (ne stavljajte u pretragu)',
+Podržani protokoli: <code>$1</code> (zadaje http:// ako ne navedete protokol).',
'linksearch-line' => '$1 veza u $2',
'linksearch-error' => 'Džokeri se mogu pojaviti samo na početku adrese.',
'whatlinkshere-hideredirs' => '$1 preusmerenja',
'whatlinkshere-hidetrans' => '$1 uključivanja',
'whatlinkshere-hidelinks' => '$1 veze',
-'whatlinkshere-hideimages' => '$1 veze do slika',
+'whatlinkshere-hideimages' => '$1 veze do datoteke',
'whatlinkshere-filters' => 'Filteri',
# Block/unblock
'cancel' => 'Avbryt',
'moredotdotdot' => 'Mer...',
'mypage' => 'Min sida',
-'mytalk' => 'Min diskussion',
+'mytalk' => 'Diskussion',
'anontalk' => 'Diskussionssida för denna IP-adress',
'navigation' => 'Navigering',
'and' => ' och',
# Preferences page
'preferences' => 'Inställningar',
-'mypreferences' => 'Mina inställningar',
+'mypreferences' => 'Inställningar',
'prefs-edits' => 'Antal redigeringar:',
'prefsnologin' => 'Inte inloggad',
'prefsnologintext' => 'Du måste vara <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} inloggad]</span> för att kunna ändra dina inställningar.',
'linksearch-ns' => 'Namnrymd:',
'linksearch-ok' => 'Sök',
'linksearch-text' => 'Jokertecken (wildcards) som t.ex. "*.wikipedia.org" kan användas.
-Det krävs åtminstone en toppnivå-domän, t.ex. "*.org".<br />
-Protokoll som stöds: <code>$1</code> (lägg inte till något av dessa i din sökning).',
+Det krävs åtminstone en toppdomän, t.ex. "*.org".<br />
+Protokoll som stöds: <code>$1</code> (lägg inte till någon av dessa i din sökning).',
'linksearch-line' => '$1 länkas från $2',
'linksearch-error' => 'Jokertecken kan bara användas i början av domännamnet.',
# Watchlist
'watchlist' => 'Bevakningslista',
-'mywatchlist' => 'Min bevakningslista',
+'mywatchlist' => 'Bevakningslista',
'watchlistfor2' => 'För $1 $2',
'nowatchlist' => 'Du har inga sidor i din bevakningslista.',
'watchlistanontext' => 'Du måste $1 för att se eller redigera din bevakningslista.',
# Contributions
'contributions' => 'Användarbidrag',
'contributions-title' => 'Bidrag av $1',
-'mycontris' => 'Mina bidrag',
+'mycontris' => 'Bidrag',
'contribsub2' => 'För $1 ($2)',
'nocontribs' => 'Inga ändringar som motsvarar dessa kriterier hittades.',
'uctop' => '(senaste)',
'version-license' => 'Licens',
'version-poweredby-credits' => "Den här wikin drivs av '''[//www.mediawiki.org/ MediaWiki]''', copyright © 2001-$1 $2.",
'version-poweredby-others' => 'andra',
+'version-credits-summary' => 'Vi skulle vilja tacka följande personer för deras bidrag till [[Special:Version|MediaWiki]].',
'version-license-info' => 'MediaWiki är fri programvara; du kan distribuera det och/eller modifiera det under villkoren i GNU General Public License, publicerad av Free Software Foundation; antingen version 2 av licensen, eller (om du önskar) någon senare version.
MediaWiki distribueras i hopp om att det ska vara användbart, men UTAN NÅGON GARANTI, även utan underförstådd garanti om SÄLJBARHET eller LÄMPLIGHET FÖR ETT VISST SYFTE. Se GNU General Public License för fler detaljer.
'duration-centuries' => '$1 {{PLURAL:$1|sekel|sekel}}',
'duration-millennia' => '$1 {{PLURAL:$1|millennium|millennier}}',
+# Unknown messages
+'mytalk-parenthetical' => 'diskussion',
);
'cancel' => 'Batilisha',
'moredotdotdot' => 'Zaidi...',
'mypage' => 'Ukurasa wangu',
-'mytalk' => 'Majadiliano yangu',
+'mytalk' => 'Majadiliano',
'anontalk' => 'Majadiliano ya IP hii',
'navigation' => 'Urambazaji',
'and' => ' na',
'noarticletext' => 'Ukurasa huu haujaandikwa bado. [[Special:Search/{{PAGENAME}}|tafutia jina hili]] katika kurasa nyingine, <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} tafuta kumbukumbu zinazohusika], au [{{fullurl:{{FULLPAGENAME}}|action=edit}} hariri ukurasa huu]</span>.',
'noarticletext-nopermission' => 'Kwa sasa hakuna maandishi katika ukurasa huu.
Unaweza [[Special:Search/{{PAGENAME}}|kutafuta jina la ukurasa huu]] katika kurasa nyingine,
-au <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} tafuta ingizo linalofanana]</span>.',
+au <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} tafuta kumbukumbu zinazohusika]</span>, lakini huruhusiwi kuanzisha ukurasa huu.',
'userpage-userdoesnotexist' => 'Akaunti ya mtumiaji "<nowiki>$1</nowiki>" haijasajilishwa.
Ukitaka kuanzisha au kuhariri ukurasa huu tafadhali ucheki jina la akaunti.',
'userpage-userdoesnotexist-view' => 'Akaunti ya mtumiaji "$1" haijasajilishwa.',
# Preferences page
'preferences' => 'Mapendekezo',
-'mypreferences' => 'Mapendekezo yangu',
+'mypreferences' => 'Mapendekezo',
'prefs-edits' => 'Idadi ya marekebisho:',
'prefsnologin' => 'Hujaingia',
'prefsnologintext' => 'Inabidi <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} uingie akaunti yako]</span> ili ubadilishe mapendekezo yako.',
# Watchlist
'watchlist' => 'Maangalizi yangu',
-'mywatchlist' => 'Maangalizi yangu',
+'mywatchlist' => 'Maangalizi',
'watchlistfor2' => 'Kwa ajili ya $1 $2',
'nowatchlist' => 'Hamna vitu katika maangalizi yako.',
'watchlistanontext' => 'Tafadhali $1 ili kutazama au kuhariri vitu vilivyopo katika orodha yako ya maangalizi.',
# Contributions
'contributions' => 'Michango ya mtumiaji',
'contributions-title' => 'Michango ya mtumiaji $1',
-'mycontris' => 'Michango yangu',
+'mycontris' => 'Michango',
'contribsub2' => 'Kwa $1 ($2)',
'nocontribs' => 'Mabadiliko yanayolingana na vigezo vilivyoulizwa hayakupatikana.',
'uctop' => '(juu)',
'underline-always' => 'எப்பொழுதும்',
'underline-never' => 'எப்போதுமில்லை',
-'underline-default' => 'உலாவி இயல்பிருப்பு',
+'underline-default' => 'தà¯\8bலà¯\8d à®\85லà¯\8dலதà¯\81 à®\89லாவி à®\87யலà¯\8dபிரà¯\81பà¯\8dபà¯\81',
# Font style option in Special:Preferences
'editfont-style' => 'தொகுத்தல் பெட்டி எழுத்துரு:',
'newwindow' => '(புதிய சாளரத்துள் திறக்கும்)',
'cancel' => 'சேமிக்காமல் திரும்பு',
'moredotdotdot' => 'மேலும்...',
-'mypage' => 'à®\8eனதà¯\81 பà®\95à¯\8dà®\95à®®à¯\8d',
-'mytalk' => 'à®\8eனà¯\8d பà¯\87à®\9aà¯\8dà®\9aà¯\81',
+'mypage' => 'பக்கம்',
+'mytalk' => 'பேச்சு',
'anontalk' => 'இந்த ஐ.பி. முகவரிக்கான பேச்சு',
'navigation' => 'வழிசெலுத்தல்',
'and' => ' மற்றும்',
'youhavenewmessages' => 'உங்களுக்குப் $1 உள்ளன ($2).',
'newmessageslink' => 'புதிய செய்திகள்',
'newmessagesdifflink' => 'கடைசி மாற்றம்',
+'youhavenewmessagesfromusers' => 'உங்களுக்கு $1 {{PLURAL:$3|வேறொரு பயனரிடம்|$3 பயனர்களிடம்}} இருந்து உள்ளது ($2).',
'newmessageslinkplural' => '{{PLURAL:$1|ஒரு புதிய செய்தி|புதிய செய்திகள்}}',
'newmessagesdifflinkplural' => 'கடைசி {{PLURAL:$1|மாற்றம்|மாற்றங்கள்}}',
'youhavenewmessagesmulti' => '$1 இல் உங்களுக்கு புதிய செய்திகள் காத்திருக்கின்றன',
* தடை செய்யப்பட்டவர்: $7
$1 பயனரையோ அல்லது வேறு [[{{MediaWiki:Grouppage-sysop}}|நிர்வாகி]] ஒருவரையோ அனுகி தடைப் பற்றி கலந்துரையாடலாம். 'இப் பயனருக்கு மின்னஞ்சல் செய்' என்ற வசதியை நீங்கள் பயன்படுத்துவதுலிருந்து தடைச் செய்யப்பட்டிருந்தாலோ அல்லது [[Special:Preferences|என் விருப்பத்தேர்வுகள்]] பக்கத்தில் இயங்குநிலையிலுள்ள மின்னஞ்சல் முகவரியை தராத போதோ பயனருக்கு மின்னஞ்சல் செய்ய முடியாது. உங்களது தற்போதைய ஐ.பி. முகவரி $3 மற்றும் தடை எண் #$5 என்பவற்றை கேள்விகள் கேட்கும் போது கட்டாயம் குறிப்பிடவும்.",
-'autoblockedtext' => '$1 ஆல் தடைச்செய்யப்பட்ட வேறு பயனரால் பயன்படுத்தபட்டதால், உங்கள் ஐ.பி. முகவரி தானியக்கமாக தடுக்கப்பட்டுள்ளது. அதற்கான காரணம் பின்வருமாறு:
+'autoblockedtext' => 'உங்கள் ஐ.பி. முகவரி தடை செய்யப்பட்டுள்ளது. அதே முகவரியைப் பயன்படுத்தித் தொக்குத்த யாரோ ஒரு பயனர் பின்வரும் காரணங்களுக்காகத் தடை செய்யப்பட்டுள்ளார். அதனால் உங்களால் தொகுக்க முடியவில்லை. அதற்கான காரணம் பின்வருமாறு:
:\'\'$2\'\'
* தடை முடிவு: $6
* தடை செய்யப்பட்டவர்: $7
-$1 பயனரà¯\88யà¯\8b à®\85லà¯\8dலதà¯\81 வà¯\87à®±à¯\81 [[{{MediaWiki:Grouppage-sysop}}|நிரà¯\8dவாà®\95ி]] à®\92à®°à¯\81வரà¯\88யà¯\8b à®\85னà¯\81à®\95ி தà®\9fைப் பற்றி கலந்துரையாடலாம்.
+$1 à®\8eனà¯\81à®®à¯\8d பயனரà¯\88யà¯\8b வà¯\87à®±à¯\81 [[{{MediaWiki:Grouppage-sysop}}|நிரà¯\8dவாà®\95ி]] à®\92à®°à¯\81வரà¯\88யà¯\8b à®\85னà¯\81à®\95ிதà¯\8d தà®\9fà¯\88யைப் பற்றி கலந்துரையாடலாம்.
-"à®\87பà¯\8d பயனரà¯\81à®\95à¯\8dà®\95à¯\81 மினà¯\8dனà®\9eà¯\8dà®\9aலà¯\8d à®\9aà¯\86யà¯\8d" à®\8eனà¯\8dà®± வà®\9aதியà¯\88 நà¯\80à®\99à¯\8dà®\95ளà¯\8d பயனà¯\8dபà®\9fà¯\81தà¯\81வதிலிரà¯\81நà¯\8dதà¯\81 தà®\9fà¯\88à®\9aà¯\8d à®\9aà¯\86யà¯\8dயபà¯\8dபà®\9fà¯\8dà®\9fிரà¯\81நà¯\8dதாலà¯\8b à®\85லà¯\8dலதà¯\81 [[Special:Preferences|à®\8eனà¯\8d விரà¯\81பà¯\8dபதà¯\8dதà¯\87à®°à¯\8dவà¯\81à®\95ளà¯\8d]] பà®\95à¯\8dà®\95தà¯\8dதிலà¯\8d à®\87யà®\99à¯\8dà®\95à¯\81நிலà¯\88யிலà¯\81ளà¯\8dள மினà¯\8dனà®\9eà¯\8dà®\9aலà¯\8d à®®à¯\81à®\95வரியà¯\88 தராத போதோ பயனருக்கு மின்னஞ்சல் செய்ய முடியாது.
+"à®\87பà¯\8d பயனரà¯\81à®\95à¯\8dà®\95à¯\81 மினà¯\8dனà®\9eà¯\8dà®\9aலà¯\8d à®\9aà¯\86யà¯\8d" à®\8eனà¯\8dà®± வà®\9aதியà¯\88 நà¯\80à®\99à¯\8dà®\95ளà¯\8d பயனà¯\8dபà®\9fà¯\81தà¯\8dதà¯\81வதிலிரà¯\81நà¯\8dதà¯\81 தà®\9fà¯\88à®\9aà¯\8d à®\9aà¯\86யà¯\8dயபà¯\8dபà®\9fà¯\8dà®\9fிரà¯\81நà¯\8dதாலà¯\8b à®\85லà¯\8dலதà¯\81 [[Special:Preferences|à®\8eனà¯\8d விரà¯\81பà¯\8dபதà¯\8dதà¯\87à®°à¯\8dவà¯\81à®\95ளà¯\8d]] பà®\95à¯\8dà®\95தà¯\8dதிலà¯\8d à®\87யà®\99à¯\8dà®\95à¯\81நிலà¯\88யிலà¯\81ளà¯\8dள மினà¯\8dனà®\9eà¯\8dà®\9aலà¯\8d à®®à¯\81à®\95வரியà¯\88தà¯\8d தராதபோதோ பயனருக்கு மின்னஞ்சல் செய்ய முடியாது.
-à®\89à®\99à¯\8dà®\95ளதà¯\81 தறà¯\8dபà¯\8bதà¯\88ய à®\90.பி. à®®à¯\81à®\95வரி $3 மறà¯\8dà®±à¯\81à®®à¯\8d தà®\9fà¯\88 à®\8eணà¯\8d #$5 à®\8eனà¯\8dபவறà¯\8dà®±à¯\88 à®\95à¯\87ளà¯\8dவிà®\95ளà¯\8d à®\95à¯\87à®\9fà¯\8dà®\95à¯\81à®®à¯\8d பà¯\8bதà¯\81 கட்டாயம் குறிப்பிடவும்.',
+à®\87தà¯\88பà¯\8d பறà¯\8dறிய à®\89à®\99à¯\8dà®\95ளà¯\8d à®\95à¯\87ளà¯\8dவிà®\95ளà¯\88à®\95à¯\8d à®\95à¯\87à®\9fà¯\8dà®\95à¯\81à®®à¯\8dபà¯\8bதà¯\81 à®\89à®\99à¯\8dà®\95ளதà¯\81 தறà¯\8dபà¯\8bதà¯\88ய à®\90.பி. à®®à¯\81à®\95வரி $3 மறà¯\8dà®±à¯\81à®®à¯\8d தà®\9fà¯\88 à®\8eணà¯\8d #$5 à®\86à®\95ியவறà¯\8dà®±à¯\88à®\95à¯\8d கட்டாயம் குறிப்பிடவும்.',
'blockednoreason' => 'காரணம் தரப்படவில்லை',
'whitelistedittext' => 'நீங்கள் பக்கங்களத் தொகுக்க $1 செய்யவேண்டும்.',
'confirmedittext' => 'நீங்கள் பக்கங்களைத் தொகுக்க முன்னர் மின்னஞ்சல் முகவரியை உறுதிப்படுத்த வேண்டும். உங்கள் [[Special:Preferences|விருப்பத்தேர்வுகள்]] பக்கத்தில் செல்லுபடியான மின்னஞ்சலைக் கொடுத்து அதனை உறுதிப்படுத்துங்கள்.',
# Preferences page
'preferences' => 'விருப்பங்கள்',
-'mypreferences' => 'à®\8eனà¯\8d விரà¯\81பà¯\8dபதà¯\8dதà¯\87à®°à¯\8dவà¯\81à®\95ளà¯\8d',
+'mypreferences' => 'விருப்பத்தேர்வுகள்',
'prefs-edits' => 'தொகுப்புகளின் எண்ணிக்கை:',
'prefsnologin' => 'புகுபதிகை செய்யப்படவில்லை',
'prefsnologintext' => 'பயனர் விருப்பத்தேர்வுகளை அமைப்பதற்கு நீங்கள் <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} புகுபதிகை ]</span> செய்திருக்க வேண்டும்.',
# Watchlist
'watchlist' => 'என் கவனிப்புப் பட்டியல்',
-'mywatchlist' => 'à®\8eனà¯\8d à®\95வனிபà¯\8dபà¯\81பà¯\8d பà®\9fà¯\8dà®\9fியலà¯\8d',
+'mywatchlist' => 'கவனிப்புப் பட்டியல்',
'watchlistfor2' => '$1 பயனரின் ($2)',
'nowatchlist' => 'உங்களுடைய கவனிப்புப் பட்டியலில் ஒரு விடயமும் இல்லை.',
'watchlistanontext' => 'உங்கள் கவனிப்புப் பட்டியலைப் பார்க்க அல்லது தொகுக்க அருள் கூர்ந்து $1 செய்யுங்கள்.',
# Contributions
'contributions' => 'பயனர் பங்களிப்புக்கள்',
'contributions-title' => '$1 இற்கான பயனர் பங்களிப்புகள்',
-'mycontris' => 'à®\8eனà¯\8d பà®\99à¯\8dà®\95ளிபà¯\8dபà¯\81à®\95à¯\8dà®\95ளà¯\8d',
+'mycontris' => 'பங்களிப்புக்கள்',
'contribsub2' => '$1 பயனரின் ($2)',
'nocontribs' => 'இந்த நிபந்தனையுடன் ஒத்துப்போகும் வகையில் மாற்றங்களெதுவும் காணப்படவில்லை.',
'uctop' => '(மேல்)',
'whatlinkshere-hideredirs' => 'வழிமாற்றுகளை $1',
'whatlinkshere-hidetrans' => 'உள்ளிடப்பட்டவைகளை $1',
'whatlinkshere-hidelinks' => 'இணைப்புகள் $1',
-'whatlinkshere-hideimages' => '$1உருவ இணைப்புகள்',
+'whatlinkshere-hideimages' => '$1 கோப்பிணைப்புக்கள்',
'whatlinkshere-filters' => 'வடிகட்டிகள்',
# Block/unblock
'pageinfo-watchers' => 'பார்வையாளர்கள் எண்ணிக்கை',
'pageinfo-firstuser' => 'பக்க உருவாக்குநர்',
'pageinfo-firsttime' => 'பக்கம் உருவாக்கப்பட்ட காலம்',
-'pageinfo-lastuser' => 'பிநà¯\8dதிய தொகுப்பாளர்',
+'pageinfo-lastuser' => 'à®\85ணà¯\8dà®®à¯\88ய தொகுப்பாளர்',
'pageinfo-edits' => 'தொகுப்புகளின் எண்ணிக்கை:',
'pageinfo-authors' => 'சாதகமான அம்சங்களை பெற்றிருக்கும் எழுத்தாளர்கள் எண்ணிக்கை',
* @author Jprmvnvijay5
* @author Kaganer
* @author Kiranmayee
+ * @author Malkum
* @author Meno25
* @author Mpradeep
* @author Praveen Illa
'cancel' => 'Para',
'moredotdotdot' => 'Barak liu...',
'mypage' => "Ha'u-nia pájina",
-'mytalk' => "Ha'u-nia diskusaun",
+'mytalk' => 'Diskusaun',
'anontalk' => "Diskusaun ba IP ne'e",
'navigation' => 'Hatudu-dalan',
'and' => ' ho',
# Preferences page
'preferences' => 'Preferénsia',
-'mypreferences' => "Ha'u-nia preferénsia",
+'mypreferences' => 'Preferénsia',
'prefs-rc' => 'Mudansa foufoun sira',
'prefs-watchlist' => 'Lista hateke',
'prefs-editing' => 'Edita',
# Watchlist
'watchlist' => "Ha'u-nia lista hateke",
-'mywatchlist' => "Ha'u-nia lista hateke",
+'mywatchlist' => 'Lista hateke',
'removedwatchtext' => 'La hateke pájina "[[:$1]]" ona (haree [[Special:Watchlist|"lista hateke"]]).',
'watch' => 'Hateke',
'watchthispage' => "Hateke pájina ne'e",
# Contributions
'contributions' => "Kontribuisaun uza-na'in",
'contributions-title' => 'Kontribuisaun "$1" nian',
-'mycontris' => "Ha'u-nia kontribuisaun",
+'mycontris' => 'Kontribuisaun',
'contribsub2' => 'Ba $1 ($2)',
'uctop' => '(versaun atuál)',
'month' => 'Fulan (ho molok):',
'underline-always' => 'Palagi',
'underline-never' => 'Hindi magpakailanman',
-'underline-default' => 'Tinakda ng pambasa-basa',
+'underline-default' => 'Tinakda ng pambasa-basa o balat',
# Font style option in Special:Preferences
'editfont-style' => 'Baguhin ang estilong pantitik ng lugar:',
'cancel' => 'Kanselahin',
'moredotdotdot' => 'Damihan pa...',
'mypage' => 'Pahina ko',
-'mytalk' => 'Usapan ko',
+'mytalk' => 'Usapan',
'anontalk' => 'Usapan para sa IP na ito',
'navigation' => 'Paglilibot (nabigasyon)',
'and' => ', at',
'note' => "'''Paunawa:'''",
'previewnote' => "'''Tandaan na isa lamang itong paunang tingin.'''
Hindi pa nasasagip ang mga binago mo!",
-'continue-editing' => 'Ipagpatuloy ang pamamatnugot',
+'continue-editing' => 'Pumunta sa pook ng pamamatnugot',
'previewconflict' => 'Ipinamamalas ng paunang tinging ito ang teksto sa loob ng pangitaas na pook-patnugutan ng teksto ayon sa lilitaw na anyo nito kapag pinili mo ang pagsagip.',
'session_fail_preview' => "'''Paumanhin! Hindi namin maproseso ang iyong pagbabago hinggil sa pagkawala ng sesyon ng datos.
Paki ulit muli. Kung hindi ito gumana, subukang umalis sa pagkalagda at bumalik muli.'''",
# Preferences page
'preferences' => 'Mga kagustuhan',
-'mypreferences' => 'Mga nais ko',
+'mypreferences' => 'Mga nais',
'prefs-edits' => 'Bilang ng mga pagbabago:',
'prefsnologin' => 'Hindi nakalagda/nakatala',
'prefsnologintext' => 'Kailangan mong <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} lumagda/tumala]</span> para makapagtakda ng mga kagustuhang ng tagagamit.',
'timezoneregion-indian' => 'Karagatang Indyano',
'timezoneregion-pacific' => 'Karagatang Pasipiko',
'allowemail' => 'Pahintulutan ang e-liham mula sa ibang mga tagagamit',
-'prefs-searchoptions' => 'Mga pagpipilian para sa paghahanap',
+'prefs-searchoptions' => 'Paghahanap',
'prefs-namespaces' => 'Mga espasyo ng pangalan',
'defaultns' => 'O kaya maghanap sa mga pangalan ng espasyong ito:',
'default' => 'Likas na pagtatakda',
# Contributions
'contributions' => 'Mga ambag ng tagagamit',
'contributions-title' => 'Mga ambag ng tagagamit na si $1',
-'mycontris' => 'Mga ambag ko',
+'mycontris' => 'Mga ambag',
'contribsub2' => 'Para kay $1 ($2)',
'nocontribs' => 'Walang pagbabagong nakita sa binigay na kondisyon.',
'uctop' => ' (itaas)',
# Info page
'pageinfo-title' => 'Kabatiran para sa "$1"',
+'pageinfo-not-current' => 'Maaari lamang ipakita ang impormasyon para sa kasalukuyang rebisyon.',
'pageinfo-header-basic' => 'Saligang kabatiran',
'pageinfo-header-edits' => 'Kasaysayan ng pamamatnugot',
'pageinfo-header-restrictions' => 'Pruteksiyon ng pahina',
'newwindow' => '(yeni bir pencerede açılır)',
'cancel' => 'İptal',
'moredotdotdot' => 'Daha...',
-'mypage' => 'sayfam',
-'mytalk' => 'Mesaj sayfam',
+'mypage' => 'Sayfa',
+'mytalk' => 'Mesaj',
'anontalk' => "Bu IP'nin iletileri",
'navigation' => 'Gezinti',
'and' => ' ve',
# Preferences page
'preferences' => 'Tercihler',
-'mypreferences' => 'Tercihlerim',
+'mypreferences' => 'Tercihler',
'prefs-edits' => 'Değişiklik sayısı:',
'prefsnologin' => 'Oturum açık değil',
'prefsnologintext' => 'Kullanıcı tercihlerinizi ayarlamak için <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} giriş yapmalısınız]</span>.',
# Watchlist
'watchlist' => 'İzleme listem',
-'mywatchlist' => 'İzleme listem',
+'mywatchlist' => 'İzleme listesi',
'watchlistfor2' => '$1 için $2',
'nowatchlist' => 'İzleme listesinde hiçbir madde bulunmuyor.',
'watchlistanontext' => 'Lütfen izleme listenizdeki maddeleri görmek ya da değiştirmek için $1.',
# Contributions
'contributions' => 'Kullanıcının katkıları',
'contributions-title' => '$1 için kullanıcı katkıları',
-'mycontris' => 'Katkılarım',
+'mycontris' => 'Katkılar',
'contribsub2' => '$1 ($2)',
'nocontribs' => 'Bu kriterlere uyan değişiklik bulunamadı',
'uctop' => '(son)',
'underline-always' => 'Кезээде',
'underline-never' => 'Кажан-даа',
-'underline-default' => 'Ð\92еб-браузерниң ниити үнези',
+'underline-default' => 'Ð\9aеÑ\88Ñ\82иң азÑ\8b веб-браузерниң ниити үнези',
# Font style option in Special:Preferences
'editfont-default' => 'Веб-браузерниң ниити үнези',
'newwindow' => '(чаа көзенээ ажыытынар)',
'cancel' => 'Соксаары',
'moredotdotdot' => 'Артык...',
-'mypage' => 'Ð\9cÑ\8dÑ\8dÒ£ аÑ\80Ñ\8bнÑ\8bм',
-'mytalk' => 'Ð\9cÑ\8dÑ\8dÒ£ Ñ\87Ñ\83гаам',
+'mypage' => 'Ð\90Ñ\80Ñ\8bн',
+'mytalk' => 'ЧÑ\83гаа',
'anontalk' => 'Бо ИП-адрестиң чугаазы',
'navigation' => 'Навигация',
'and' => ' болгаш',
'create' => 'Чогаадыры',
'editthispage' => 'Бо арынны өскертири',
'create-this-page' => 'Бо арынны чогаадыры',
-'delete' => 'ЫÑ\80адÑ\8bры',
+'delete' => 'ЫÑ\80аары',
'deletethispage' => 'Бо арынны ырадыры',
'undelete_short' => '$1 {{PLURAL:$1|эдигни|эдиглерни}} катап үндүрери',
'viewdeleted_short' => '{{PLURAL:$1|Бир ыраткан өскерлиишкинни|$1 ыраткан өскерлиишкиннерни}} көөрү',
'viewsource' => 'Дөзүн көөрү',
'actionthrottled' => 'Шеглээн дүрген',
'sqlhidden' => '(SQL айтырыгны чажырган)',
+'exception-nologin' => 'Кирбес',
# Login and logout pages
'welcomecreation' => '== Кирип моорлаңар, $1! ==
'remembermypassword' => 'Мени бо компьютерде сактып алыры ($1 {{PLURAL:$1|хүн|хүн}}ге чедир)',
'login' => 'Кирери',
'nav-login-createaccount' => 'Кирери / бүрүткел бижикти чогаадыры',
+'loginprompt' => '{{SITENAME}} сайтче кирерде, баштай «cookies»-ти чөшпээрээр ужурлуг Силер.',
'userlogin' => 'Кирери / бүрүткел бижикти чогаадыры',
'userloginnocreate' => 'Кирери',
'logout' => 'Үнери',
'resetpass-temp-password' => 'Түр чажыт сөс:',
# Special:PasswordReset
+'passwordreset' => 'Чажыт сөстү дүжүрү',
'passwordreset-legend' => 'Чажыт атты дүжүр',
'passwordreset-username' => 'Aжыглакчының ады:',
'passwordreset-domain' => 'Домен:',
'moveddeleted-notice' => 'Бо арын ап каавыткан.
Адаанда ап каавыткан биле өскээр адаан бижиктер шынзылгазын көргүскен.',
+# Parser/template warnings
+'post-expand-template-inclusion-warning' => 'Сагындырыг: Кошкан майыктарның ниити хемчээли дендии улуг.
+Чамдык майыктар коштунмаан боор.',
+'post-expand-template-inclusion-category' => 'Кожар майыктарга чөшпээрээн хемчээлин ашкан арыннар',
+'post-expand-template-argument-category' => "Аргументилери салдынмаан майыктарлыг '''арыннар'''",
+
# History pages
'viewpagelogs' => 'Бо арынның журналын көргүзери',
'nohistory' => 'Бо арынның өскерлиишкин төөгүзү чок.',
'lineno' => 'Одуруг $1:',
'compareselectedversions' => 'Шилип алган хевирлери деңнээри',
'editundo' => 'чөрчүүрү',
+'diff-multi' => '({{PLURAL:$2|$2 киржикчиниң}} {{PLURAL:$1|$1 түр хевирин көргүспээн}})',
# Search results
'searchresults' => 'Түңнелдер',
'searchprofile-everything-tooltip' => 'Шупту арыннардан дилээри (сумележиишкиннерден база)',
'searchprofile-advanced-tooltip' => 'Айыткан аттар делгемнеринден дилээри',
'search-result-size' => '$1 ({{PLURAL:$2|$2 сөс}})',
+'search-result-category-size' => '{{PLURAL:$1|1 кежигүн|$1 кежигүн}} ({{PLURAL:$2|1 aдаккы бөлүк|$2 aдаккы бөлүк}}, {{PLURAL:$3|1 файл|$3 файл}})',
'search-redirect' => '($1-н шиглелге)',
'search-section' => '(«$1» деп салбыр)',
'search-suggest' => 'Силер «$1» деп бодадыңар чадавас',
# Preferences page
'preferences' => 'Шилилгелер',
-'mypreferences' => 'Ð\9cÑ\8dÑ\8dÒ£ Ñ\88илилгелеÑ\80им',
+'mypreferences' => 'ШилилгелеÑ\80',
'prefs-edits' => 'Өскерлиишкиннериңерниң саны:',
'changepassword' => 'Чажыт сөстү өскертири',
'prefs-skin' => 'Кеш',
'recentchanges-label-minor' => 'Бо өскерлиишкин бичии-дир',
'recentchanges-label-bot' => 'Бо эдилгени робот күүсеткен.',
'recentchanges-label-unpatrolled' => 'Бо өскертилге истетинмээн (патрульдаттынмаан)',
+'rcnote' => "$4 $5 өйде соңгу '''$2''' {{PLURAL:$2|хонуктуң}} {{PLURAL:$1|сөөлгү '''$1''' '''өскерилгелери'''}} .",
+'rcnotefrom' => 'Адаанда <strong>$2</strong> тура (<strong>$1</strong> чедир) өскертилгелерни санаан.',
'rclistfrom' => '$1 тура чаа өскерилгелерни көргүзер',
'rcshowhideminor' => 'Бичии өскерлиишкиннерни $1',
'rcshowhidebots' => 'Роботтарну $1',
'protectedpages' => 'Камгалаган арыннар',
'listusers' => 'Ажыглакчылар даңзызы',
'usereditcount' => '$1 {{PLURAL:$1|эдилге}}',
+'usercreated' => '$1 хүнде $2 {{GENDER:$3|бүрүткенип алган}}',
'newpages' => 'Чаа арыннар',
'newpages-username' => 'Ажыглакчының ады:',
'ancientpages' => 'Эң эрги арыннар',
# Watchlist
'watchlist' => 'Мээң хайгаарал даңзым',
-'mywatchlist' => 'Ð\9cÑ\8dÑ\8dÒ£ Ñ\85айгааÑ\80ал даңзÑ\8bм',
+'mywatchlist' => 'ХайгааÑ\80ал даңзÑ\8b',
'watchlistfor2' => '$1, силерге $2',
'nowatchlist' => 'Силерниң хайгаарал даңзыңар куруг.',
'watchnologin' => 'Кирбес',
# Contributions
'contributions' => 'Ажыглакчыниң салыышкыннары',
'contributions-title' => '«$1» деп ажыглакчының салыышкыннары',
-'mycontris' => 'Ð\9cÑ\8dÑ\8dÒ£ Ñ\81алÑ\8bÑ\8bÑ\88кÑ\8bннаÑ\80Ñ\8bм',
+'mycontris' => 'СалÑ\8bÑ\8bÑ\88кÑ\8bннаÑ\80',
'contribsub2' => '$1 ($2)',
'uctop' => '(баш)',
'month' => 'Айдан:',
'whatlinkshere-hideredirs' => '$1-че шиглиглер',
'whatlinkshere-hidetrans' => '$1 даңзылааннар',
'whatlinkshere-hidelinks' => 'холбааларны $1',
-'whatlinkshere-hideimages' => 'ЧÑ\83Ñ\80Ñ\83малдың холбааларын $1',
+'whatlinkshere-hideimages' => 'Файлдың холбааларын $1',
'whatlinkshere-filters' => 'Шүүрлер',
# Block/unblock
'tooltip-ca-nstab-main' => 'Допчы арынын көөрү',
'tooltip-ca-nstab-user' => 'Ажыглакчының арынын көөрү',
'tooltip-ca-nstab-media' => 'Медиа арынын көөрү',
+'tooltip-ca-nstab-special' => 'Бо бөлгээт арын-дыр (служебная страница), ооң эдери болдунмас.',
'tooltip-ca-nstab-project' => 'Төлевилелдиң арынын көөрү',
'tooltip-ca-nstab-image' => 'Файлдың арынын көөрү',
'tooltip-ca-nstab-template' => 'Майыкты көөрү',
'tooltip-minoredit' => 'Бо өскертилгени "биче" деп демдеглээр',
'tooltip-save' => 'Силерниң өскерлиишкиннериңерни шыгжаары',
'tooltip-preview' => 'Шыгжаар мурнунда силерниң өскерлиишкиннерин чижеглеп көрем!',
+'tooltip-compareselectedversions' => 'Бо арынның шилиттинген ийи хевиринниң ылгалын көөр.',
'tooltip-watch' => 'Силерниң хайгаарал даңзызынга бо арынны немерелээри',
'tooltip-rollback' => 'Сөөлгү киржикчиниң өскерилгелерин чаңгыс баскаш, ойталаар',
'tooltip-summary' => 'Кысказы-биле бижиңер',
'duration-decades' => '$1 {{PLURAL:$1|он хонук|он хонук}}',
'duration-centuries' => '$1 {{PLURAL:$1|чүс чыл|чүс чыл}}',
+# Unknown messages
+'mytalk-parenthetical' => 'чугаалажыры',
);
'underline-always' => 'Завжди',
'underline-never' => 'Ніколи',
-'underline-default' => 'Використати налаштування браузера',
+'underline-default' => 'Ð\92икоÑ\80иÑ\81Ñ\82овÑ\83ваÑ\82и налаÑ\88Ñ\82Ñ\83ваннÑ\8f бÑ\80аÑ\83зеÑ\80а',
# Font style option in Special:Preferences
'editfont-style' => 'Тип шрифту в полі редагування:',
'newwindow' => '(відкривається в новому вікні)',
'cancel' => 'Скасувати',
'moredotdotdot' => 'Детальніше…',
-'mypage' => 'Ð\9cоÑ\8f оÑ\81обиÑ\81Ñ\82а Ñ\81торінка',
-'mytalk' => 'Ð\9cоÑ\8f Ñ\81Ñ\82оÑ\80Ñ\96нка обговорення',
+'mypage' => 'Сторінка',
+'mytalk' => 'Ð\9eбговорення',
'anontalk' => 'Обговорення для цієї IP-адреси',
'navigation' => 'Навігація',
'and' => ' і',
# Preferences page
'preferences' => 'Налаштування',
'mypreferences' => 'Налаштування',
-'prefs-edits' => 'Ð\9aÑ\96лÑ\8cкÑ\96Ñ\81Ñ\82Ñ\8c редагувань:',
+'prefs-edits' => 'ЧиÑ\81ло редагувань:',
'prefsnologin' => 'Ви не ввійшли в систему',
'prefsnologintext' => 'Щоб змінити налаштування користувача, ви повинні <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} ввійти до системи]</span>.',
'changepassword' => 'Змінити пароль',
'rightslogtext' => 'Це протокол зміни прав користувачів.',
'rightslogentry' => 'змінив права доступу для користувача $1 з $2 на $3',
'rightslogentry-autopromote' => 'був автоматично переведений з $2 до $3',
+'logentry-rights-rights' => '$1 {{GENDER:$1|змінив|змінила}} членство в групах для $3 із $4 на $5',
+'logentry-rights-rights-legacy' => '$1 {{GENDER:$1|змінив|змінила}} членство в групах для $3',
+'logentry-rights-autopromote' => '$1 було автоматично переведено із $4 в $5',
'rightsnone' => '(нема)',
# Associated actions - in the sentence "You do not have permission to X"
'linksearch-ns' => 'Простір назв:',
'linksearch-ok' => 'Знайти',
'linksearch-text' => 'Можна використовувати підстановочні символи (шаблони), наприклад, "*.wikipedia.org".
-Необхідний домен якнайменше верхнього рівня, наприклад "*.org"<br />
-Ð\9fÑ\96дÑ\82Ñ\80имÑ\83ванÑ\96 пÑ\80оÑ\82околи: <code>$1</code> (не додавайÑ\82е жоден з ниÑ\85 Ñ\83 ваÑ\88омÑ\83 поÑ\88Ñ\83кÑ\83)',
+Необхідний домен принаймні верхнього рівня, наприклад "*.org"<br />
+Ð\9fÑ\96дÑ\82Ñ\80имÑ\83ванÑ\96 пÑ\80оÑ\82околи: <code>$1</code> (за замовÑ\87Ñ\83ваннÑ\8fм http:// Ñ\8fкÑ\89о жоден пÑ\80оÑ\82окол не вказано)',
'linksearch-line' => 'Посилання на $1 із $2',
'linksearch-error' => 'Підстановочні знаки можуть використовуватися лише на початку адрес.',
'mailnologin' => 'Відсутня адреса для відправки',
'mailnologintext' => 'Ви повинні [[Special:UserLogin|ввійти до системи]] і мати підтверджену адресу електронної пошти у ваших [[Special:Preferences|налаштуваннях]], щоб мати змогу надсилати електронну пошту іншим користувачам.',
'emailuser' => 'Надіслати листа',
-'emailuser-title-target' => 'Надіслати електронного листа користувачеві',
+'emailuser-title-target' => 'Надіслати електронного листа {{GENDER:$1|користувачеві|користувачці}}',
'emailuser-title-notarget' => 'Надіслати електронного листа користувачеві',
'emailpage' => 'Лист користувачеві',
-'emailpagetext' => 'Заповнивши наведену нижче форму, можна надіслати повідомлення цьому користувачу.
-Ð\95лекÑ\82Ñ\80онна адÑ\80еÑ\81а, Ñ\8fкÑ\83 ви зазначили у [[Special:Preferences|своїх налаштуваннях]], буде зазначена в полі «Від кого» листа, тому одержувач матиме можливість відповісти безпосередньо вам.',
+'emailpagetext' => 'Заповнивши наведену нижче форму, можна надіслати повідомлення {{GENDER:$1|цьому користувачу|цій користувачці}}.
+Ð\95лекÑ\82Ñ\80онна адÑ\80еÑ\81а, Ñ\8fкÑ\83 Ð\92и зазначили у [[Special:Preferences|своїх налаштуваннях]], буде зазначена в полі «Від кого» листа, тому одержувач матиме можливість відповісти безпосередньо вам.',
'usermailererror' => 'При відправці повідомлення електронної пошти сталася помилка:',
'defemailsubject' => '{{SITENAME}} - електронний лист від користувача " $1 "',
'usermaildisabled' => 'Електронне листування між користувачами вимкнене',
'undeletedrevisions' => '$1 {{PLURAL:$1|редагування|редагування|редагувань}} відновлено',
'undeletedrevisions-files' => '$1 {{PLURAL:$1|версія|версії|версій}} та $2 {{PLURAL:$2|файл|файли|файлів}} відновлено',
'undeletedfiles' => '$1 {{PLURAL:$1|файл|файли|файлів}} відновлено',
-'cannotundelete' => 'Не вдалося скасувати видалення, хтось інший вже міг відмінити видалення сторінки.',
+'cannotundelete' => 'Помилка відновлення:
+$1',
'undeletedpage' => "'''Сторінка «$1» відновлена'''
Див. [[Special:Log/delete|список вилучень]], щоб дізнатися про останні вилучення та відновлення.",
# Contributions
'contributions' => 'Внесок користувача',
'contributions-title' => 'Внесок користувача $1',
-'mycontris' => 'Ð\9cÑ\96й внесок',
+'mycontris' => 'Ð\92несок',
'contribsub2' => 'Внесок $1 ($2)',
'nocontribs' => 'Редагувань, що задовольняють заданим умовам не знайдено.',
'uctop' => ' (остання)',
# Info page
'pageinfo-title' => 'Інформація про " $1 "',
-'pageinfo-not-current' => 'Ð\94анÑ\96 можÑ\83Ñ\82Ñ\8c бÑ\83Ñ\82и показанÑ\96 лиÑ\88е длÑ\8f поÑ\82оÑ\87ноÑ\97 веÑ\80Ñ\81Ñ\96Ñ\97',
+'pageinfo-not-current' => 'Ð\92ибаÑ\87Ñ\82е, неможливо пеÑ\80еглÑ\8fнÑ\83Ñ\82и Ñ\86Ñ\8e Ñ\96нÑ\84оÑ\80маÑ\86Ñ\96Ñ\8e длÑ\8f Ñ\81Ñ\82аÑ\80иÑ\85 веÑ\80Ñ\81Ñ\96й.',
'pageinfo-header-basic' => 'Основна інформація',
'pageinfo-header-edits' => 'Історія редагувань',
'pageinfo-header-restrictions' => 'Захист сторінки',
'sqlite-no-fts' => '$1 без підтримки повнотекстового пошуку',
# New logging system
-'logentry-delete-delete' => '$1 вилучив сторінку $3',
+'logentry-delete-delete' => '$1 {{GENDER:$2|вилучив|вилучила}} сторінку $3',
'logentry-delete-restore' => '$1 відновив сторінку $3',
'logentry-delete-event' => '$1 змінив видимість {{PLURAL:$5 запису журнала|$5 записів журналу}} на $3: $4',
'logentry-delete-revision' => '$1 змінив видимість {{PLURAL:$5 версії|$5 версій}} на сторінці $3: $4',
* @author O.bangash
* @author Rachitrali
* @author Reedy
+ * @author Tahir mq
* @author Wisesabre
* @author ZxxZxxZ
* @author לערי ריינהארט
'vector-action-delete' => 'حذف کرو',
'vector-action-move' => 'منتقل کرو',
'vector-action-protect' => 'محفوظ کرو',
+'vector-action-undelete' => 'بحال',
'vector-action-unprotect' => 'تحفظ میں تبدیلی',
'vector-view-create' => 'تخلیق',
'vector-view-edit' => 'ترمیم',
'searcharticle' => 'چلو',
'history' => 'تاریخچہ ء صفحہ',
'history_short' => 'تاریخچہ',
+'updatedmarker' => 'میری آخری آمد تک جدید',
'printableversion' => 'قابل طبع نسخہ',
'permalink' => 'مستقل کڑی',
'print' => 'طباعت',
برائے مہربانی! صفحہ دیکھنے کیلئے دوبارہ کوشش کرنے سے پہلے ذرا انتظار فرمالیجئے.
$1',
+'pool-errorunknown' => 'نامعلوم خطا',
# All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage) and the disambiguation template definition (see disambiguations).
'aboutsite' => 'کا تعارف {{SITENAME}}',
'youhavenewmessages' => 'آپکے لیۓ ایک $1 ہے۔ ($2)',
'newmessageslink' => 'نئے پیغامات',
'newmessagesdifflink' => 'تـجـدیـد مـاقـبل آخـر سے فـرق',
+'newmessagesdifflinkplural' => 'آخری {{PLURAL:$1|تبدیلی|تبدیلیاں}}',
'youhavenewmessagesmulti' => 'ء$1 پر آپ کیلئے نئے پیغامات ہیں',
'editsection' => 'ترمیم',
'editsection-brackets' => '[$1]',
'toc' => 'فہرست',
'showtoc' => 'دکھائیں',
'hidetoc' => 'چھپائیں',
+'collapsible-expand' => 'توسیع',
'thisisdeleted' => 'دیکھیں یا بحال کریں $1؟',
'viewdeleted' => 'دیکھیں $1؟',
'restorelink' => '{{PLURAL:$1|ایک ترمیم حذف ہوچکی|$1 ترامیم حذف ہوچکیں}}',
'feed-atom' => 'اٹوم',
'feed-rss' => 'آر ایس ایس',
'red-link-title' => '$1 (صفحہ موجود نہیں)',
+'sort-descending' => 'ترتیب نزولی',
+'sort-ascending' => 'ترتیب صعودی',
# Short words for each namespace, by default used in the namespace tab in monobook
'nstab-main' => 'صفحہ',
'badarticleerror' => 'اس صفحہ پر یہ عمل انجام نہیں دیا جاسکتا۔',
'cannotdelete' => 'صفحہ یا ملف $1 کو حذف نہیں کیا جاسکتا.
ہوسکتا ہے کہ اسے پہلے ہی کسی نے حذف کردیا ہو.',
+'cannotdelete-title' => 'صفحہ ھذف نہیں کیا جا سکتا "$1"',
'badtitle' => 'خراب عنوان',
'badtitletext' => 'درخواست شدہ صفحہ کا عنوان ناقص، خالی، یا کوئی غلط ربط شدہ بین لسانی یا بین ویکی عنوان ہے.
شاید اِس میں ایک یا زیادہ ایسے حروف موجود ہوں جو عنوانات میں استعمال نہیں ہوسکتے.',
'ns-specialprotected' => 'خاص صفحات کی تدوین نہیں کی جاسکتی.',
'titleprotected' => 'اس عنوان کو [[User:$1|$1]] نے تخلیق سے محفوظ کیا ہے.
وجہ یہ بتائی گئی ہے: "\'\'$2\'\'"',
+'exception-nologin' => 'غیر داخل نوشتہ',
# Virus scanner
'virus-badscanner' => "خراب وضعیت: انجان وائرسی مفراس: ''$1''",
'yourpasswordagain' => 'کلمۂ شناخت دوبارہ لکھیں',
'remembermypassword' => 'اِس متصفح پر میرے داخلِ نوشتگی معلومات یاد رکھو (زیادہ سے زیادہ $1 {{PLURAL:$1|دِن|ایام}} کیلئے)',
'yourdomainname' => 'آپکا ڈومین',
+'password-change-forbidden' => 'آپ اس ویکی پر پارلفظ (پاس روڈ) تبدیل نہیں کر سکتے',
'externaldberror' => 'یا تو توثیقی ڈیٹابیس میں خطا واقع ہوئی اور یا آپ کو بیرونی کھاتہ بتاریخ کرنے کی اِجازت نہیں ہے.',
'login' => 'داخل ہوں',
'nav-login-createaccount' => 'کھاتہ کھولیں یا اندراج کریں',
دوبارہ کوشش کرنے سے پہلے انتظار فرمائیے.',
'loginlanguagelabel' => 'زبان: $1',
+# E-mail sending
+'user-mail-no-addy' => 'برقی ڈاک بھیجنے کی کوشش بغیر برقی ڈاک پتہ',
+
# Change password dialog
'resetpass' => 'پارلفظ تبدیل کریں',
'resetpass_announce' => 'آپ ایک برقی ارسال کردہ عارضی رمز کے ساتھ داخل ہوئے ہیں.
# Special:PasswordReset
'passwordreset' => 'پارلفظ کی بازتعینی',
'passwordreset-username' => 'اسمِ صارف:',
+'passwordreset-domain' => 'ساحہ:',
+'passwordreset-email' => 'برقی ڈاک پتہ:',
+
+# Special:ChangeEmail
+'changeemail-oldemail' => 'حالیہ برقی ڈاک پتہ:',
+'changeemail-newemail' => 'نیا برقی ڈاک پتہ:',
+'changeemail-none' => '(کوئی نہیں)',
+'changeemail-submit' => 'برقی ڈاک تبدیل کریں',
+'changeemail-cancel' => 'منسوخ',
# Edit page toolbar
'bold_sample' => 'دبیز متن',
'noarticletext' => 'اِس صفحہ میں فی الحال کوئی متن موجود نہیں ہے.
آپ دیگں صفحات میں [[Special:Search/{{PAGENAME}}|اِس صفحہ کے عنوان کیلئے تلاش کرسکتے ہیں]]، <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} متعلقہ نوشتہ جات تلاش کرسکتے ہیں],
یا [{{fullurl:{{FULLPAGENAME}}|action=edit}} اِس صفحہ میں ترمیم کرسکتے ہیں]</span>',
-'noarticletext-nopermission' => 'اِس صفحہ میں فی الحال کوئی متن موجود نہیں ہے.
+'noarticletext-nopermission' => 'اس صفحہ میں فی الحال کوئی متن موجود نہیں ہے.
آپ دیگں صفحات میں [[Special:Search/{{PAGENAME}}|اِس صفحہ کے عنوان کیلئے]] یا <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} متعلقہ نوشتہ جات تلاش کرسکتے ہیں]</span>',
'updated' => '(اپ ڈیٹڈ)',
'note' => "'''نوٹ:'''",
\"محفوظ\" کا بٹن ٹک کرنے سے '''صرف''' بالائی متن محفوظ ہوگا.",
'yourtext' => 'آپ کی تحریر',
'storedversion' => 'ذخیرہ شدہ نظرثانی',
+'nonunicodebrowser' => '"انتباہ: آپ کا براؤزر یونی کوڈ کے مطابق نہیں ہے."',
'editingold' => "'''انتباہ: آپ اس صفحے کا ایک پرانا مسودہ مرتب کررہے ہیں۔ اگر آپ اسے محفوظ کرتے ہیں تو اس صفحے کے اس پرانے مسودے سے اب تک کی جانے والی تمام تدوین ضائع ہو جاۓ گی۔'''",
'yourdiff' => 'تضادات',
'copyrightwarning' => "یہ یادآوری کرلیجیۓ کہ {{SITENAME}} میں تمام تحریری شراکت جی این یو آزاد مسوداتی اجازہ ($2)کے تحت تصور کی جاتی ہے (مزید تفصیل کیلیۓ $1 دیکھیۓ)۔ اگر آپ اس بات سے متفق نہیں کہ آپکی تحریر میں ترمیمات کری جائیں اور اسے آزادانہ (جیسے ضرورت ہو) استعمال کیا جاۓ تو براۓ کرم اپنی تصانیف یہاں داخل نہ کیجیۓ۔ اگر آپ یہاں اپنی تحریر جمع کراتے ہیں تو آپ اس بات کا بھی اقرار کر رہے ہیں کہ، اسے آپ نے خود تصنیف کیا ہے یا دائرہ ءعام (پبلک ڈومین) سے حاصل کیا ہے یا اس جیسے کسی اور آذاد وسیلہ سے۔'''بلااجازت ایسا کام داخل نہ کیجیۓ جسکا حق ِطبع و نشر محفوظ ہو!'''",
'edit-already-exists' => 'نیا صفحہ تخلیق نہیں کیا جاسکتا.
یہ پہلے سے موجود ہے.',
+# Content models
+'content-model-text' => 'سادہ متن',
+'content-model-javascript' => 'جاوا اسکرپٹ',
+
# History pages
'viewpagelogs' => 'اس صفحہ کیلیے نوشتہ جات دیکھیے',
'nohistory' => 'اِس صفحہ کیلئے کوئی تدوینی تاریخچہ موجود نہیں ہے.',
# Diffs
'history-title' => '"$1" کا نظرثانی تاریخچہ',
+'difference-multipage' => '(فرق مابین صفحات)',
'lineno' => 'لکیر $1:',
'compareselectedversions' => 'منتخب متـن کا موازنہ',
'editundo' => 'استرجع',
'powersearch-ns' => 'جائے نام میں تلاش:',
'powersearch-redir' => 'فہرستِ رجوع مکرر',
'powersearch-field' => 'تلاش برائے',
+'powersearch-togglelabel' => 'جانچ',
'powersearch-toggleall' => 'تمام',
'powersearch-togglenone' => 'کوئی نہیں',
'search-external' => 'بیرونی تلاش',
'skin-preview' => 'پیش منظر',
'datedefault' => 'کوئی ترجیحات نہیں',
'prefs-datetime' => 'تاریخ و وقت',
+'prefs-user-pages' => 'صارف صفحات',
'prefs-personal' => 'نمایۂ صارف',
'prefs-rc' => 'حالیہ تبدیلیاں',
'prefs-watchlist' => 'زیرِنظر فہرست',
'rows' => 'صفیں:',
'columns' => 'قطاریں:',
'searchresultshead' => 'تلاش',
+'stub-threshold-disabled' => 'غیر فعال',
'recentchangesdays' => 'حالیہ تبدیلیوں میں دکھائی جانے والے ایّام:',
'recentchangesdays-max' => '(زیادہ سے زیادہ $1 {{PLURAL:$1|دن|ایام}})',
'recentchangescount' => 'دکھائی جانے والی ترامیم کی تعداد:',
'prefs-i18n' => 'بین الاقوامیت',
'prefs-signature' => 'دستخط',
'prefs-dateformat' => 'شکلبندِ تاریخ',
+'prefs-advancedediting' => 'اعلی اختیارات',
+'prefs-advancedrc' => 'اعلی اختیارات',
+'prefs-advancedrendering' => 'اعلی اختیارات',
+'prefs-advancedsearchoptions' => 'اعلی اختیارات',
+'prefs-advancedwatchlist' => 'اعلی اختیارات',
'prefs-diffs' => 'فروق',
# User rights
'grouppage-bot' => '{{ns:project}}:روبہ جات',
'grouppage-sysop' => '{{ns:project}}:منتظمین',
+# Rights
+'right-upload' => 'ملفات زبراثقال (اپ لوڈ) کریں',
+'right-delete' => 'صفحات حذف کریں',
+'right-sendemail' => 'دیگر صارفین کو برقی ڈاک بھیجیں',
+
# User rights log
'rightslog' => 'نوشتہ صارفی اختیارات',
'rightslogtext' => 'یہ صارفی اختیارات میں تبدیلیوں کا نوشتہ ہے۔',
'whatlinkshere-hideredirs' => 'رجوع مکررات $1',
'whatlinkshere-hidetrans' => 'تضمینات',
'whatlinkshere-hidelinks' => 'روابط $1',
-'whatlinkshere-hideimages' => 'روابطِ تصویر $1',
+'whatlinkshere-hideimages' => 'روابطِ تصاویر $1',
'whatlinkshere-filters' => 'فلٹرذ',
# Block/unblock
'newwindow' => '(yangi oynada ochiladi)',
'cancel' => 'Bekor qilish',
'moredotdotdot' => 'Batafsil...',
-'mypage' => 'Shaxsiy sahifa',
+'mypage' => 'Sahifa',
'mytalk' => 'Suhbatim',
'anontalk' => 'Bu IP uchun suhbat',
'navigation' => 'Saytda harakatlanish',
'whatlinkshere-hideredirs' => "$1 qayta yo'naltirishlar",
'whatlinkshere-hidetrans' => '$1 kiritmalar',
'whatlinkshere-hidelinks' => '$1 havolalar',
-'whatlinkshere-hideimages' => '$1 rasmlar uchun havolalar',
+'whatlinkshere-hideimages' => '$1 fayllar uchun havolalar',
'whatlinkshere-filters' => 'Filtrlar',
# Block/unblock
'underline-always' => 'Luôn luôn',
'underline-never' => 'Không bao giờ',
-'underline-default' => 'Mặc định của trình duyệt',
+'underline-default' => 'Mặc định của hình dạng hoặc trình duyệt',
# Font style option in Special:Preferences
'editfont-style' => 'Kiểu phông chữ trong khung sửa đổi:',
'newwindow' => '(mở cửa sổ mới)',
'cancel' => 'Hủy bỏ',
'moredotdotdot' => 'Thêm nữa…',
-'mypage' => 'Trang của tôi',
-'mytalk' => 'Thảo luận với tôi',
+'mypage' => 'Trang cá nhân',
+'mytalk' => 'Thảo luận',
'anontalk' => 'Thảo luận với IP này',
'navigation' => 'Xem nhanh',
'and' => ' và',
'linksearch-pat' => 'Mẫu liên kết:',
'linksearch-ns' => 'Không gian tên:',
'linksearch-ok' => 'Tìm kiếm',
-'linksearch-text' => "Bạn có thể sử dụng ký tự đại diện (''wildcard''), ví dụ “*.wikipedia.org”; ít nhất phải có tên miền cấp cao nhất, thí dụ “*.org”.<br />Các giao thức này được hỗ trợ: <code>$1</code>; vui lòng không đưa giao thức vào truy vấn.",
+'linksearch-text' => "Bạn có thể sử dụng ký tự đại diện (''wildcard''), ví dụ “*.wikipedia.org”; ít nhất phải có tên miền cấp cao nhất, thí dụ “*.org”.<br />Các giao thức này được hỗ trợ: <code>$1</code>; mặc định là <code>http://</code> nếu không định rõ giao thức trong truy vấn.",
'linksearch-line' => '$1 được liên kết từ $2',
'linksearch-error' => "Chỉ được sử dụng ký tự đại diện (''wildcard'') vào đầu tên miền (''hostname'').",
# Watchlist
'watchlist' => 'Trang tôi theo dõi',
-'mywatchlist' => 'Trang tôi theo dõi',
+'mywatchlist' => 'Trang theo dõi',
'watchlistfor2' => 'Của $1 $2',
'nowatchlist' => 'Danh sách theo dõi của bạn không có gì.',
'watchlistanontext' => 'Xin hãy $1 để xem hay sửa đổi các trang được theo dõi.',
# Contributions
'contributions' => 'Đóng góp của thành viên',
'contributions-title' => 'Đóng góp của thành viên $1',
-'mycontris' => 'Đóng góp của tôi',
+'mycontris' => 'Đóng góp',
'contribsub2' => 'Của $1 ($2)',
'nocontribs' => 'Không tìm thấy thay đổi nào khớp với yêu cầu.',
'uctop' => '(mới nhất)',
'whatlinkshere-hideredirs' => '$1 trang đổi hướng',
'whatlinkshere-hidetrans' => '$1 trang nhúng',
'whatlinkshere-hidelinks' => '$1 liên kết',
-'whatlinkshere-hideimages' => '$1 liên kết hình',
+'whatlinkshere-hideimages' => '$1 liên kết tập tin',
'whatlinkshere-filters' => 'Bộ lọc',
# Block/unblock
'exif-compression-3' => 'CCITT Nhóm 3: mã hóa fax',
'exif-compression-4' => 'CCITT Nhóm 4: mã hóa fax',
'exif-compression-6' => 'JPEG (cũ)',
+'exif-compression-34712' => 'JPEG 2000',
'exif-copyrighted-true' => 'Dưới bản quyền',
'exif-copyrighted-false' => 'Phạm vi công cộng',
'duration-centuries' => '$1 thế kỷ',
'duration-millennia' => '$1 thiên niên kỷ',
+# Unknown messages
+'mytalk-parenthetical' => 'thảo luận',
);
'cancel' => 'זיי מבטל',
'moredotdotdot' => 'נאך…',
'mypage' => 'מײַן בלאט',
-'mytalk' => '×\9eײַ×\9f ש×\9e×\95עס',
+'mytalk' => 'שמועס',
'anontalk' => 'דאס רעדן פון דעם IP',
'navigation' => 'נאַוויגאַציע',
'and' => ' און',
# Watchlist
'watchlist' => 'מיין אויפפַּאסונג ליסטע',
-'mywatchlist' => '×\9e×\99×\99×\9f ×\90×\95×\99פפַּ×\90ס×\95× ×\92 ×\9c×\99ס×\98×¢',
+'mywatchlist' => 'אויפפַּאסונג ליסטע',
'watchlistfor2' => 'פֿאַר $1 $2',
'nowatchlist' => 'איר האט נישט קיין שום בלעטער אין אייער אויפפַּאסונג ליסטע.',
'watchlistanontext' => 'ביטע $1 כדי צו זען אדער ענדערן בלעטער אין אייער אַכטגעבן ליסטע.',
# Contributions
'contributions' => "באניצער'ס בײַשטײַערונגען",
'contributions-title' => 'בײַשטײַערונגען פֿון באַניצער $1',
-'mycontris' => '×\9e×²Ö·× ×¢ ×\91ײַש×\98ײַער×\95× ×\92×¢×\9f',
+'mycontris' => 'בײַשטײַערונגען',
'contribsub2' => 'וועגן $1 ($2)',
'nocontribs' => 'נישט געטראפן קיין ענדערונגען צוזאמעגעפאסט מיט די קריטעריעס.',
'uctop' => '(לעצטע)',
'whatlinkshere-hideredirs' => '$1 ווײַטערפֿירונגען',
'whatlinkshere-hidetrans' => '$1 אַריבערשליסונגען',
'whatlinkshere-hidelinks' => '$1 פֿאַרבינדונגען',
-'whatlinkshere-hideimages' => '$1 ×\91×\99×\9c×\93ער פֿאַרבינדונגען',
+'whatlinkshere-hideimages' => '$1 ×\98עקע פֿאַרבינדונגען',
'whatlinkshere-filters' => 'פֿילטערס',
# Block/unblock
# Info page
'pageinfo-title' => 'אינפֿאָרמאַציע פֿאַר "$1"',
+'pageinfo-not-current' => 'קען ווייזן אינפארמאציע נאר פאר דער לויפיקער רעוויזיע.',
'pageinfo-header-basic' => 'גרונטלעכע אינפֿארמאַציע',
'pageinfo-header-edits' => '!רעדאַקטירן היסטאריע',
'pageinfo-header-restrictions' => 'בלאט באַשיצונג',
'pageinfo-length' => 'בלאט לענג (אין בייטן)',
'pageinfo-article-id' => 'בלאט נומער',
'pageinfo-robot-policy' => 'זוכמאשין סטאטוס',
+'pageinfo-robot-index' => 'אינדעקסירבאר',
+'pageinfo-robot-noindex' => 'נישט אינדעקסירבאר',
'pageinfo-views' => 'צאַל קוקן',
'pageinfo-watchers' => '!צאָל בלאט אויפֿפאַסער',
'pageinfo-redirects-name' => 'ווײַטערפירונגען צו דעם בלאט',
'exif-orientation' => 'אריענטאַציע',
'exif-samplesperpixel' => 'צאל קאמאפאנענטן',
'exif-planarconfiguration' => 'דאטן איינארדנונג',
+'exif-xresolution' => 'האריזאנטאלע רעזאלוציע',
+'exif-yresolution' => 'ווערטיקאלע רעזאלוציע',
+'exif-stripoffsets' => 'בילדדאטן פלאציר',
+'exif-rowsperstrip' => 'צאל שורות אין א שטרייף',
+'exif-stripbytecounts' => 'בייטן אין א קאמפרימירטן שטרייף',
'exif-jpeginterchangeformatlength' => 'בייטן פון JPEG דאטן',
'exif-datetime' => 'טעקע ענדערונג דאטע און צײַט',
'exif-imagedescription' => 'בילד טיטל',
'underline-always' => '总是使用',
'underline-never' => '从不使用',
-'underline-default' => '浏览器默认',
+'underline-default' => '浏览器默认设置',
# Font style option in Special:Preferences
'editfont-style' => '编辑区字体样式:',
'newwindow' => '(将于新窗口中打开)',
'cancel' => '取消',
'moredotdotdot' => '更多',
-'mypage' => '我的页面',
-'mytalk' => '我的讨论',
+'mypage' => '页面',
+'mytalk' => '讨论',
'anontalk' => '该IP地址的讨论',
'navigation' => '导航',
'and' => '和',
'vector-action-protect' => '保护',
'vector-action-undelete' => '恢复',
'vector-action-unprotect' => '更改保护',
-'vector-simplesearch-preference' => '启用简化搜索栏(仅适用Vector皮肤)',
+'vector-simplesearch-preference' => '启用简化搜索栏(仅Vector皮肤)',
'vector-view-create' => '创建',
'vector-view-edit' => '编辑',
'vector-view-history' => '查看历史',
'searcharticle' => '提交',
'history' => '页面历史',
'history_short' => '历史',
-'updatedmarker' => 'æ\88\91ä¸\8a次访é\97®ä»¥æ\9d¥ç\9a\84ä¿®æ\94¹',
+'updatedmarker' => 'æ\88\91ä¸\8a次访é\97®ä¹\8bå\90\8eç\9a\84æ\9b´æ\96°',
'printableversion' => '打印版本',
'permalink' => '永久链接',
'print' => '打印',
'edit-already-exists' => '不可以建立一个新页面。
它已经存在。',
'defaultmessagetext' => '默认消息文本',
+'content-failed-to-parse' => '未能将 $2 内容转换为 $1:$3',
'invalid-content-data' => '无效的内容数据',
+'content-not-allowed-here' => '[[$2]]页面上不允许“$1”内容',
# Content models
+'content-model-wikitext' => 'wiki语法',
'content-model-text' => '纯文本',
'content-model-javascript' => 'JavaScript',
'content-model-css' => 'CSS',
# Preferences page
'preferences' => '系统设置',
-'mypreferences' => '我的设置',
+'mypreferences' => '系统设置',
'prefs-edits' => '编辑数量:',
'prefsnologin' => '尚未登录',
'prefsnologintext' => '您必须先<span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} 登录]</span>才能设置个人参数。',
# Contributions
'contributions' => '用户贡献',
'contributions-title' => '$1的用户贡献',
-'mycontris' => '我的贡献',
+'mycontris' => '贡献记录',
'contribsub2' => '$1的贡献($2)',
'nocontribs' => '没有找到符合特征的更改。',
'uctop' => '(最后更改)',
'whatlinkshere-hideredirs' => '$1重定向',
'whatlinkshere-hidetrans' => '$1包含',
'whatlinkshere-hidelinks' => '$1链接',
-'whatlinkshere-hideimages' => '$1文件链接',
+'whatlinkshere-hideimages' => '$1个文件链接',
'whatlinkshere-filters' => '过滤器',
# Block/unblock
'pageinfo-subpages-value' => '$1 ($2个重定向;$3个非重定向)',
'pageinfo-firstuser' => '页面创建者',
'pageinfo-firsttime' => '页面创建日期',
-'pageinfo-lastuser' => '最近的编者',
+'pageinfo-lastuser' => '最后编辑',
'pageinfo-lasttime' => '最后编辑的日期',
'pageinfo-edits' => '总编辑次数',
'pageinfo-authors' => '不同编者总计',
'pageinfo-contentpage-yes' => '是',
'pageinfo-protect-cascading' => '从这里开始连锁保护',
'pageinfo-protect-cascading-yes' => '是',
+'pageinfo-protect-cascading-from' => '保护级联自',
# Skin names
'skinname-standard' => '标准',
'nextdiff' => '下一编辑→',
# Media information
-'mediawarning' => "'''警告''':该文件类型可能包含恶意代码。
-运行它可能对您的系统带来危险。",
+'mediawarning' => "'''警告''':该文件类型可能含有恶意代码。执行后你的系统可能受损。",
'imagemaxsize' => '图像大小限制:<br /><u>(文件描述页)</u>',
'thumbsize' => '缩略图大小:',
'widthheightpage' => '$1×$2,$3页',
'exif-worldregiondest' => '世界区域显示',
'exif-countrydest' => '所示的国家',
'exif-countrycodedest' => '国家代码',
-'exif-provinceorstatedest' => '省或状态显示',
+'exif-provinceorstatedest' => '省或州',
'exif-citydest' => '所示的城市',
'exif-sublocationdest' => '显示城市中的详细地点',
'exif-objectname' => '简称',
'api-error-unknown-error' => '内部错误:尝试上传文件时出错。',
'api-error-unknown-warning' => '未知的警告:$1',
'api-error-unknownerror' => '未知错误:$1。',
-'api-error-uploaddisabled' => '此wiki关闭了上传功能。',
-'api-error-verification-error' => '此文件可能已损坏,或有错误的扩展名。',
+'api-error-uploaddisabled' => '该wiki停用上传。',
+'api-error-verification-error' => '该文件可能损坏或扩展名错误。',
# Durations
'duration-seconds' => '$1秒',
'newwindow' => '(以新視窗開啟)',
'cancel' => '取消',
'moredotdotdot' => '更多...',
-'mypage' => '我的頁面',
-'mytalk' => '我的對話頁',
+'mypage' => '頁面',
+'mytalk' => '對話頁',
'anontalk' => '該IP的對話頁',
'navigation' => '導覽',
'and' => '和',
# Preferences page
'preferences' => '偏好設定',
-'mypreferences' => '我的偏好設定',
+'mypreferences' => '偏好設定',
'prefs-edits' => '編輯數量:',
'prefsnologin' => '還未登入',
'prefsnologintext' => '您必須先<span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} 登入]</span>才能設置個人參數。',
'linksearch-pat' => '搜尋網址:',
'linksearch-ns' => '名字空間:',
'linksearch-ok' => '搜尋',
-'linksearch-text' => '製作可以使用類似“*.wikipedia.org”的通配符。必須至少是頂級域名,例如“*.org”。<br />
-支持的協議:<code>$1</code>(不要包含在搜索中)。',
+'linksearch-text' => '可使用通配符,如“*.wikipedia.org”。至少需要一個頂級域名,例如“*.org”。<br />
+支持的協議:<code>$1</code>(若沒有指定協議,預設為http://)。',
'linksearch-line' => '$1 連自 $2',
'linksearch-error' => '萬用字元僅可在主機名稱的開頭使用。',
# Watchlist
'watchlist' => '監視列表',
-'mywatchlist' => '我的監視列表',
+'mywatchlist' => '監視列表',
'watchlistfor2' => '$1的監視列表 $2',
'nowatchlist' => '您的監視列表為空。',
'watchlistanontext' => '請$1以檢視或編輯您的監視列表。',
# Contributions
'contributions' => '用戶貢獻',
'contributions-title' => '$1的用戶貢獻',
-'mycontris' => '我的貢獻',
+'mycontris' => '貢獻',
'contribsub2' => '$1的貢獻 ($2)',
'nocontribs' => '沒有找到符合特徵的更改。',
'uctop' => '(最新修改)',
+++ /dev/null
-<?php
-/**
- * Check the autoloader
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Maintenance
- */
-
-require_once( __DIR__ . '/Maintenance.php' );
-
-/**
- * Maintenance script to check classes definitions in the autoloader.
- *
- * @ingroup Maintenance
- */
-class CheckAutoLoader extends Maintenance {
- public function __construct() {
- parent::__construct();
- $this->mDescription = "AutoLoader sanity checks";
- }
- public function execute() {
- global $wgAutoloadLocalClasses, $IP;
- $files = array_unique( $wgAutoloadLocalClasses );
-
- foreach ( $files as $file ) {
- if ( function_exists( 'parsekit_compile_file' ) ) {
- $parseInfo = parsekit_compile_file( "$IP/$file" );
- $classes = array_keys( $parseInfo['class_table'] );
- } else {
- $contents = file_get_contents( "$IP/$file" );
- $m = array();
- preg_match_all( '/\n\s*class\s+([a-zA-Z0-9_]+)/', $contents, $m, PREG_PATTERN_ORDER );
- $classes = $m[1];
- }
- foreach ( $classes as $class ) {
- if ( !isset( $wgAutoloadLocalClasses[$class] ) ) {
- // printf( "%-50s Unlisted, in %s\n", $class, $file );
- $this->output( "\t'$class' => '$file',\n" );
- } elseif ( $wgAutoloadLocalClasses[$class] !== $file ) {
- $this->output( "$class: Wrong file: found in $file, listed in " . $wgAutoloadLocalClasses[$class] . "\n" );
- }
- }
- }
- }
-}
-
-$maintClass = "CheckAutoLoader";
-require_once( RUN_MAINTENANCE_IF_MAIN );
public function execute() {
global $wgMemc;
+
$type = $this->getOption( 'type', false );
- $memcKey = 'jobqueue:dbs:v2';
- $pendingDBs = $wgMemc->get( $memcKey );
+ $memcKey = 'jobqueue:dbs:v3';
+ $pendingDbInfo = $wgMemc->get( $memcKey );
// If the cache entry wasn't present, or in 1% of cases otherwise,
- // regenerate the cache.
- if ( !$pendingDBs || mt_rand( 0, 100 ) == 0 ) {
- $pendingDBs = $this->getPendingDbs();
- $wgMemc->set( $memcKey, $pendingDBs, 300 );
+ // regenerate the cache. Use any available stale cache if another
+ // process is currently regenerating the pending DB information.
+ if ( !$pendingDbInfo || mt_rand( 0, 100 ) == 0 ) {
+ $lock = $wgMemc->add( 'jobqueue:dbs:v3:lock', 1, 1800 ); // lock
+ if ( $lock ) {
+ $pendingDbInfo = array(
+ 'pendingDBs' => $this->getPendingDbs(),
+ 'timestamp' => time()
+ );
+ $wgMemc->set( $memcKey, $pendingDbInfo );
+ $wgMemc->delete( 'jobqueue:dbs:v3:lock' ); // unlock
+ }
}
- if ( !$pendingDBs ) {
- return;
+ if ( !$pendingDbInfo || !$pendingDbInfo['pendingDBs'] ) {
+ return; // no DBs with jobs or cache is both empty and locked
}
+ $pendingDBs = $pendingDbInfo['pendingDBs'];
do {
$again = false;
* @return bool
*/
function checkJob( $type, $dbName ) {
- global $wgJobTypesExcludedFromDefaultQueue;
-
+ $group = JobQueueGroup::singleton( $dbName );
if ( $type === false ) {
- $lb = wfGetLB( $dbName );
- $db = $lb->getConnection( DB_MASTER, array(), $dbName );
- $conds = array();
- if ( count( $wgJobTypesExcludedFromDefaultQueue ) > 0 ) {
- foreach ( $wgJobTypesExcludedFromDefaultQueue as $cmdType ) {
- $conds[] = "job_cmd != " . $db->addQuotes( $cmdType );
+ foreach ( $group->getDefaultQueueTypes() as $type ) {
+ if ( !$group->get( $type )->isEmpty() ) {
+ return true;
}
}
- $exists = (bool)$db->selectField( 'job', '1', $conds, __METHOD__ );
- $lb->reuseConnection( $db );
+ return false;
} else {
- $exists = !JobQueueGroup::singleton( $dbName )->get( $type )->isEmpty();
+ return !$group->get( $type )->isEmpty();
}
-
- return $exists;
}
/**
*/
private function getPendingDbs() {
global $wgLocalDatabases;
- $pendingDBs = array();
- # Cross-reference DBs by master DB server
- $dbsByMaster = array();
- foreach ( $wgLocalDatabases as $db ) {
- $lb = wfGetLB( $db );
- $dbsByMaster[$lb->getServerName( 0 )][] = $db;
- }
-
- foreach ( $dbsByMaster as $dbs ) {
- $dbConn = wfGetDB( DB_MASTER, array(), $dbs[0] );
- # Padding row for MySQL bug
- $pad = str_repeat( '-', 40 );
- $sql = "(SELECT '$pad' as db, '$pad' as job_cmd)";
- foreach ( $dbs as $wikiId ) {
- if ( $sql != '' ) {
- $sql .= ' UNION ';
- }
-
- list( $dbName, $tablePrefix ) = wfSplitWikiID( $wikiId );
- $dbConn->tablePrefix( $tablePrefix );
- $jobTable = $dbConn->tableName( 'job' );
-
- $sql .= "(SELECT DISTINCT '$wikiId' as db, job_cmd FROM $dbName.$jobTable GROUP BY job_cmd)";
- }
- $res = $dbConn->query( $sql, __METHOD__ );
- $first = true;
- foreach ( $res as $row ) {
- if ( $first ) {
- // discard padding row
- $first = false;
- continue;
- }
- $pendingDBs[$row->job_cmd][] = $row->db;
+ $pendingDBs = array(); // (job type => (db list))
+ foreach ( $wgLocalDatabases as $db ) {
+ $types = JobQueueGroup::singleton( $db )->getQueuesWithJobs();
+ foreach ( $types as $type ) {
+ $pendingDBs[$type][] = $db;
}
}
+
return $pendingDBs;
}
}
.mw-badge {
- min-width: 8px;
- height: 14px;
- border: 1px solid white;
- -moz-border-radius: 8px;
- -webkit-border-radius: 8px;
- border-radius: 8px;
+ min-width: 7px;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
-moz-box-shadow: 0px 1px 4px #ccc;
-webkit-box-shadow: 0px 1px 4px #ccc;
box-shadow: 0px 1px 4px #ccc;
- background-color: #b60a00;
- background-image: -o-linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
- background-image: -moz-linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
- background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #a70802), color-stop(1, #cf0e00));
- background-image: -webkit-linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
- background-image: -ms-linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
- background-image: linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
+ background-color: #cc0000;
padding: 0 3px;
text-align: center;
+ font-size: 12px;
+ line-height: 12px;
}
.mw-badge-content {
- font-size: 12px;
- line-height: 14px;
+ font-weight: bold;
color: white;
- vertical-align: top;
+ vertical-align: baseline;
+ text-shadow: 0 1px rgba(0, 0, 0, 0.4);
}
.mw-badge-inline {
/**
* jQuery Badge plugin
*
- * Based on Badger plugin by Daniel Raftery (http://thrivingkings.com/badger).
- *
* @license MIT
*/
* This program is distributed WITHOUT ANY WARRANTY.
*/
( function ( $ ) {
-
/**
- * Allows you to put a numeric "badge" on an item on the page.
+ * Allows you to put a "badge" on an item on the page. The badge container
+ * will be appended to the selected element(s).
* See mediawiki.org/wiki/ResourceLoader/Default_modules#jQuery.badge
*
- * @param {string|number} badgeCount An explicit number, or "+n"/ "-n"
- * to modify the existing value. If the new value is equal or lower than 0,
- * any existing badge will be removed. The badge container will be appended
- * to the selected element(s).
- * @param {Object} options Optional parameters specified below
- * type: 'inline' or 'overlay' (default)
- * callback: will be called with the number now shown on the badge as a parameter
+ * @param text The value to display in the badge. If the value is falsey (0,
+ * null, false, '', etc.), any existing badge will be removed.
+ * @param boolean inline True if the badge should be displayed inline, false
+ * if the badge should overlay the parent element (default is inline)
*/
- $.fn.badge = function ( badgeCount, options ) {
- var $badge,
- oldBadgeCount,
- newBadgeCount,
- $existingBadge = this.find( '.mw-badge' );
-
- options = $.extend( { type : 'overlay' }, options );
-
- // If there is no existing badge, this will give an empty string
- oldBadgeCount = Number( $existingBadge.text() );
- if ( isNaN( oldBadgeCount ) ) {
- oldBadgeCount = 0;
- }
+ $.fn.badge = function ( text, inline ) {
+ var $badge = this.find( '.mw-badge' );
- // If badgeCount is a number, use that as the new badge
- if ( typeof badgeCount === 'number' ) {
- newBadgeCount = badgeCount;
- } else if ( typeof badgeCount === 'string' ) {
- // If badgeCount is "+x", add x to the old badge
- if ( badgeCount.charAt(0) === '+' ) {
- newBadgeCount = oldBadgeCount + Number( badgeCount.substr(1) );
- // If badgeCount is "-x", subtract x from the old badge
- } else if ( badgeCount.charAt(0) === '-' ) {
- newBadgeCount = oldBadgeCount - Number( badgeCount.substr(1) );
- // If badgeCount can be converted into a number, convert it
- } else if ( !isNaN( Number( badgeCount ) ) ) {
- newBadgeCount = Number( badgeCount );
+ if ( text ) {
+ // If a badge already exists, reuse it
+ if ( $badge.length ) {
+ $badge.find( '.mw-badge-content' ).text( text );
} else {
- newBadgeCount = 0;
+ // Otherwise, create a new badge with the specified text and style
+ $badge = $( '<div class="mw-badge mw-badge-' + ( inline ? 'inline' : 'overlay' ) + '"></div>' )
+ .append( $( '<span class="mw-badge-content"></span>' ).text ( text ) )
+ .appendTo( this );
}
- // Other types are not supported, fall back to 0.
- } else {
- newBadgeCount = 0;
- }
-
- // Badge count must be a whole number
- newBadgeCount = Math.round( newBadgeCount );
-
- if ( newBadgeCount <= 0 ) {
- // Badges should only exist for values > 0.
- $existingBadge.remove();
} else {
- // Don't add duplicates
- if ( $existingBadge.length ) {
- $badge = $existingBadge;
- // Insert the new count into the badge
- this.find( '.mw-badge-content' ).text( newBadgeCount );
- } else {
- // Contruct a new badge with the count
- $badge = $( '<div>' )
- .addClass( 'mw-badge' )
- .append(
- $( '<span>' )
- .addClass( 'mw-badge-content' )
- .text( newBadgeCount )
- );
- this.append( $badge );
- }
-
- if ( options.type === 'inline' ) {
- $badge
- .removeClass( 'mw-badge-overlay' )
- .addClass( 'mw-badge-inline' );
- // Default: overlay
- } else {
- $badge
- .removeClass( 'mw-badge-inline' )
- .addClass( 'mw-badge-overlay' );
-
- }
-
- // If a callback was specified, call it with the badge count
- if ( $.isFunction( options.callback ) ) {
- options.callback( newBadgeCount );
- }
+ $badge.remove();
}
+ return this;
};
}( jQuery ) );
/**
* jQuery checkboxShiftClick
*
- * This will enable checkboxes to be checked or unchecked in a row by clicking one, holding shift and clicking another one
+ * This will enable checkboxes to be checked or unchecked in a row by clicking one,
+ * holding shift and clicking another one.
*
- * @author Krinkle <krinklemail@gmail.com>
+ * @author Timo Tijhof, 2011 - 2012
* @license GPL v2
*/
( function ( $ ) {
- $.fn.checkboxShiftClick = function ( text ) {
- var prevCheckbox = null, $box = this;
+ $.fn.checkboxShiftClick = function () {
+ var prevCheckbox = null,
+ $box = this;
// When our boxes are clicked..
$box.click( function ( e ) {
// And one has been clicked before...
// Use the cached version if possible
if ( profileCache[nav.userAgent] === undefined ) {
- /* Configuration */
-
- // Name of browsers or layout engines we don't recognize
- var uk = 'unknown';
- // Generic version digit
- var x = 'x';
- // Strings found in user agent strings that need to be conformed
- var wildUserAgents = ['Opera', 'Navigator', 'Minefield', 'KHTML', 'Chrome', 'PLAYSTATION 3'];
- // Translations for conforming user agent strings
- var userAgentTranslations = [
- // Tons of browsers lie about being something they are not
- [/(Firefox|MSIE|KHTML,\slike\sGecko|Konqueror)/, ''],
- // Chrome lives in the shadow of Safari still
- ['Chrome Safari', 'Chrome'],
- // KHTML is the layout engine not the browser - LIES!
- ['KHTML', 'Konqueror'],
- // Firefox nightly builds
- ['Minefield', 'Firefox'],
- // This helps keep differnt versions consistent
- ['Navigator', 'Netscape'],
- // This prevents version extraction issues, otherwise translation would happen later
- ['PLAYSTATION 3', 'PS3']
- ];
- // Strings which precede a version number in a user agent string - combined and used as match 1 in
- // version detectection
- var versionPrefixes = [
- 'camino', 'chrome', 'firefox', 'netscape', 'netscape6', 'opera', 'version', 'konqueror',
- 'lynx', 'msie', 'safari', 'ps3'
- ];
- // Used as matches 2, 3 and 4 in version extraction - 3 is used as actual version number
- var versionSuffix = '(\\/|\\;?\\s|)([a-z0-9\\.\\+]*?)(\\;|dev|rel|\\)|\\s|$)';
- // Names of known browsers
- var names = [
- 'camino', 'chrome', 'firefox', 'netscape', 'konqueror', 'lynx', 'msie', 'opera',
- 'safari', 'ipod', 'iphone', 'blackberry', 'ps3', 'rekonq'
- ];
- // Tanslations for conforming browser names
- var nameTranslations = [];
- // Names of known layout engines
- var layouts = ['gecko', 'konqueror', 'msie', 'opera', 'webkit'];
- // Translations for conforming layout names
- var layoutTranslations = [['konqueror', 'khtml'], ['msie', 'trident'], ['opera', 'presto']];
- // Names of supported layout engines for version number
- var layoutVersions = ['applewebkit', 'gecko'];
- // Names of known operating systems
- var platforms = ['win', 'mac', 'linux', 'sunos', 'solaris', 'iphone'];
- // Translations for conforming operating system names
- var platformTranslations = [['sunos', 'solaris']];
-
- /* Methods */
-
- /**
- * Performs multiple replacements on a string
- */
- var translate = function ( source, translations ) {
- var i;
- for ( i = 0; i < translations.length; i++ ) {
- source = source.replace( translations[i][0], translations[i][1] );
- }
- return source;
- };
-
- /* Pre-processing */
-
- var ua = nav.userAgent,
+ var
+ versionNumber,
+
+ /* Configuration */
+
+ // Name of browsers or layout engines we don't recognize
+ uk = 'unknown',
+ // Generic version digit
+ x = 'x',
+ // Strings found in user agent strings that need to be conformed
+ wildUserAgents = ['Opera', 'Navigator', 'Minefield', 'KHTML', 'Chrome', 'PLAYSTATION 3'],
+ // Translations for conforming user agent strings
+ userAgentTranslations = [
+ // Tons of browsers lie about being something they are not
+ [/(Firefox|MSIE|KHTML,\slike\sGecko|Konqueror)/, ''],
+ // Chrome lives in the shadow of Safari still
+ ['Chrome Safari', 'Chrome'],
+ // KHTML is the layout engine not the browser - LIES!
+ ['KHTML', 'Konqueror'],
+ // Firefox nightly builds
+ ['Minefield', 'Firefox'],
+ // This helps keep differnt versions consistent
+ ['Navigator', 'Netscape'],
+ // This prevents version extraction issues, otherwise translation would happen later
+ ['PLAYSTATION 3', 'PS3']
+ ],
+ // Strings which precede a version number in a user agent string - combined and used as match 1 in
+ // version detectection
+ versionPrefixes = [
+ 'camino', 'chrome', 'firefox', 'netscape', 'netscape6', 'opera', 'version', 'konqueror',
+ 'lynx', 'msie', 'safari', 'ps3'
+ ],
+ // Used as matches 2, 3 and 4 in version extraction - 3 is used as actual version number
+ versionSuffix = '(\\/|\\;?\\s|)([a-z0-9\\.\\+]*?)(\\;|dev|rel|\\)|\\s|$)',
+ // Names of known browsers
+ names = [
+ 'camino', 'chrome', 'firefox', 'netscape', 'konqueror', 'lynx', 'msie', 'opera',
+ 'safari', 'ipod', 'iphone', 'blackberry', 'ps3', 'rekonq'
+ ],
+ // Tanslations for conforming browser names
+ nameTranslations = [],
+ // Names of known layout engines
+ layouts = ['gecko', 'konqueror', 'msie', 'opera', 'webkit'],
+ // Translations for conforming layout names
+ layoutTranslations = [ ['konqueror', 'khtml'], ['msie', 'trident'], ['opera', 'presto'] ],
+ // Names of supported layout engines for version number
+ layoutVersions = ['applewebkit', 'gecko'],
+ // Names of known operating systems
+ platforms = ['win', 'mac', 'linux', 'sunos', 'solaris', 'iphone'],
+ // Translations for conforming operating system names
+ platformTranslations = [ ['sunos', 'solaris'] ],
+
+ /* Methods */
+
+ /**
+ * Performs multiple replacements on a string
+ */
+ translate = function ( source, translations ) {
+ var i;
+ for ( i = 0; i < translations.length; i++ ) {
+ source = source.replace( translations[i][0], translations[i][1] );
+ }
+ return source;
+ },
+
+ /* Pre-processing */
+
+ ua = nav.userAgent,
match,
name = uk,
layout = uk,
if ( name === 'opera' && version >= 9.8) {
version = ua.match( /version\/([0-9\.]*)/i )[1] || 10;
}
- var versionNumber = parseFloat( version, 10 ) || 0.0;
+ versionNumber = parseFloat( version, 10 ) || 0.0;
/* Caching */
* @return Boolean true if browser known or assumed to be supported, false if blacklisted
*/
test: function ( map, profile ) {
- /*jshint evil:true */
+ /*jshint evil: true */
var conditions, dir, i, op, val;
profile = $.isPlainObject( profile ) ? profile : $.client.profile();
}
return $settings;
},
- handleResize: function ( e ) {
+ /**
+ * @param {jQuery.Event} e
+ */
+ handleResize: function () {
$.collapsibleTabs.instances.each( function () {
var $el = $( this ),
data = $.collapsibleTabs.getSettings( $el );
* @return Array The HSL representation
*/
rgbToHsl: function ( R, G, B ) {
- var r = R / 255,
+ var d,
+ r = R / 255,
g = G / 255,
- b = B / 255;
- var max = Math.max( r, g, b ), min = Math.min( r, g, b );
- var h, s, l = (max + min) / 2;
+ b = B / 255,
+ max = Math.max( r, g, b ), min = Math.min( r, g, b ),
+ h,
+ s,
+ l = (max + min) / 2;
if ( max === min ) {
// achromatic
h = s = 0;
} else {
- var d = max - min;
+ d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch ( max ) {
case r:
* @return Array The RGB representation
*/
hslToRgb: function ( h, s, l ) {
- var r, g, b;
+ var r, g, b, hue2rgb, q, p;
if ( s === 0 ) {
r = g = b = l; // achromatic
} else {
- var hue2rgb = function ( p, q, t ) {
+ hue2rgb = function ( p, q, t ) {
if ( t < 0 ) {
t += 1;
}
return p;
};
- var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
- var p = 2 * l - q;
+ q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+ p = 2 * l - q;
r = hue2rgb( p, q, h + 1/3 );
g = hue2rgb( p, q, h );
b = hue2rgb( p, q, h - 1/3 );
context = {
config: {
// callback function for before collapse
- beforeCondense: function ( context ) {},
+ beforeCondense: function () {},
// callback function for before expand
- beforeExpand: function ( context ) {},
+ beforeExpand: function () {},
// callback function for after collapse
- afterCondense: function ( context ) {},
+ afterCondense: function () {},
// callback function for after expand
- afterExpand: function ( context ) {},
+ afterExpand: function () {},
// Whether the field should expand to the left or the right -- defaults to left
expandToLeft: true
if ( bits.length > 1 && bits[1].charAt( bits[1].length - 1 ) === 'x' ) {
ratioStr = bits[1].substr( 0, bits[1].length - 1 );
ratio = parseFloat( ratioStr );
- if ( ratio > devicePixelRatio ) {
- // Too big, skip!
- } else if ( ratio > selectedRatio ) {
+ if ( ratio <= devicePixelRatio && ratio > selectedRatio ) {
selectedRatio = ratio;
selectedSrc = src;
}
// non latin characters can make regex think a new word has begun: do not use \b
// http://stackoverflow.com/questions/3787072/regex-wordwrap-with-utf8-characters-in-js
// look for an occurrence of our pattern and store the starting position
- match = node.data.match( new RegExp( "(^|\\s)" + $.escapeRE( pat ), "i" ) );
+ match = node.data.match( new RegExp( '(^|\\s)' + $.escapeRE( pat ), 'i' ) );
if ( match ) {
pos = match.index + match[1].length; // include length of any matched spaces
// create the span wrapper for the matched text
/**
* JavaScript to show jump links to motor-impaired users when they are focused.
*/
-jQuery( function( $ ) {
+jQuery( function ( $ ) {
- $('.mw-jump').delegate( 'a', 'focus blur', function( e ) {
- // Confusingly jQuery leaves e.type as "focusout" for delegated blur events
- if ( e.type === "blur" || e.type === "focusout" ) {
- $( this ).closest( '.mw-jump' ).css({ height: '0' });
+ $( '.mw-jump' ).on( 'focus blur', 'a', function ( e ) {
+ // Confusingly jQuery leaves e.type as focusout for delegated blur events
+ if ( e.type === 'blur' || e.type === 'focusout' ) {
+ $( this ).closest( '.mw-jump' ).css({ height: 0 });
} else {
$( this ).closest( '.mw-jump' ).css({ height: 'auto' });
}
return str.charAt( 0 ).toUpperCase() + str.substr( 1 );
},
escapeRE: function ( str ) {
- return str.replace ( /([\\{}()|.?*+\-\^$\[\]])/g, "\\$1" );
+ return str.replace ( /([\\{}()|.?*+\-\^$\[\]])/g, '\\$1' );
},
isDomElement: function ( el ) {
return !!el && !!el.nodeType;
},
isEmpty: function ( v ) {
+ var key;
if ( v === '' || v === 0 || v === '0' || v === null
|| v === false || v === undefined )
{
return true;
}
if ( typeof v === 'object' ) {
- for ( var key in v ) {
+ for ( key in v ) {
return false;
}
return true;
/*global jQuery, QUnit */
/*jshint eqeqeq:false, eqnull:false, forin:false */
( function ( $ ) {
- "use strict";
+ 'use strict';
var util,
hasOwn = Object.prototype.hasOwnProperty,
*
* Options:
*
- * fetch(query): Callback that should fetch suggestions and set the suggestions property. Executed in the context of the
- * textbox
+ * fetch(query): Callback that should fetch suggestions and set the suggestions property.
+ * Executed in the context of the textbox
* Type: Function
- * cancel: Callback function to call when any pending asynchronous suggestions fetches should be canceled.
- * Executed in the context of the textbox
+ * cancel: Callback function to call when any pending asynchronous suggestions fetches
+ * should be canceled. Executed in the context of the textbox
* Type: Function
* special: Set of callbacks for rendering and selecting
* Type: Object of Functions 'render' and 'select'
* Type: Number, Range: 0 - 1200, Default: 120
* submitOnClick: Whether to submit the form containing the textbox when a suggestion is clicked
* Type: Boolean, Default: false
- * maxExpandFactor: Maximum suggestions box width relative to the textbox width. If set to e.g. 2, the suggestions box
- * will never be grown beyond 2 times the width of the textbox.
+ * maxExpandFactor: Maximum suggestions box width relative to the textbox width. If set
+ * to e.g. 2, the suggestions box will never be grown beyond 2 times the width of the textbox.
* Type: Number, Range: 1 - infinity, Default: 3
* expandFrom: Which direction to offset the suggestion box from.
- * Values 'start' and 'end' translate to left and right respectively depending on the directionality
- * of the current document, according to $( 'html' ).css( 'direction' ).
+ * Values 'start' and 'end' translate to left and right respectively depending on the
+ * directionality of the current document, according to $( 'html' ).css( 'direction' ).
* Type: String, default: 'auto', options: 'left', 'right', 'start', 'end', 'auto'.
* positionFromLeft: Sets expandFrom=left, for backwards compatibility
* Type: Boolean, Default: true
context.config.cancel.call( context.data.$textbox );
}
},
+
/**
- * Restore the text the user originally typed in the textbox, before it was overwritten by highlight(). This
- * restores the value the currently displayed suggestions are based on, rather than the value just before
+ * Restore the text the user originally typed in the textbox, before it
+ * was overwritten by highlight(). This restores the value the currently
+ * displayed suggestions are based on, rather than the value just before
* highlight() overwrote it; the former is arguably slightly more sensible.
*/
restore: function ( context ) {
context.data.$textbox.val( context.data.prevText );
},
+
/**
- * Ask the user-specified callback for new suggestions. Any previous delayed call to this function still pending
- * will be canceled. If the value in the textbox is empty or hasn't changed since the last time suggestions were fetched, this
- * function does nothing.
+ * Ask the user-specified callback for new suggestions. Any previous delayed
+ * call to this function still pending will be canceled. If the value in the
+ * textbox is empty or hasn't changed since the last time suggestions were fetched,
+ * this function does nothing.
* @param {Boolean} delayed Whether or not to delay this by the currently configured amount of time
*/
update: function ( context, delayed ) {
}
$.suggestions.special( context );
},
+
special: function ( context ) {
// Allow custom rendering - but otherwise don't do any rendering
if ( typeof context.config.special.render === 'function' ) {
}, 1 );
}
},
+
/**
* Sets the value of a property, and updates the widget accordingly
* @param property String Name of property
* @param value Mixed Value to set property with
*/
configure: function ( context, property, value ) {
- var newCSS;
+ var newCSS,
+ $autoEllipseMe, $result, $results, $span,
+ i, expWidth, matchedText, maxWidth, text;
+
// Validate creation using fallback values
switch( property ) {
case 'fetch':
}
context.data.$container.css( newCSS );
- var $results = context.data.$container.children( '.suggestions-results' );
+ $results = context.data.$container.children( '.suggestions-results' );
$results.empty();
- var expWidth = -1;
- var $autoEllipseMe = $( [] );
- var matchedText = null;
- for ( var i = 0; i < context.config.suggestions.length; i++ ) {
+ expWidth = -1;
+ $autoEllipseMe = $( [] );
+ matchedText = null;
+ for ( i = 0; i < context.config.suggestions.length; i++ ) {
/*jshint loopfunc:true */
- var text = context.config.suggestions[i];
- var $result = $( '<div>' )
+ text = context.config.suggestions[i];
+ $result = $( '<div>' )
.addClass( 'suggestions-result' )
.attr( 'rel', i )
.data( 'text', context.config.suggestions[i] )
- .mousemove( function ( e ) {
+ .mousemove( function () {
context.data.selectedWithMouse = true;
$.suggestions.highlight(
- context, $(this).closest( '.suggestions-results div' ), false
+ context,
+ $(this).closest( '.suggestions-results div' ),
+ false
);
} )
.appendTo( $results );
// Widen results box if needed
// New width is only calculated here, applied later
- var $span = $result.children( 'span' );
+ $span = $result.children( 'span' );
if ( $span.outerWidth() > $result.width() && $span.outerWidth() > expWidth ) {
// factor in any padding, margin, or border space on the parent
expWidth = $span.outerWidth() + ( context.data.$container.width() - $span.parent().width());
}
// Apply new width for results box, if any
if ( expWidth > context.data.$container.width() ) {
- var maxWidth = context.config.maxExpandFactor*context.data.$textbox.width();
+ maxWidth = context.config.maxExpandFactor*context.data.$textbox.width();
context.data.$container.width( Math.min( expWidth, maxWidth ) );
}
// autoEllipse the results. Has to be done after changing the width
- $autoEllipseMe.autoEllipsis( { hasSpan: true, tooltip: true, matchText: matchedText } );
+ $autoEllipseMe.autoEllipsis( {
+ hasSpan: true,
+ tooltip: true,
+ matchText: matchedText
+ } );
}
}
break;
break;
}
},
+
/**
* Highlight a result in the results table
* @param result <tr> to highlight: jQuery object, or 'prev' or 'next'
context.data.$textbox.trigger( 'change' );
}
},
+
/**
* Respond to keypress event
* @param key Integer Code of key pressed
*/
keypress: function ( e, context, key ) {
- var wasVisible = context.data.$container.is( ':visible' ),
+ var selected,
+ wasVisible = context.data.$container.is( ':visible' ),
preventDefault = false;
+
switch ( key ) {
// Arrow down
case 40:
case 13:
context.data.$container.hide();
preventDefault = wasVisible;
- var selected = context.data.$container.find( '.suggestions-result-current' );
+ selected = context.data.$container.find( '.suggestions-result-current' );
if ( selected.length === 0 || context.data.selectedWithMouse ) {
// if nothing is selected OR if something was selected with the mouse,
// cancel any current requests and submit the form
if ( context === undefined || context === null ) {
context = {
config: {
- 'fetch' : function () {},
- 'cancel': function () {},
- 'special': {},
- 'result': {},
- '$region': $(this),
- 'suggestions': [],
- 'maxRows': 7,
- 'delay': 120,
- 'submitOnClick': false,
- 'maxExpandFactor': 3,
- 'expandFrom': 'auto',
- 'highlightInput': false
+ fetch: function () {},
+ cancel: function () {},
+ special: {},
+ result: {},
+ $region: $(this),
+ suggestions: [],
+ maxRows: 7,
+ delay: 120,
+ submitOnClick: false,
+ maxExpandFactor: 3,
+ expandFrom: 'auto',
+ highlightInput: false
}
};
}
.addClass( 'suggestions' )
.append(
$( '<div>' ).addClass( 'suggestions-results' )
- // Can't use click() because the container div is hidden when the textbox loses focus. Instead,
- // listen for a mousedown followed by a mouseup on the same div
+ // Can't use click() because the container div is hidden when the
+ // textbox loses focus. Instead, listen for a mousedown followed
+ // by a mouseup on the same div.
.mousedown( function ( e ) {
context.data.mouseDownOn = $( e.target ).closest( '.suggestions-results div' );
} )
.mouseup( function ( e ) {
- var $result = $( e.target ).closest( '.suggestions-results div' );
- var $other = context.data.mouseDownOn;
+ var $result = $( e.target ).closest( '.suggestions-results div' ),
+ $other = context.data.mouseDownOn;
+
context.data.mouseDownOn = $( [] );
if ( $result.get( 0 ) !== $other.get( 0 ) ) {
return;
)
.append(
$( '<div>' ).addClass( 'suggestions-special' )
- // Can't use click() because the container div is hidden when the textbox loses focus. Instead,
- // listen for a mousedown followed by a mouseup on the same div
+ // Can't use click() because the container div is hidden when the
+ // textbox loses focus. Instead, listen for a mousedown followed
+ // by a mouseup on the same div.
.mousedown( function ( e ) {
context.data.mouseDownOn = $( e.target ).closest( '.suggestions-special' );
} )
.mouseup( function ( e ) {
- var $special = $( e.target ).closest( '.suggestions-special' );
- var $other = context.data.mouseDownOn;
+ var $special = $( e.target ).closest( '.suggestions-special' ),
+ $other = context.data.mouseDownOn;
+
context.data.mouseDownOn = $( [] );
if ( $special.get( 0 ) !== $other.get( 0 ) ) {
return;
}
$.fn.textSelection = function ( command, options ) {
+ var fn,
+ context,
+ hasIframe,
+ needSave,
+ retval;
/**
* Helper function to get an IE TextRange object for an element
}
}
- var fn = {
+ fn = {
/**
* Get the contents of the textarea
*/
range2.collapse();
range2.moveStart( 'character', -1 );
// FIXME: Which check is correct?
- if ( range2.text !== "\r" && range2.text !== "\n" && range2.text !== "" ) {
- insertText = "\n" + insertText;
- pre += "\n";
+ if ( range2.text !== '\r' && range2.text !== '\n' && range2.text !== '' ) {
+ insertText = '\n' + insertText;
+ pre += '\n';
}
range3 = document.selection.createRange();
range3.collapse( false );
range3.moveEnd( 'character', 1 );
- if ( range3.text !== "\r" && range3.text !== "\n" && range3.text !== "" ) {
- insertText += "\n";
- post += "\n";
+ if ( range3.text !== '\r' && range3.text !== '\n' && range3.text !== '' ) {
+ insertText += '\n';
+ post += '\n';
}
}
insertText = doSplitLines( selText, pre, post );
}
if ( options.ownline ) {
- if ( startPos !== 0 && this.value.charAt( startPos - 1 ) !== "\n" && this.value.charAt( startPos - 1 ) !== "\r" ) {
- insertText = "\n" + insertText;
- pre += "\n";
+ if ( startPos !== 0 && this.value.charAt( startPos - 1 ) !== '\n' && this.value.charAt( startPos - 1 ) !== '\r' ) {
+ insertText = '\n' + insertText;
+ pre += '\n';
}
- if ( this.value.charAt( endPos ) !== "\n" && this.value.charAt( endPos ) !== "\r" ) {
- insertText += "\n";
- post += "\n";
+ if ( this.value.charAt( endPos ) !== '\n' && this.value.charAt( endPos ) !== '\r' ) {
+ insertText += '\n';
+ post += '\n';
}
}
this.value = this.value.substring( 0, startPos ) + insertText +
// Setting this.value scrolls the textarea to the top, restore the scroll position
this.scrollTop = scrollTop;
if ( window.opera ) {
- pre = pre.replace( /\r?\n/g, "\r\n" );
- selText = selText.replace( /\r?\n/g, "\r\n" );
- post = post.replace( /\r?\n/g, "\r\n" );
+ pre = pre.replace( /\r?\n/g, '\r\n' );
+ selText = selText.replace( /\r?\n/g, '\r\n' );
+ post = post.replace( /\r?\n/g, '\r\n' );
}
if ( isSample && options.selectPeri && !options.splitlines ) {
this.selectionStart = startPos + pre.length;
*/
getCaretPosition: function ( options ) {
function getCaret( e ) {
- var caretPos = 0, endPos = 0;
+ var caretPos = 0,
+ endPos = 0,
+ preText, rawPreText, periText,
+ rawPeriText, postText, rawPostText,
+ // IE Support
+ preFinished,
+ periFinished,
+ postFinished,
+ // Range containing text in the selection
+ periRange,
+ // Range containing text before the selection
+ preRange,
+ // Range containing text after the selection
+ postRange;
+
if ( document.selection && document.selection.createRange ) {
// IE doesn't properly report non-selected caret position through
// the selection ranges when textarea isn't focused. This can
// whatever we do later (bug 31847).
activateElementOnIE( e );
- var
- preText, rawPreText, periText,
- rawPeriText, postText, rawPostText,
-
- // IE Support
- preFinished = false,
- periFinished = false,
- postFinished = false,
- // Range containing text in the selection
- periRange = document.selection.createRange().duplicate(),
- // Range containing text before the selection
- preRange,
- // Range containing text after the selection
- postRange;
+ preFinished = false;
+ periFinished = false;
+ postFinished = false;
+ periRange = document.selection.createRange().duplicate();
preRange = rangeForElementIE( e ),
// Move the end where we need it
} else {
preRange.moveEnd( 'character', -1 );
if ( preRange.text === preText ) {
- rawPreText += "\r\n";
+ rawPreText += '\r\n';
} else {
preFinished = true;
}
} else {
periRange.moveEnd( 'character', -1 );
if ( periRange.text === periText ) {
- rawPeriText += "\r\n";
+ rawPeriText += '\r\n';
} else {
periFinished = true;
}
} else {
postRange.moveEnd( 'character', -1 );
if ( postRange.text === postText ) {
- rawPostText += "\r\n";
+ rawPostText += '\r\n';
} else {
postFinished = true;
}
}
}
} while ( ( !preFinished || !periFinished || !postFinished ) );
- caretPos = rawPreText.replace( /\r\n/g, "\n" ).length;
- endPos = caretPos + rawPeriText.replace( /\r\n/g, "\n" ).length;
+ caretPos = rawPreText.replace( /\r\n/g, '\n' ).length;
+ endPos = caretPos + rawPeriText.replace( /\r\n/g, '\n' ).length;
} else if ( e.selectionStart || e.selectionStart === 0 ) {
// Firefox support
caretPos = e.selectionStart;
return Math.floor( e.scrollWidth / ( $.client.profile().platform === 'linux' ? 7 : 8 ) );
}
function getCaretScrollPosition( e ) {
- var i, j;
// FIXME: This functions sucks and is off by a few lines most
// of the time. It should be replaced by something decent.
- var text = e.value.replace( /\r/g, '' );
- var caret = $( e ).textSelection( 'getCaretPosition' );
- var lineLength = getLineLength( e );
- var row = 0;
- var charInLine = 0;
- var lastSpaceInLine = 0;
+ var i, j,
+ nextSpace,
+ text = e.value.replace( /\r/g, '' ),
+ caret = $( e ).textSelection( 'getCaretPosition' ),
+ lineLength = getLineLength( e ),
+ row = 0,
+ charInLine = 0,
+ lastSpaceInLine = 0;
+
for ( i = 0; i < caret; i++ ) {
charInLine++;
if ( text.charAt( i ) === ' ' ) {
lastSpaceInLine = charInLine;
- } else if ( text.charAt( i ) === "\n" ) {
+ } else if ( text.charAt( i ) === '\n' ) {
lastSpaceInLine = 0;
charInLine = 0;
row++;
}
}
}
- var nextSpace = 0;
+ nextSpace = 0;
for ( j = caret; j < caret + lineLength; j++ ) {
if (
text.charAt( j ) === ' ' ||
- text.charAt( j ) === "\n" ||
+ text.charAt( j ) === '\n' ||
caret === text.length
) {
nextSpace = j;
break;
}
- var context = $(this).data( 'wikiEditor-context' );
- var hasIframe = typeof context !== 'undefined' && context && typeof context.$iframe !== 'undefined';
+ context = $(this).data( 'wikiEditor-context' );
+ hasIframe = context !== undefined && context && context.$iframe !== undefined;
// IE selection restore voodoo
- var needSave = false;
+ needSave = false;
if ( hasIframe && context.savedSelection !== null ) {
context.fn.restoreSelection();
needSave = true;
}
- var retval = ( hasIframe ? context.fn : fn )[command].call( this, options );
+ retval = ( hasIframe ? context.fn : fn )[command].call( this, options );
if ( hasIframe && needSave ) {
context.fn.saveSelection();
}
* Apply tagOpen/tagClose to selection in textarea,
* use sampleText instead of selection if there is none.
*/
- insertTags: function ( tagOpen, tagClose, sampleText, selectText ) {
+ insertTags: function ( tagOpen, tagClose, sampleText ) {
if ( currentFocused && currentFocused.length ) {
currentFocused.textSelection(
'encapsulateSelection', {
/*
** Diff rendering
*/
-table.diff, td.diff-otitle, td.diff-ntitle {
+table.diff {
background-color: white;
+ border: none;
+ border-spacing: 4px;
+ margin: 0;
+ width: 100%;
+ /* Ensure that colums are of equal width */
+ table-layout: fixed;
+}
+
+table.diff td {
+ padding: 0.33em 0.5em;
+}
+
+table.diff td.diff-marker {
+ /* Compensate padding for increased font-size */
+ padding: 0.25em;
+}
+
+table.diff col.diff-marker {
+ width: 2%;
+}
+
+table.diff col.diff-content {
+ width: 48%;
+}
+
+table.diff td div {
+ /* Force-wrap very long lines such as URLs or page-widening char strings */
+ word-wrap: break-word;
}
td.diff-otitle,
text-align: center;
}
-td.diff-marker {
- text-align: right;
+td.diff-lineno {
font-weight: bold;
- font-size: 1.25em;
}
-td.diff-lineno {
+td.diff-marker {
+ text-align: right;
font-weight: bold;
+ font-size: 1.25em;
}
td.diff-addedline,
vertical-align: top;
white-space: -moz-pre-wrap;
white-space: pre-wrap;
-}
-
-td.diff-addedline,
-td.diff-deletedline {
border-style: solid;
border-width: 1px 1px 1px 4px;
border-radius: 0.33em;
}
td.diff-context {
- background: #f3f3f3;
- color: #333333;
- border-style: solid;
- border-width: 1px 1px 1px 4px;
+ background: #f9f9f9;
border-color: #e6e6e6;
- border-radius: 0.33em;
+ color: #333333;
}
.diffchange {
text-decoration: none;
}
-table.diff {
- border: none;
- width: 98%;
- border-spacing: 4px;
-
- /* Ensure that colums are of equal width */
- table-layout: fixed;
-}
-
td.diff-addedline .diffchange,
td.diff-deletedline .diffchange {
border-radius: 0.33em;
td.diff-deletedline .diffchange {
background: #feeec8;
}
-
-table.diff td {
- padding: 0.33em 0.66em;
-}
-
-table.diff col.diff-marker {
- width: 2%;
-}
-
-table.diff col.diff-content {
- width: 48%;
-}
-
-table.diff td div {
- /* Force-wrap very long lines such as URLs or page-widening char strings.*/
- word-wrap: break-word;
-
- /* As fallback (FF<3.5, Opera <10.5), scrollbars will be added for very wide cells
- instead of text overflowing or widening
- */
- overflow: auto;
-}
/**
- * CLDR related utility methods
+ * CLDR related utility methods.
*/
-( function( mw ) {
- "use strict";
+( function ( mw ) {
+ 'use strict';
var cldr = {
/**
* In case none of the rules passed, we return pluralRules.length
* That means it is the "other" form.
* @param number
- * @param pluralRules
- * @return plural form index
+ * @param {Array} pluralRules
+ * @return {number} plural form index
*/
- getPluralForm: function( number, pluralRules ) {
- var pluralFormIndex = 0;
- for ( pluralFormIndex = 0; pluralFormIndex < pluralRules.length; pluralFormIndex++ ) {
- if ( mw.libs.pluralRuleParser( pluralRules[pluralFormIndex], number ) ) {
+ getPluralForm: function ( number, pluralRules ) {
+ var i;
+ for ( i = 0; i < pluralRules.length; i++ ) {
+ if ( mw.libs.pluralRuleParser( pluralRules[i], number ) ) {
break;
}
}
- return pluralFormIndex;
+ return i;
}
};
mw.cldr = cldr;
-} )( mediaWiki );
+
+}( mediaWiki ) );
* Base language object with methods for storing and getting
* language data.
*/
-( function ( mw, $ ) {
+( function ( mw ) {
var language = {
/**
mw.language = language;
-}( mediaWiki, jQuery ) );
+}( mediaWiki ) );
* @param forms array List of plural forms
* @return string Correct form for quantifier in this language
*/
- convertPlural: function( count, forms ) {
- var pluralFormIndex = 0;
+ convertPlural: function ( count, forms ) {
+ var pluralRules,
+ pluralFormIndex = 0;
+
if ( !forms || forms.length === 0 ) {
return '';
}
- var pluralRules = mw.language.getData( mw.config.get( 'wgUserLanguage' ), 'pluralRules' );
+ pluralRules = mw.language.getData( mw.config.get( 'wgUserLanguage' ), 'pluralRules' );
if ( !pluralRules ) {
// default fallback.
return ( count === 1 ) ? forms[0] : forms[1];
* @param {num} number Value to be converted
* @param {boolean} integer Convert the return value to an integer
*/
- convertNumber: function( num, integer ) {
- var i, tmp, transformTable;
+ convertNumber: function ( num, integer ) {
+ var i, tmp, transformTable, numberString, convertedNumber;
if ( !mw.language.digitTransformTable ) {
return num;
}
transformTable = tmp;
}
- var numberString = '' + num;
- var convertedNumber = '';
+ numberString = '' + num;
+ convertedNumber = '';
for ( i = 0; i < numberString.length; i++ ) {
if ( transformTable[ numberString[i] ] ) {
convertedNumber += transformTable[numberString[i]];
*
* @return string
*/
- gender: function( gender, forms ) {
+ gender: function ( gender, forms ) {
if ( !forms || forms.length === 0 ) {
return '';
}
-jQuery( document ).ready( function( $ ) {
+( function ( mw, $ ) {
+ $( function () {
+ var $sortableTables;
- /* Emulate placeholder if not supported by browser */
- if ( !( 'placeholder' in document.createElement( 'input' ) ) ) {
- $( 'input[placeholder]' ).placeholder();
- }
+ /* Emulate placeholder if not supported by browser */
+ if ( !( 'placeholder' in document.createElement( 'input' ) ) ) {
+ $( 'input[placeholder]' ).placeholder();
+ }
- /* Enable makeCollapsible */
- $( '.mw-collapsible' ).makeCollapsible();
+ /* Enable makeCollapsible */
+ $( '.mw-collapsible' ).makeCollapsible();
- /* Lazy load jquery.tablesorter */
- if ( $( 'table.sortable' ).length ) {
- mw.loader.using( 'jquery.tablesorter', function() {
- $( 'table.sortable' ).tablesorter();
- });
- }
+ /* Lazy load jquery.tablesorter */
+ $sortableTables = $( 'table.sortable' );
+ if ( $sortableTables.length ) {
+ mw.loader.using( 'jquery.tablesorter', function () {
+ $sortableTables.tablesorter();
+ });
+ }
- /* Enable CheckboxShiftClick */
- $( 'input[type=checkbox]:not(.noshiftselect)' ).checkboxShiftClick();
+ /* Enable CheckboxShiftClick */
+ $( 'input[type=checkbox]:not(.noshiftselect)' ).checkboxShiftClick();
- /* Add accesskey hints to the tooltips */
- mw.util.updateTooltipAccessKeys();
+ /* Add accesskey hints to the tooltips */
+ mw.util.updateTooltipAccessKeys();
-} );
+ } );
+}( mediaWiki, jQuery ) );
otherAction = action === 'watch' ? 'unwatch' : 'watch';
accesskeyTip = $link.attr( 'title' ).match( mw.util.tooltipAccessKeyRegexp );
$li = $link.closest( 'li' );
+
/**
* Trigger a 'watchpage' event for this List item.
* Announce the otherAction value as the first param.
* Used to monitor the state of watch link.
* TODO: Revise when system wide hooks are implemented
*/
- if( state === undefined ) {
+ if ( state === undefined ) {
$li.trigger( 'watchpage.mw', otherAction );
}
// Expose local methods
mw.page.watch = {
- 'updateWatchLink': updateWatchLink
+ updateWatchLink: updateWatchLink
};
$( document ).ready( function () {
otherAction = action === 'watch' ? 'unwatch' : 'watch';
$li = $link.closest( 'li' );
- mw.notify( $.parseHTML( watchResponse.message ), { tag: 'watch-self' } );
+ mw.notify( $.parseHTML( watchResponse.message ), {
+ tag: 'watch-self'
+ } );
// Set link to opposite
updateWatchLink( $link, otherAction );
if ( watchResponse.watched !== undefined ) {
$( '#wpWatchthis' ).prop( 'checked', true );
} else {
- $( '#wpWatchthis' ).removeProp( 'checked' );
+ $( '#wpWatchthis' ).prop( 'checked', false );
}
},
// Error
}
);
- });
- });
+ } );
+ } );
}( mediaWiki, jQuery ) );
-/* JavaScript for Special:Block */
+/**
+ * JavaScript for Special:Block
+ */
+( function ( mw, $ ) {
+ $( function ( $ ) {
-jQuery( function( $ ) {
+ var $blockTarget = $( '#mw-bi-target' ),
+ $anonOnlyRow = $( '#mw-input-wpHardBlock' ).closest( 'tr' ),
+ $enableAutoblockRow = $( '#mw-input-wpAutoBlock' ).closest( 'tr' ),
+ $hideUser = $( '#mw-input-wpHideUser' ).closest( 'tr' ),
+ $watchUser = $( '#mw-input-wpWatch' ).closest( 'tr' );
- var DO_INSTANT = true,
- $blockTarget = $( '#mw-bi-target' ),
- $anonOnlyRow = $( '#mw-input-wpHardBlock' ).closest( 'tr' ),
- $enableAutoblockRow = $( '#mw-input-wpAutoBlock' ).closest( 'tr' ),
- $hideUser = $( '#mw-input-wpHideUser' ).closest( 'tr' ),
- $watchUser = $( '#mw-input-wpWatch' ).closest( 'tr' );
+ function updateBlockOptions( instant ) {
+ if ( !$blockTarget.length ) {
+ return;
+ }
- var updateBlockOptions = function( instant ) {
- if ( !$blockTarget.length ) {
- return;
- }
-
- var blocktarget = $.trim( $blockTarget.val() );
- var isEmpty = ( blocktarget === '' );
- var isIp = mw.util.isIPv4Address( blocktarget, true ) || mw.util.isIPv6Address( blocktarget, true );
- var isIpRange = isIp && blocktarget.match( /\/\d+$/ );
+ var blocktarget = $.trim( $blockTarget.val() ),
+ isEmpty = blocktarget === '',
+ isIp = mw.util.isIPv4Address( blocktarget, true ) || mw.util.isIPv6Address( blocktarget, true ),
+ isIpRange = isIp && blocktarget.match( /\/\d+$/ );
- if ( isIp && !isEmpty ) {
- $enableAutoblockRow.goOut( instant );
- $hideUser.goOut( instant );
- } else {
- $enableAutoblockRow.goIn( instant );
- $hideUser.goIn( instant );
- }
- if ( !isIp && !isEmpty ) {
- $anonOnlyRow.goOut( instant );
- } else {
- $anonOnlyRow.goIn( instant );
+ if ( isIp && !isEmpty ) {
+ $enableAutoblockRow.goOut( instant );
+ $hideUser.goOut( instant );
+ } else {
+ $enableAutoblockRow.goIn( instant );
+ $hideUser.goIn( instant );
+ }
+ if ( !isIp && !isEmpty ) {
+ $anonOnlyRow.goOut( instant );
+ } else {
+ $anonOnlyRow.goIn( instant );
+ }
+ if ( isIpRange && !isEmpty ) {
+ $watchUser.goOut( instant );
+ } else {
+ $watchUser.goIn( instant );
+ }
}
- if ( isIpRange && !isEmpty ) {
- $watchUser.goOut( instant );
- } else {
- $watchUser.goIn( instant );
- }
- };
- // Bind functions so they're checked whenever stuff changes
- $blockTarget.keyup( updateBlockOptions );
+ // Bind functions so they're checked whenever stuff changes
+ $blockTarget.keyup( updateBlockOptions );
+
+ // Call them now to set initial state (ie. Special:Block/Foobar?wpBlockExpiry=2+hours)
+ updateBlockOptions( /* instant= */ true );
+ } );
+}( mediaWiki, jQuery ) );
- // Call them now to set initial state (ie. Special:Block/Foobar?wpBlockExpiry=2+hours)
- updateBlockOptions( DO_INSTANT );
-});
// (only if a framework was found, not on error pages).
$( '#mw-javascripttest-summary.mw-javascripttest-frameworkfound' ).append( function () {
- var $html = $( '<p><label for="useskin">'
+ var $html = $( '<p><label for="useskin">'
+ mw.message( 'javascripttest-pagetext-skins' ).escaped()
+ ' '
+ '</label></p>' ),
-mw.special = {};
+/*
+ * Namespace for mediawiki.special.* modules
+ */
+
+mediaWiki.special = {};
-/* JavaScript for Special:MovePage */
+/**
+ * JavaScript for Special:MovePage
+ */
jQuery( function( $ ) {
$( '#wpReason, #wpNewTitleMain' ).byteLimit();
-});
+} );
* JavaScript for Special:Preferences
*/
jQuery( document ).ready( function ( $ ) {
-$( '#prefsubmit' ).attr( 'id', 'prefcontrol' );
-var $preftoc = $('<ul id="preftoc"></ul>');
-var $preferences = $( '#preferences' )
- .addClass( 'jsprefs' )
- .before( $preftoc );
-
-var $fieldsets = $preferences.children( 'fieldset' )
- .hide()
- .addClass( 'prefsection' );
-
-var $legends = $fieldsets.children( 'legend' )
- .addClass( 'mainLegend' );
-
-/**
- * It uses document.getElementById for security reasons (html injections in
- * jQuery()).
- *
- * @param String name: the name of a tab without the prefix ("mw-prefsection-")
- * @param String mode: [optional] A hash will be set according to the current
- * open section. Set mode 'noHash' to surpress this.
- */
-function switchPrefTab( name, mode ) {
- var $tab, scrollTop;
- // Handle hash manually to prevent jumping,
- // therefore save and restore scrollTop to prevent jumping.
- scrollTop = $( window ).scrollTop();
- if ( mode !== 'noHash' ) {
- window.location.hash = '#mw-prefsection-' + name;
- }
- $( window ).scrollTop( scrollTop );
-
- $preftoc.find( 'li' ).removeClass( 'selected' );
- $tab = $( document.getElementById( 'preftab-' + name ) );
- if ( $tab.length ) {
- $tab.parent().addClass( 'selected' );
- $preferences.children( 'fieldset' ).hide();
- $( document.getElementById( 'mw-prefsection-' + name ) ).show();
+ var $preftoc, $preferences, $fieldsets, $legends,
+ hash,
+ $tzSelect, $tzTextbox, $localtimeHolder, servertime;
+
+ $( '#prefsubmit' ).attr( 'id', 'prefcontrol' );
+
+ $preftoc = $('<ul id="preftoc"></ul>'),
+ $preferences = $( '#preferences' )
+ .addClass( 'jsprefs' )
+ .before( $preftoc ),
+ $fieldsets = $preferences.children( 'fieldset' )
+ .hide()
+ .addClass( 'prefsection' ),
+ $legends = $fieldsets
+ .children( 'legend' )
+ .addClass( 'mainLegend' );
+
+ /**
+ * It uses document.getElementById for security reasons (html injections in
+ * jQuery()).
+ *
+ * @param String name: the name of a tab without the prefix ("mw-prefsection-")
+ * @param String mode: [optional] A hash will be set according to the current
+ * open section. Set mode 'noHash' to surpress this.
+ */
+ function switchPrefTab( name, mode ) {
+ var $tab, scrollTop;
+ // Handle hash manually to prevent jumping,
+ // therefore save and restore scrollTop to prevent jumping.
+ scrollTop = $( window ).scrollTop();
+ if ( mode !== 'noHash' ) {
+ window.location.hash = '#mw-prefsection-' + name;
+ }
+ $( window ).scrollTop( scrollTop );
+
+ $preftoc.find( 'li' ).removeClass( 'selected' );
+ $tab = $( document.getElementById( 'preftab-' + name ) );
+ if ( $tab.length ) {
+ $tab.parent().addClass( 'selected' );
+ $preferences.children( 'fieldset' ).hide();
+ $( document.getElementById( 'mw-prefsection-' + name ) ).show();
+ }
}
-}
-// Populate the prefToc
-$legends.each( function ( i, legend ) {
- var $legend = $(legend);
- if ( i === 0 ) {
- $legend.parent().show();
+ // Populate the prefToc
+ $legends.each( function ( i, legend ) {
+ var $legend = $(legend),
+ ident, $li, $a;
+ if ( i === 0 ) {
+ $legend.parent().show();
+ }
+ ident = $legend.parent().attr( 'id' );
+
+ $li = $( '<li>' )
+ .addClass( i === 0 ? 'selected' : '' );
+ $a = $( '<a>' )
+ .attr( {
+ id: ident.replace( 'mw-prefsection', 'preftab' ),
+ href: '#' + ident
+ } )
+ .text( $legend.text() );
+ $li.append( $a );
+ $preftoc.append( $li );
+ } );
+
+ // If we've reloaded the page or followed an open-in-new-window,
+ // make the selected tab visible.
+ hash = window.location.hash;
+ if ( hash.match( /^#mw-prefsection-[\w\-]+/ ) ) {
+ switchPrefTab( hash.replace( '#mw-prefsection-' , '' ) );
}
- var ident = $legend.parent().attr( 'id' );
-
- var $li = $( '<li/>', {
- 'class' : ( i === 0 ) ? 'selected' : null
- });
- var $a = $( '<a/>', {
- text : $legend.text(),
- id : ident.replace( 'mw-prefsection', 'preftab' ),
- href : '#' + ident
- });
- $li.append( $a );
- $preftoc.append( $li );
-} );
-// If we've reloaded the page or followed an open-in-new-window,
-// make the selected tab visible.
-var hash = window.location.hash;
-if ( hash.match( /^#mw-prefsection-[\w-]+/ ) ) {
- switchPrefTab( hash.replace( '#mw-prefsection-' , '' ) );
-}
-
-// In browsers that support the onhashchange event we will not bind click
-// handlers and instead let the browser do the default behavior (clicking the
-// <a href="#.."> will naturally set the hash, handled by onhashchange.
-// But other things that change the hash will also be catched (e.g. using
-// the Back and Forward browser navigation).
-if ( 'onhashchange' in window ) {
- $(window).on( 'hashchange' , function () {
- var hash = window.location.hash;
- if ( hash.match( /^#mw-prefsection-[\w-]+/ ) ) {
- switchPrefTab( hash.replace( '#mw-prefsection-', '' ) );
- } else if ( hash === '' ) {
- switchPrefTab( 'personal', 'noHash' );
- }
- });
-// In older browsers we'll bind a click handler as fallback.
-// We must not have onhashchange *and* the click handlers, other wise
-// the click handler calls switchPrefTab() which sets the hash value,
-// which triggers onhashcange and calls switchPrefTab() again.
-} else {
- $preftoc.on( 'click', 'li a', function ( e ) {
- switchPrefTab( $( this ).attr( 'href' ).replace( '#mw-prefsection-', '' ) );
- e.preventDefault();
- });
-}
-
-/**
-* Timezone functions.
-* Guesses Timezone from browser and updates fields onchange
-*/
-
-var $tzSelect = $( '#mw-input-wptimecorrection' );
-var $tzTextbox = $( '#mw-input-wptimecorrection-other' );
-
-var $localtimeHolder = $( '#wpLocalTime' );
-var servertime = parseInt( $( 'input[name=wpServerTime]' ).val(), 10 );
-var minuteDiff = 0;
-
-var minutesToHours = function ( min ) {
- var tzHour = Math.floor( Math.abs( min ) / 60 );
- var tzMin = Math.abs( min ) % 60;
- var tzString = ( ( min >= 0 ) ? '' : '-' ) + ( ( tzHour < 10 ) ? '0' : '' ) + tzHour +
- ':' + ( ( tzMin < 10 ) ? '0' : '' ) + tzMin;
- return tzString;
-};
-
-var hoursToMinutes = function ( hour ) {
- var arr = hour.split( ':' );
- arr[0] = parseInt( arr[0], 10 );
-
- var minutes;
- if ( arr.length == 1 ) {
- // Specification is of the form [-]XX
- minutes = arr[0] * 60;
+ // In browsers that support the onhashchange event we will not bind click
+ // handlers and instead let the browser do the default behavior (clicking the
+ // <a href="#.."> will naturally set the hash, handled by onhashchange.
+ // But other things that change the hash will also be catched (e.g. using
+ // the Back and Forward browser navigation).
+ if ( 'onhashchange' in window ) {
+ $(window).on( 'hashchange' , function () {
+ var hash = window.location.hash;
+ if ( hash.match( /^#mw-prefsection-[\w\-]+/ ) ) {
+ switchPrefTab( hash.replace( '#mw-prefsection-', '' ) );
+ } else if ( hash === '' ) {
+ switchPrefTab( 'personal', 'noHash' );
+ }
+ });
+ // In older browsers we'll bind a click handler as fallback.
+ // We must not have onhashchange *and* the click handlers, other wise
+ // the click handler calls switchPrefTab() which sets the hash value,
+ // which triggers onhashcange and calls switchPrefTab() again.
} else {
- // Specification is of the form [-]XX:XX
- minutes = Math.abs( arr[0] ) * 60 + parseInt( arr[1], 10 );
- if ( arr[0] < 0 ) {
- minutes *= -1;
- }
+ $preftoc.on( 'click', 'li a', function ( e ) {
+ switchPrefTab( $( this ).attr( 'href' ).replace( '#mw-prefsection-', '' ) );
+ e.preventDefault();
+ });
}
- // Gracefully handle non-numbers.
- if ( isNaN( minutes ) ) {
- return 0;
- } else {
- return minutes;
+
+ /**
+ * Timezone functions.
+ * Guesses Timezone from browser and updates fields onchange
+ */
+
+ $tzSelect = $( '#mw-input-wptimecorrection' );
+ $tzTextbox = $( '#mw-input-wptimecorrection-other' );
+ $localtimeHolder = $( '#wpLocalTime' );
+ servertime = parseInt( $( 'input[name="wpServerTime"]' ).val(), 10 );
+
+ function minutesToHours( min ) {
+ var tzHour = Math.floor( Math.abs( min ) / 60 ),
+ tzMin = Math.abs( min ) % 60,
+ tzString = ( ( min >= 0 ) ? '' : '-' ) + ( ( tzHour < 10 ) ? '0' : '' ) + tzHour +
+ ':' + ( ( tzMin < 10 ) ? '0' : '' ) + tzMin;
+ return tzString;
}
-};
-
-var updateTimezoneSelection = function () {
- var type = $tzSelect.val();
- if ( type == 'guess' ) {
- // Get browser timezone & fill it in
- minuteDiff = -new Date().getTimezoneOffset();
- $tzTextbox.val( minutesToHours( minuteDiff ) );
- $tzSelect.val( 'other' );
- $tzTextbox.get( 0 ).disabled = false;
- } else if ( type == 'other' ) {
- // Grab data from the textbox, parse it.
- minuteDiff = hoursToMinutes( $tzTextbox.val() );
- } else {
- // Grab data from the $tzSelect value
- minuteDiff = parseInt( type.split( '|' )[1], 10 ) || 0;
- $tzTextbox.val( minutesToHours( minuteDiff ) );
+
+ function hoursToMinutes( hour ) {
+ var minutes,
+ arr = hour.split( ':' );
+
+ arr[0] = parseInt( arr[0], 10 );
+
+ if ( arr.length === 1 ) {
+ // Specification is of the form [-]XX
+ minutes = arr[0] * 60;
+ } else {
+ // Specification is of the form [-]XX:XX
+ minutes = Math.abs( arr[0] ) * 60 + parseInt( arr[1], 10 );
+ if ( arr[0] < 0 ) {
+ minutes *= -1;
+ }
+ }
+ // Gracefully handle non-numbers.
+ if ( isNaN( minutes ) ) {
+ return 0;
+ } else {
+ return minutes;
+ }
}
- // Determine local time from server time and minutes difference, for display.
- var localTime = servertime + minuteDiff;
+ function updateTimezoneSelection () {
+ var minuteDiff, localTime,
+ type = $tzSelect.val();
+
+ if ( type === 'guess' ) {
+ // Get browser timezone & fill it in
+ minuteDiff = -( new Date().getTimezoneOffset() );
+ $tzTextbox.val( minutesToHours( minuteDiff ) );
+ $tzSelect.val( 'other' );
+ $tzTextbox.prop( 'disabled', false );
+ } else if ( type === 'other' ) {
+ // Grab data from the textbox, parse it.
+ minuteDiff = hoursToMinutes( $tzTextbox.val() );
+ } else {
+ // Grab data from the $tzSelect value
+ minuteDiff = parseInt( type.split( '|' )[1], 10 ) || 0;
+ $tzTextbox.val( minutesToHours( minuteDiff ) );
+ }
- // Bring time within the [0,1440) range.
- while ( localTime < 0 ) {
- localTime += 1440;
+ // Determine local time from server time and minutes difference, for display.
+ localTime = servertime + minuteDiff;
+
+ // Bring time within the [0,1440) range.
+ while ( localTime < 0 ) {
+ localTime += 1440;
+ }
+ while ( localTime >= 1440 ) {
+ localTime -= 1440;
+ }
+ $localtimeHolder.text( minutesToHours( localTime ) );
}
- while ( localTime >= 1440 ) {
- localTime -= 1440;
+
+ if ( $tzSelect.length && $tzTextbox.length ) {
+ $tzSelect.change( updateTimezoneSelection );
+ $tzTextbox.blur( updateTimezoneSelection );
+ updateTimezoneSelection();
}
- $localtimeHolder.text( minutesToHours( localTime ) );
-};
-
-if ( $tzSelect.length && $tzTextbox.length ) {
- $tzSelect.change( function () { updateTimezoneSelection(); } );
- $tzTextbox.blur( function () { updateTimezoneSelection(); } );
- updateTimezoneSelection();
-}
} );
-/* JavaScript for Special:RecentChanges */
+/**
+ * JavaScript for Special:RecentChanges
+ */
( function ( mw, $ ) {
+ var rc,
+ $checkboxes,
+ $select;
- var checkboxes = [ 'nsassociated', 'nsinvert' ];
-
- /**
- * @var select {jQuery}
- */
- var $select = null;
-
- var rc = mw.special.recentchanges = {
+ rc = {
/**
* Handler to disable/enable the namespace selector checkboxes when the
*/
updateCheckboxes: function () {
// The option element for the 'all' namespace has an empty value
- var isAllNS = $select.find('option:selected').val() === '';
+ var isAllNS = $select.find( 'option:selected' ).val() === '';
// Iterates over checkboxes and propagate the selected option
- $.each( checkboxes, function ( i, id ) {
- $( '#' + id ).prop( 'disabled', isAllNS );
- });
+ $checkboxes.prop( 'disabled', isAllNS );
},
init: function () {
- // Populate
$select = $( '#namespace' );
+ $checkboxes = $( '#nsassociated, #nsinvert' );
// Bind to change event, and trigger once to set the initial state of the checkboxes.
- $select.change( rc.updateCheckboxes ).change();
+ rc.updateCheckboxes();
+ $select.change( rc.updateCheckboxes );
}
};
- // Run when document is ready
$( rc.init );
+ mw.special.recentchanges = rc;
+
}( mediaWiki, jQuery ) );
/*
* JavaScript for Special:Search
*/
-( function( $, mw ) { $( function() {
+( function ( $, mw ) {
+ $( function () {
+ var $checkboxes, $headerLinks;
-// Emulate HTML5 autofocus behavior in non HTML5 compliant browsers
-if ( !( 'autofocus' in document.createElement( 'input' ) ) ) {
- $( 'input[autofocus]:first' ).focus();
-}
+ // Emulate HTML5 autofocus behavior in non HTML5 compliant browsers
+ if ( !( 'autofocus' in document.createElement( 'input' ) ) ) {
+ $( 'input[autofocus]' ).eq( 0 ).focus();
+ }
-// Create check all/none button
-var $checkboxes = $('#powersearch input[id^=mw-search-ns]');
-$('#mw-search-togglebox').append(
- $('<label />')
- .text(mw.msg('powersearch-togglelabel'))
-).append(
- $('<input type="button" />')
- .attr('id', 'mw-search-toggleall')
- .attr('value', mw.msg('powersearch-toggleall'))
- .click( function() {
- $checkboxes.prop('checked', true);
- } )
-).append(
- $('<input type="button" />')
- .attr('id', 'mw-search-togglenone')
- .attr('value', mw.msg('powersearch-togglenone'))
- .click( function() {
- $checkboxes.prop('checked', false);
- } )
-);
+ // Create check all/none button
+ $checkboxes = $('#powersearch input[id^=mw-search-ns]');
+ $('#mw-search-togglebox').append(
+ $('<label>')
+ .text(mw.msg('powersearch-togglelabel'))
+ ).append(
+ $('<input type="button" />')
+ .attr( 'id', 'mw-search-toggleall' )
+ .prop( 'value', mw.msg('powersearch-toggleall' ) )
+ .click( function () {
+ $checkboxes.prop('checked', true);
+ } )
+ ).append(
+ $('<input type="button" />')
+ .attr( 'id', 'mw-search-togglenone' )
+ .prop( 'value', mw.msg('powersearch-togglenone' ) )
+ .click( function() {
+ $checkboxes.prop( 'checked', false );
+ } )
+ );
-// Change the header search links to what user entered
-var headerLinks = $('.search-types a');
-$('#searchText, #powerSearchText').change(function() {
- var searchterm = $(this).val();
- headerLinks.each( function() {
- var parts = $(this).attr('href').split( 'search=' );
- var lastpart = '';
- var prefix = 'search=';
- if( parts.length > 1 && parts[1].indexOf('&') >= 0 ) {
- lastpart = parts[1].substring( parts[1].indexOf('&') );
- } else {
- prefix = '&search=';
- }
- this.href = parts[0] + prefix + encodeURIComponent( searchterm ) + lastpart;
- });
-}).trigger('change');
+ // Change the header search links to what user entered
+ $headerLinks = $( '.search-types a' );
+ $( '#searchText, #powerSearchText' ).change( function () {
+ var searchterm = $(this).val();
+ $headerLinks.each( function () {
+ var parts = $(this).attr('href').split( 'search=' ),
+ lastpart = '',
+ prefix = 'search=';
+ if ( parts.length > 1 && parts[1].indexOf('&') >= 0 ) {
+ lastpart = parts[1].substring( parts[1].indexOf('&') );
+ } else {
+ prefix = '&search=';
+ }
+ this.href = parts[0] + prefix + encodeURIComponent( searchterm ) + lastpart;
+ });
+ }).trigger( 'change' );
+
+ } );
-} ); } )( jQuery, mediaWiki );
+}( jQuery, mediaWiki ) );
/*
* JavaScript for Specical:Undelete
*/
-jQuery( document ).ready( function( $ ) {
- $( '#mw-undelete-invert' ).click( function( e ) {
+jQuery( document ).ready( function ( $ ) {
+ $( '#mw-undelete-invert' ).click( function ( e ) {
e.preventDefault();
- $( '#undelete' ).find( 'input:checkbox' )
- .prop( 'checked', function( i, val ) { return !val; } );
+ $( '#undelete input[type="checkbox"]' ).prop( 'checked', function ( i, val ) {
+ return !val;
+ } );
} );
} );
* Is the FileAPI available with sufficient functionality?
*/
function hasFileAPI() {
- return typeof window.FileReader !== 'undefined';
+ return window.FileReader !== undefined;
}
/**
* @param {File} file
*/
function showPreview( file ) {
- var previewSize = 180,
+ var $canvas,
+ ctx,
+ meta,
+ previewSize = 180,
thumb = $( '<div id="mw-upload-thumbnail" class="thumb tright">' +
'<div class="thumbinner">' +
'<div class="mw-small-spinner" style="width: 180px; height: 180px"></div>' +
'<div class="thumbcaption"><div class="filename"></div><div class="fileinfo"></div></div>' +
'</div>' +
'</div>' );
+
thumb.find( '.filename' ).text( file.name ).end()
.find( '.fileinfo' ).text( prettySize( file.size ) ).end();
- var $canvas = $('<canvas width="' + previewSize + '" height="' + previewSize + '" ></canvas>'),
- ctx = $canvas[0].getContext( '2d' );
+ $canvas = $('<canvas width="' + previewSize + '" height="' + previewSize + '" ></canvas>');
+ ctx = $canvas[0].getContext( '2d' );
$( '#mw-htmlform-source' ).parent().prepend( thumb );
- var meta;
- fetchPreview( file, function( dataURL ) {
+ fetchPreview( file, function ( dataURL ) {
var img = new Image(),
rotation = 0;
}
img.onload = function () {
- var width, height, x, y, dx, dy, logicalWidth, logicalHeight;
+ var info, width, height, x, y, dx, dy, logicalWidth, logicalHeight;
+
// Fit the image within the previewSizexpreviewSize box
if ( img.width > img.height ) {
width = previewSize;
thumb.find('.mw-small-spinner').replaceWith($canvas);
// Image size
- var info = mw.msg( 'widthheight', logicalWidth, logicalHeight ) +
+ info = mw.msg( 'widthheight', logicalWidth, logicalHeight ) +
', ' + prettySize( file.size );
+
$( '#mw-upload-thumbnail .fileinfo' ).text( info );
};
img.src = dataURL;
}, mw.config.get( 'wgFileCanRotate' ) ? function ( data ) {
+ /*jshint camelcase: false, nomen: false */
try {
meta = mw.libs.jpegmeta( data, file.fileName );
meta._binary_data = null;
// However, our JPEG metadata library wants a string.
// So, this is going to be an ugly conversion.
reader.onload = function() {
- var buffer = new Uint8Array( reader.result ),
+ var i,
+ buffer = new Uint8Array( reader.result ),
string = '';
- for ( var i = 0; i < buffer.byteLength; i++ ) {
+ for ( i = 0; i < buffer.byteLength; i++ ) {
string += String.fromCharCode( buffer[i] );
}
callbackBinary( string );
} else {
// This ends up decoding the file to base-64 and back again, which
// feels horribly inefficient.
- reader.onload = function() {
+ reader.onload = function () {
callback( reader.result );
};
reader.readAsDataURL( file );
* Check if the file does not exceed the maximum size
*/
function checkMaxUploadSize( file ) {
+ var maxSize, $error;
+
function getMaxUploadSize( type ) {
var sizes = mw.config.get( 'wgMaxUploadSize' );
+
if ( sizes[type] !== undefined ) {
return sizes[type];
}
return sizes['*'];
}
+
$( '.mw-upload-source-error' ).remove();
- var maxSize = getMaxUploadSize( 'file' );
+ maxSize = getMaxUploadSize( 'file' );
if ( file.size > maxSize ) {
- var error = $( '<p class="error mw-upload-source-error" id="wpSourceTypeFile-error">' +
- mw.message( 'largefileserver', file.size, maxSize ).escaped() + '</p>' );
- $( '#wpUploadFile' ).after( error );
+ $error = $( '<p class="error mw-upload-source-error" id="wpSourceTypeFile-error">' +
+ mw.message( 'largefileserver', file.size, maxSize ).escaped() + '</p>' );
+
+ $( '#wpUploadFile' ).after( $error );
+
return false;
}
+
return true;
}
* Disable all upload source fields except the selected one
*/
$( function ( $ ) {
- var i, row,
- rows = $( '.mw-htmlform-field-UploadSourceField' );
- for ( i = rows.length; i; i-- ) {
- row = rows[i - 1];
- $( 'input[name="wpSourceType"]', row ).change( ( function () {
- var currentRow = row; // Store current row in our own scope
- return function () {
- $( '.mw-upload-source-error' ).remove();
- if ( this.checked ) {
- // Disable all inputs
- $( 'input[name!="wpSourceType"]', rows ).prop( 'disabled', true );
- // Re-enable the current one
- $( 'input', currentRow ).prop( 'disabled', false );
- }
- };
- }() ) );
+ var i, $row,
+ $rows = $( '.mw-htmlform-field-UploadSourceField' );
+
+ function createHandler( $currentRow ) {
+ /**
+ * @param {jQuery.Event}
+ */
+ return function () {
+ $( '.mw-upload-source-error' ).remove();
+ if ( this.checked ) {
+ // Disable all inputs
+ $rows.find( 'input[name!="wpSourceType"]' ).prop( 'disabled', true );
+ // Re-enable the current one
+ $currentRow.find( 'input' ).prop( 'disabled', false );
+ }
+ };
+ }
+
+ for ( i = $rows.length; i; i-- ) {
+ $row = $rows.eq(i - 1);
+ $row
+ .find( 'input[name="wpSourceType"]' )
+ .change( createHandler( $row ) );
}
} );
// In normal browsers the match-array contains null/undefined if there's no match,
// IE returns an empty string.
var matches = s.match( /^(?:([^:]+):)?(.*?)(?:\.(\w+))?$/ ),
- ns_match = getNsIdByName( matches[1] );
+ nsMatch = getNsIdByName( matches[1] );
// Namespace must be valid, and title must be a non-empty string.
- if ( ns_match && typeof matches[2] === 'string' && matches[2] !== '' ) {
- title.ns = ns_match;
+ if ( nsMatch && typeof matches[2] === 'string' && matches[2] !== '' ) {
+ title.ns = nsMatch;
title.name = fixName( matches[2] );
if ( typeof matches[3] === 'string' && matches[3] !== '' ) {
title.ext = fixExt( matches[3] );
/**
- * mediawiki.Feedback
+ * mediawiki.feedback
*
* @author Ryan Kaldari, 2010
* @author Neil Kandalgaonkar, 2010-11
mw.Feedback.prototype = {
setup: function () {
- var fb = this;
+ var $feedbackPageLink,
+ $bugNoteLink,
+ $bugsListLink,
+ fb = this;
- var $feedbackPageLink = $( '<a>' )
- .attr( { 'href': fb.title.getUrl(), 'target': '_blank' } )
- .css( { 'white-space': 'nowrap' } );
+ $feedbackPageLink = $( '<a>' )
+ .attr( {
+ href: fb.title.getUrl(),
+ target: '_blank'
+ } )
+ .css( {
+ whiteSpace: 'nowrap'
+ } );
- var $bugNoteLink = $( '<a>' ).attr( { 'href': '#' } ).click( function () {
+ $bugNoteLink = $( '<a>' ).attr( { href: '#' } ).click( function () {
fb.displayBugs();
} );
- var $bugsListLink = $( '<a>' ).attr( { 'href': fb.bugsListLink, 'target': '_blank' } );
+ $bugsListLink = $( '<a>' ).attr( {
+ href: fb.bugsListLink,
+ target: '_blank'
+ } );
// TODO: Use a stylesheet instead of these inline styles
this.$dialog =
),
$( '<div class="feedback-mode feedback-submitting" style="text-align: center; margin: 3em 0;"></div>' ).append(
mw.msg( 'feedback-adding' ),
- $( '<br/>' ),
+ $( '<br>' ),
$( '<span class="feedback-spinner"></span>' )
),
$( '<div class="feedback-mode feedback-thanks" style="text-align: center; margin:1em"></div>' ).msg(
},
displayBugs: function () {
- var fb = this;
+ var fb = this,
+ bugsButtons = {};
this.display( 'bugs' );
- var bugsButtons = {};
bugsButtons[ mw.msg( 'feedback-bugnew' ) ] = function () {
window.open( fb.bugsLink, '_blank' );
};
},
displayThanks: function () {
- var fb = this;
+ var fb = this,
+ closeButton = {};
this.display( 'thanks' );
- var closeButton = {};
closeButton[ mw.msg( 'feedback-close' ) ] = function () {
fb.$dialog.dialog( 'close' );
};
* message: {String}
*/
displayForm: function ( contents ) {
- var fb = this;
+ var fb = this,
+ formButtons = {};
this.subjectInput.value = ( contents && contents.subject ) ? contents.subject : '';
this.messageInput.value = ( contents && contents.message ) ? contents.message : '';
this.display( 'form' );
// Set up buttons for dialog box. We have to do it the hard way since the json keys are localized
- var formButtons = {};
formButtons[ mw.msg( 'feedback-submit' ) ] = function () {
fb.submit();
};
},
displayError: function ( message ) {
- var fb = this;
+ var fb = this,
+ closeButton = {};
this.display( 'error' );
this.$dialog.find( '.feedback-error-msg' ).msg( message );
- var closeButton = {};
closeButton[ mw.msg( 'feedback-close' ) ] = function () {
fb.$dialog.dialog( 'close' );
};
}
}
- function err( code, info ) {
+ function err() {
// ajax request failed
fb.displayError( 'feedback-error3' );
}
-$( function() {
+jQuery( function ( $ ) {
// Apply hidpi images on DOM-ready
// Some may have already partly preloaded at low resolution.
$( 'body' ).hidpi();
-} );
\ No newline at end of file
+} );
/**
- * Utility functions for jazzing up HTMLForm elements
+ * Utility functions for jazzing up HTMLForm elements.
*/
( function ( $ ) {
-/**
- * jQuery plugin to fade or snap to visible state.
- *
- * @param boolean instantToggle (optional)
- * @return jQuery
- */
-$.fn.goIn = function ( instantToggle ) {
- if ( instantToggle === true ) {
- return $(this).show();
- }
- return $(this).stop( true, true ).fadeIn();
-};
-
-/**
- * jQuery plugin to fade or snap to hiding state.
- *
- * @param boolean instantToggle (optional)
- * @return jQuery
- */
-$.fn.goOut = function ( instantToggle ) {
- if ( instantToggle === true ) {
- return $(this).hide();
- }
- return $(this).stop( true, true ).fadeOut();
-};
-
-/**
- * Bind a function to the jQuery object via live(), and also immediately trigger
- * the function on the objects with an 'instant' parameter set to true
- * @param callback function taking one parameter, which is Bool true when the event
- * is called immediately, and the EventArgs object when triggered from an event
- */
-$.fn.liveAndTestAtStart = function ( callback ){
- $(this)
- .live( 'change', callback )
- .each( function ( index, element ){
- callback.call( this, true );
- } );
-};
-
-// Document ready:
-$( function () {
-
- // Animate the SelectOrOther fields, to only show the text field when
- // 'other' is selected.
- $( '.mw-htmlform-select-or-other' ).liveAndTestAtStart( function ( instant ) {
- var $other = $( '#' + $(this).attr( 'id' ) + '-other' );
- $other = $other.add( $other.siblings( 'br' ) );
- if ( $(this).val() === 'other' ) {
- $other.goIn( instant );
- } else {
- $other.goOut( instant );
+ /**
+ * jQuery plugin to fade or snap to visible state.
+ *
+ * @param {boolean} instantToggle [optional]
+ * @return {jQuery}
+ */
+ $.fn.goIn = function ( instantToggle ) {
+ if ( instantToggle === true ) {
+ return $(this).show();
}
- });
-
-});
-
+ return $(this).stop( true, true ).fadeIn();
+ };
+
+ /**
+ * jQuery plugin to fade or snap to hiding state.
+ *
+ * @param {boolean} instantToggle [optional]
+ * @return jQuery
+ */
+ $.fn.goOut = function ( instantToggle ) {
+ if ( instantToggle === true ) {
+ return $(this).hide();
+ }
+ return $(this).stop( true, true ).fadeOut();
+ };
+
+ /**
+ * Bind a function to the jQuery object via live(), and also immediately trigger
+ * the function on the objects with an 'instant' parameter set to true.
+ * @param {Function} callback Takes one parameter, which is {true} when the
+ * event is called immediately, and {jQuery.Event} when triggered from an event.
+ */
+ $.fn.liveAndTestAtStart = function ( callback ){
+ $(this)
+ .live( 'change', callback )
+ .each( function () {
+ callback.call( this, true );
+ } );
+ };
+
+ $( function () {
+
+ // Animate the SelectOrOther fields, to only show the text field when
+ // 'other' is selected.
+ $( '.mw-htmlform-select-or-other' ).liveAndTestAtStart( function ( instant ) {
+ var $other = $( '#' + $(this).attr( 'id' ) + '-other' );
+ $other = $other.add( $other.siblings( 'br' ) );
+ if ( $(this).val() === 'other' ) {
+ $other.goIn( instant );
+ } else {
+ $other.goOut( instant );
+ }
+ });
+
+ } );
}( jQuery ) );
* @author neilk@wikimedia.org
*/
( function ( mw, $ ) {
- var slice = Array.prototype.slice,
+ var oldParser,
+ slice = Array.prototype.slice,
parserDefaults = {
magic : {
'SITENAME' : mw.config.get( 'wgSiteName' )
* @return {jQuery}
*/
return function ( args ) {
- var key = args[0];
- var argsArray = $.isArray( args[1] ) ? args[1] : slice.call( args, 1 );
+ var key = args[0],
+ argsArray = $.isArray( args[1] ) ? args[1] : slice.call( args, 1 );
try {
return parser.parse( key, argsArray );
} catch ( e ) {
* is equivalent to
* somefunction(a, [b, c, d])
*
- * @param {String} message key
- * @param {Array} optional replacements (can also specify variadically)
- * @return {String} rendered HTML as string
+ * @param {string} key Message key.
+ * @param {Array|mixed} replacements Optional variable replacements (variadically or an array).
+ * @return {string} Rendered HTML.
*/
- return function ( /* key, replacements */ ) {
+ return function () {
return failableParserFn( arguments ).html();
};
};
* somefunction(a, [b, c, d])
*
* We append to 'this', which in a jQuery plugin context will be the selected elements.
- * @param {String} message key
- * @param {Array} optional replacements (can also specify variadically)
+ * @param {string} key Message key.
+ * @param {Array|mixed} replacements Optional variable replacements (variadically or an array).
* @return {jQuery} this
*/
- return function ( /* key, replacements */ ) {
+ return function () {
var $target = this.empty();
$.each( failableParserFn( arguments ).contents(), function ( i, node ) {
$target.append( node );
* Where the magic happens.
* Parses a message from the key, and swaps in replacements as necessary, wraps in jQuery
* If an error is thrown, returns original key, and logs the error
- * @param {String} message key
- * @param {Array} replacements for $1, $2... $n
+ * @param {String} key Message key.
+ * @param {Array} replacements Variable replacements for $1, $2... $n
* @return {jQuery}
*/
parse: function ( key, replacements ) {
if ( this.astCache[ key ] === undefined ) {
var wikiText = this.settings.messages.get( key );
if ( typeof wikiText !== 'string' ) {
- wikiText = "\\[" + key + "\\]";
+ wikiText = '\\[' + key + '\\]';
}
this.astCache[ key ] = this.wikiTextToAst( wikiText );
}
* @return {Mixed} abstract syntax tree
*/
wikiTextToAst: function ( input ) {
+ var pos,
+ regularLiteral, regularLiteralWithoutBar, regularLiteralWithoutSpace, backslash, anyCharacter,
+ escapedOrLiteralWithoutSpace, escapedOrLiteralWithoutBar, escapedOrRegularLiteral,
+ whitespace, dollar, digits,
+ openExtlink, closeExtlink, openLink, closeLink, templateName, pipe, colon,
+ templateContents, openTemplate, closeTemplate,
+ nonWhitespaceExpression, paramExpression, expression, result;
// Indicates current position in input as we parse through it.
// Shared among all parsing functions below.
- var pos = 0;
+ pos = 0;
+
// =========================================================
// parsing combinators - could be a library on its own
// =========================================================
// Try parsers until one works, if none work return null
function choice( ps ) {
return function () {
- for ( var i = 0; i < ps.length; i++ ) {
- var result = ps[i]();
+ var i, result;
+ for ( i = 0; i < ps.length; i++ ) {
+ result = ps[i]();
if ( result !== null ) {
return result;
}
// try several ps in a row, all must succeed or return null
// this is the only eager one
function sequence( ps ) {
- var originalPos = pos;
- var result = [];
- for ( var i = 0; i < ps.length; i++ ) {
- var res = ps[i]();
+ var i, res,
+ originalPos = pos,
+ result = [];
+ for ( i = 0; i < ps.length; i++ ) {
+ res = ps[i]();
if ( res === null ) {
pos = originalPos;
return null;
// must succeed a minimum of n times or return null
function nOrMore( n, p ) {
return function () {
- var originalPos = pos;
- var result = [];
- var parsed = p();
+ var originalPos = pos,
+ result = [],
+ parsed = p();
while ( parsed !== null ) {
result.push( parsed );
parsed = p();
// but some debuggers can't tell you exactly where they come from. Also the mutually
// recursive functions seem not to work in all browsers then. (Tested IE6-7, Opera, Safari, FF)
// This may be because, to save code, memoization was removed
- var regularLiteral = makeRegexParser( /^[^{}\[\]$\\]/ );
- var regularLiteralWithoutBar = makeRegexParser(/^[^{}\[\]$\\|]/);
- var regularLiteralWithoutSpace = makeRegexParser(/^[^{}\[\]$\s]/);
- var backslash = makeStringParser( "\\" );
- var anyCharacter = makeRegexParser( /^./ );
+ regularLiteral = makeRegexParser( /^[^{}\[\]$\\]/ );
+ regularLiteralWithoutBar = makeRegexParser(/^[^{}\[\]$\\|]/);
+ regularLiteralWithoutSpace = makeRegexParser(/^[^{}\[\]$\s]/);
+ backslash = makeStringParser( '\\' );
+ anyCharacter = makeRegexParser( /^./ );
function escapedLiteral() {
var result = sequence( [
backslash,
] );
return result === null ? null : result[1];
}
- var escapedOrLiteralWithoutSpace = choice( [
+ escapedOrLiteralWithoutSpace = choice( [
escapedLiteral,
regularLiteralWithoutSpace
] );
- var escapedOrLiteralWithoutBar = choice( [
+ escapedOrLiteralWithoutBar = choice( [
escapedLiteral,
regularLiteralWithoutBar
] );
- var escapedOrRegularLiteral = choice( [
+ escapedOrRegularLiteral = choice( [
escapedLiteral,
regularLiteral
] );
var result = nOrMore( 1, escapedOrRegularLiteral )();
return result === null ? null : result.join('');
}
- var whitespace = makeRegexParser( /^\s+/ );
- var dollar = makeStringParser( '$' );
- var digits = makeRegexParser( /^\d+/ );
+ whitespace = makeRegexParser( /^\s+/ );
+ dollar = makeStringParser( '$' );
+ digits = makeRegexParser( /^\d+/ );
function replacement() {
var result = sequence( [
}
return [ 'REPLACE', parseInt( result[1], 10 ) - 1 ];
}
- var openExtlink = makeStringParser( '[' );
- var closeExtlink = makeStringParser( ']' );
+ openExtlink = makeStringParser( '[' );
+ closeExtlink = makeStringParser( ']' );
// this extlink MUST have inner text, e.g. [foo] not allowed; [foo bar] is allowed
function extlink() {
- var result = null;
- var parsedResult = sequence( [
+ var result, parsedResult;
+ result = null;
+ parsedResult = sequence( [
openExtlink,
nonWhitespaceExpression,
whitespace,
}
return [ 'LINKPARAM', parseInt( result[2], 10 ) - 1, result[4] ];
}
- var openLink = makeStringParser( '[[' );
- var closeLink = makeStringParser( ']]' );
+ openLink = makeStringParser( '[[' );
+ closeLink = makeStringParser( ']]' );
function link() {
- var result = null;
- var parsedResult = sequence( [
+ var result, parsedResult;
+ result = null;
+ parsedResult = sequence( [
openLink,
expression,
closeLink
}
return result;
}
- var templateName = transform(
+ templateName = transform(
// see $wgLegalTitleChars
// not allowing : due to the need to catch "PLURAL:$1"
makeRegexParser( /^[ !"$&'()*,.\/0-9;=?@A-Z\^_`a-z~\x80-\xFF+\-]+/ ),
function ( result ) { return result.toString(); }
);
function templateParam() {
- var result = sequence( [
+ var expr, result;
+ result = sequence( [
pipe,
nOrMore( 0, paramExpression )
] );
if ( result === null ) {
return null;
}
- var expr = result[1];
- // use a "CONCAT" operator if there are multiple nodes, otherwise return the first node, raw.
- return expr.length > 1 ? [ "CONCAT" ].concat( expr ) : expr[0];
+ expr = result[1];
+ // use a CONCAT operator if there are multiple nodes, otherwise return the first node, raw.
+ return expr.length > 1 ? [ 'CONCAT' ].concat( expr ) : expr[0];
}
- var pipe = makeStringParser( '|' );
+ pipe = makeStringParser( '|' );
function templateWithReplacement() {
var result = sequence( [
templateName,
] );
return result === null ? null : [ result[0], result[2] ];
}
- var colon = makeStringParser(':');
- var templateContents = choice( [
+ colon = makeStringParser(':');
+ templateContents = choice( [
function () {
var res = sequence( [
// templates can have placeholders for dynamic replacement eg: {{PLURAL:$1|one car|$1 cars}}
return [ res[0] ].concat( res[1] );
}
] );
- var openTemplate = makeStringParser('{{');
- var closeTemplate = makeStringParser('}}');
+ openTemplate = makeStringParser('{{');
+ closeTemplate = makeStringParser('}}');
function template() {
var result = sequence( [
openTemplate,
] );
return result === null ? null : result[1];
}
- var nonWhitespaceExpression = choice( [
+ nonWhitespaceExpression = choice( [
template,
link,
extLinkParam,
replacement,
literalWithoutSpace
] );
- var paramExpression = choice( [
+ paramExpression = choice( [
template,
link,
extLinkParam,
replacement,
literalWithoutBar
] );
- var expression = choice( [
+ expression = choice( [
template,
link,
extLinkParam,
if ( result === null ) {
return null;
}
- return [ "CONCAT" ].concat( result );
+ return [ 'CONCAT' ].concat( result );
}
// everything above this point is supposed to be stateless/static, but
// I am deferring the work of turning it into prototypes & objects. It's quite fast enough
// finally let's do some actual work...
- var result = start();
+ result = start();
/*
* For success, the p must have gotten to the end of the input
* and returned a non-null.
* n.b. This is part of language infrastructure, so we do not throw an internationalizable message.
*/
- if (result === null || pos !== input.length) {
- throw new Error( "Parse error at position " + pos.toString() + " in input: " + input );
+ if ( result === null || pos !== input.length ) {
+ throw new Error( 'Parse error at position ' + pos.toString() + ' in input: ' + input );
}
return result;
}
* @return {Mixed} single-string node or array of nodes suitable for jQuery appending
*/
this.emit = function ( node, replacements ) {
- var ret = null;
- var jmsg = this;
+ var ret, subnodes, operation,
+ jmsg = this;
switch ( typeof node ) {
case 'string':
case 'number':
ret = node;
break;
- case 'object': // node is an array of nodes
- var subnodes = $.map( node.slice( 1 ), function ( n ) {
+ // typeof returns object for arrays
+ case 'object':
+ // node is an array of nodes
+ subnodes = $.map( node.slice( 1 ), function ( n ) {
return jmsg.emit( n, replacements );
} );
- var operation = node[0].toLowerCase();
+ operation = node[0].toLowerCase();
if ( typeof jmsg[operation] === 'function' ) {
ret = jmsg[ operation ]( subnodes, replacements );
} else {
/**
* Transform wiki-link
* TODO unimplemented
+ * @param nodes
*/
- wlink: function ( nodes ) {
+ wlink: function () {
return 'unimplemented';
},
* @return {jQuery}
*/
link: function ( nodes ) {
- var arg = nodes[0];
- var contents = nodes[1];
- var $el;
+ var $el,
+ arg = nodes[0],
+ contents = nodes[1];
if ( arg instanceof jQuery ) {
$el = arg;
} else {
* @return {String} selected pluralized form according to current language
*/
plural: function ( nodes ) {
- var count = parseFloat( this.language.convertNumber( nodes[0], true ) );
- var forms = nodes.slice(1);
+ var forms, count;
+ count = parseFloat( this.language.convertNumber( nodes[0], true ) );
+ forms = nodes.slice(1);
return forms.length ? this.language.convertPlural( count, forms ) : '';
},
* @return {String} selected grammatical form according to current language
*/
grammar: function ( nodes ) {
- var form = nodes[0];
- var word = nodes[1];
+ var form = nodes[0],
+ word = nodes[1];
return word && form && this.language.convertGrammar( word, form );
}
};
$.fn.msg = mw.jqueryMsg.getPlugin();
// Replace the default message parser with jqueryMsg
- var oldParser = mw.Message.prototype.parser;
+ oldParser = mw.Message.prototype.parser;
mw.Message.prototype.parser = function () {
// TODO: should we cache the message function so we don't create a new one every time? Benchmark this maybe?
// Caching is somewhat problematic, because we do need different message functions for different maps, so
*/
var mw = ( function ( $, undefined ) {
- "use strict";
+ 'use strict';
/* Private Members */
* Gets a message object, similar to wfMessage()
*
* @param key string Key of message to get
- * @param parameter_1 mixed First argument in a list of variadic arguments,
+ * @param parameter1 mixed First argument in a list of variadic arguments,
* each a parameter for $N replacement in messages.
* @return Message
*/
- message: function ( key, parameter_1 /* [, parameter_2] */ ) {
+ message: function ( key, parameter1 ) {
var parameters;
// Support variadic arguments
- if ( parameter_1 !== undefined ) {
+ if ( parameter1 !== undefined ) {
parameters = slice.call( arguments );
parameters.shift();
} else {
}
}
- function compare( a, b ) {
- var i;
- if ( a.length !== b.length ) {
- return false;
- }
- for ( i = 0; i < b.length; i += 1 ) {
- if ( $.isArray( a[i] ) ) {
- if ( !compare( a[i], b[i] ) ) {
- return false;
- }
- }
- if ( a[i] !== b[i] ) {
- return false;
- }
- }
- return true;
- }
-
/**
* Generates an ISO8601 "basic" string from a UNIX timestamp
*/
function formatVersionNumber( timestamp ) {
- var pad = function ( a, b, c ) {
- return [a < 10 ? '0' + a : a, b < 10 ? '0' + b : b, c < 10 ? '0' + c : c].join( '' );
- },
- d = new Date();
+ var d = new Date();
+ function pad( a, b, c ) {
+ return [a < 10 ? '0' + a : a, b < 10 ? '0' + b : b, c < 10 ? '0' + c : c].join( '' );
+ }
d.setTime( timestamp * 1000 );
return [
pad( d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate() ), 'T',
j -= 1;
try {
if ( hasErrors ) {
- throw new Error ("Module " + module + " failed.");
+ throw new Error( 'Module ' + module + ' failed.');
} else {
if ( $.isFunction( job.ready ) ) {
job.ready();
// Using isReady directly instead of storing it locally from
// a $.fn.ready callback (bug 31895).
if ( $.isReady || async ) {
- // jQuery's getScript method is NOT better than doing this the old-fashioned way
- // because jQuery will eval the script's code, and errors will not have sane
- // line numbers.
+ // Can't use jQuery.getScript because that only uses <script> for cross-domain,
+ // it uses XHR and eval for same-domain scripts, which we don't want because it
+ // messes up line numbers.
+ // The below is based on jQuery ([jquery@1.8.2]/src/ajax/script.js)
+
+ // IE-safe way of getting the <head>. document.head isn't supported
+ // in old IE, and doesn't work when in the <head>.
+ head = document.getElementsByTagName( 'head' )[0] || document.body;
+
script = document.createElement( 'script' );
- script.setAttribute( 'src', src );
- script.setAttribute( 'type', 'text/javascript' );
+ script.async = true;
+ script.src = src;
if ( $.isFunction( callback ) ) {
- // Attach handlers for all browsers (based on jQuery.ajax)
script.onload = script.onreadystatechange = function () {
-
if (
!done
&& (
|| /loaded|complete/.test( script.readyState )
)
) {
-
done = true;
- callback();
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
- // Handle memory leak in IE. This seems to fail in
- // IE7 sometimes (Permission Denied error when
- // accessing script.parentNode) so wrap it in
- // a try catch.
- try {
- script.onload = script.onreadystatechange = null;
- if ( script.parentNode ) {
- script.parentNode.removeChild( script );
- }
-
- // Dereference the script
- script = undefined;
- } catch ( e ) { }
+ // Remove the script
+ if ( script.parentNode ) {
+ script.parentNode.removeChild( script );
+ }
+
+ // Dereference the script
+ script = undefined;
+
+ callback();
}
};
}
if ( window.opera ) {
// Appending to the <head> blocks rendering completely in Opera,
// so append to the <body> after document ready. This means the
- // scripts only start loading after the document has been rendered,
+ // scripts only start loading after the document has been rendered,
// but so be it. Opera users don't deserve faster web pages if their
- // browser makes it impossible
- $( function () { document.body.appendChild( script ); } );
+ // browser makes it impossible.
+ $( function () {
+ document.body.appendChild( script );
+ } );
} else {
- // IE-safe way of getting the <head> . document.documentElement.head doesn't
- // work in scripts that run in the <head>
- head = document.getElementsByTagName( 'head' )[0];
- ( document.body || head ).appendChild( script );
+ head.appendChild( script );
}
} else {
- document.write( mw.html.element(
- 'script', { 'type': 'text/javascript', 'src': src }, ''
- ) );
+ document.write( mw.html.element( 'script', { 'src': src }, '' ) );
if ( $.isFunction( callback ) ) {
// Document.write is synchronous, so this is called when it's done
// FIXME: that's a lie. doc.write isn't actually synchronous
* document ready has not yet occurred
*/
function request( dependencies, ready, error, async ) {
- var regItemDeps, regItemDepLen, n;
+ var n;
// Allow calling by single module name
if ( typeof dependencies === 'string' ) {
*/
function doRequest( moduleMap, currReqBase, sourceLoadScript, async ) {
var request = $.extend(
- { 'modules': buildModulesString( moduleMap ) },
+ { modules: buildModulesString( moduleMap ) },
currReqBase
);
request = sortQuery( request );
}
}
- currReqBase = $.extend( { 'version': formatVersionNumber( maxVersion ) }, reqBase );
+ currReqBase = $.extend( { version: formatVersionNumber( maxVersion ) }, reqBase );
// For user modules append a user name to the request.
- if ( group === "user" && mw.config.get( 'wgUserName' ) !== null ) {
+ if ( group === 'user' && mw.config.get( 'wgUserName' ) !== null ) {
currReqBase.user = mw.config.get( 'wgUserName' );
}
currReqBaseLength = $.param( currReqBase ).length;
}
// List the module as registered
registry[module] = {
- 'version': version !== undefined ? parseInt( version, 10 ) : 0,
- 'dependencies': [],
- 'group': typeof group === 'string' ? group : null,
- 'source': typeof source === 'string' ? source: 'local',
- 'state': 'registered'
+ version: version !== undefined ? parseInt( version, 10 ) : 0,
+ dependencies: [],
+ group: typeof group === 'string' ? group : null,
+ source: typeof source === 'string' ? source: 'local',
+ state: 'registered'
};
if ( typeof dependencies === 'string' ) {
// Allow dependencies to be given as a single module name
- registry[module].dependencies = [dependencies];
+ registry[module].dependencies = [ dependencies ];
} else if ( typeof dependencies === 'object' || $.isFunction( dependencies ) ) {
// Allow dependencies to be given as an array of module names
// or a function which returns an array
}
// Allow calling with a single dependency as a string
if ( tod === 'string' ) {
- dependencies = [dependencies];
+ dependencies = [ dependencies ];
}
// Resolve entire dependency map
dependencies = resolve( dependencies );
* be assumed if loading a URL, and false will be assumed otherwise.
*/
load: function ( modules, type, async ) {
- var filtered, m, module;
+ var filtered, m, module, l;
// Validate input
if ( typeof modules !== 'object' && typeof modules !== 'string' ) {
async = true;
}
if ( type === 'text/css' ) {
- $( 'head' ).append( $( '<link>', {
- rel: 'stylesheet',
- type: 'text/css',
- href: modules
- } ) );
+ // IE7-8 throws security warnings when inserting a <link> tag
+ // with a protocol-relative URL set though attributes (instead of
+ // properties) - when on HTTPS. See also bug #.
+ l = document.createElement( 'link' );
+ l.rel = 'stylesheet';
+ l.href = modules;
+ $( 'head' ).append( l );
return;
}
if ( type === 'text/javascript' || type === undefined ) {
throw new Error( 'invalid type for external url, must be text/css or text/javascript. not ' + type );
}
// Called with single module
- modules = [modules];
+ modules = [ modules ];
}
// Filter out undefined modules, otherwise resolve() will throw
if ( registry[module] === undefined ) {
mw.loader.register( module );
}
- if ( $.inArray(state, ['ready', 'error', 'missing']) !== -1
+ if ( $.inArray( state, ['ready', 'error', 'missing'] ) !== -1
&& registry[module].state !== state ) {
// Make sure pending modules depending on this one get executed if their
// dependencies are now fulfilled!
html: ( function () {
function escapeCallback( s ) {
switch ( s ) {
- case "'":
+ case '\'':
return ''';
case '"':
return '"';
( function ( mw, $ ) {
'use strict';
- var isPageReady = false,
+ var notification,
+ isPageReady = false,
isInitialized = false,
preReadyNotifQueue = [],
/**
// Other notification elements matching the same tag
$tagMatches,
outerHeight,
- placeholderHeight;
+ placeholderHeight,
+ autohideCount,
+ notif;
if ( this.isOpen ) {
return;
}
} );
+ notif = this;
+
// Create a clear placeholder we can use to make the notifications around the notification that is being
// replaced expand or contract gracefully to fit the height of the new notification.
- var self = this;
- self.$replacementPlaceholder = $( '<div>' )
+ notif.$replacementPlaceholder = $( '<div>' )
// Set the height to the space the previous notification or placeholder took
.css( 'height', outerHeight )
// Make sure that this placeholder is at the very end of this tagged notification group
// Reset the notification position after we've finished the space animation
// However do not do it if the placeholder was removed because another tagged
// notification went and closed this one.
- if ( self.$replacementPlaceholder ) {
+ if ( notif.$replacementPlaceholder ) {
$notification.css( 'position', '' );
}
// Finally, remove the placeholder from the DOM
// By default a notification is paused.
// If this notification is within the first {autoHideLimit} notifications then
// start the auto-hide timer as soon as it's created.
- var autohideCount = $area.find( '.mw-notification-autohide' ).length;
+ autohideCount = $area.find( '.mw-notification-autohide' ).length;
if ( autohideCount <= notification.autoHideLimit ) {
this.resume();
}
}
}
- var notification = {
+ notification = {
/**
* Pause auto-hide timers for all notifications.
* Notifications will not auto-hide until resume is called.
/* Fill $content var */
util.$content = ( function () {
- var $content, selectors = [
+ var i, l, $content, selectors;
+ selectors = [
// The preferred standard for setting $content (class="mw-body")
// You may also use (class="mw-body mw-body-primary") if you use
// mw-body in multiple locations.
// not inserted bodytext yet. But in any case <body> should always exist
'body'
];
- for ( var i = 0, l = selectors.length; i < l; i++ ) {
+ for ( i = 0, l = selectors.length; i < l; i++ ) {
$content = $( selectors[i] ).first();
if ( $content.length ) {
return $content;
* is determined by validation.
*/
validateEmail: function ( mailtxt ) {
- var rfc5322_atext, rfc1034_ldh_str, HTML5_email_regexp;
+ var rfc5322Atext, rfc1034LdhStr, html5EmailRegexp;
if ( mailtxt === '' ) {
return null;
"|" / "}" /
"~"
*/
- rfc5322_atext = "a-z0-9!#$%&'*+\\-/=?^_`{|}~";
+ rfc5322Atext = 'a-z0-9!#$%&\'*+\\-/=?^_`{|}~';
/**
* Next define the RFC 1034 'ldh-str'
* <let-dig-hyp> ::= <let-dig> | "-"
* <let-dig> ::= <letter> | <digit>
*/
- rfc1034_ldh_str = "a-z0-9\\-";
+ rfc1034LdhStr = 'a-z0-9\\-';
- HTML5_email_regexp = new RegExp(
+ html5EmailRegexp = new RegExp(
// start of string
'^'
+
// User part which is liberal :p
- '[' + rfc5322_atext + '\\.]+'
+ '[' + rfc5322Atext + '\\.]+'
+
// 'at'
'@'
+
// Domain first part
- '[' + rfc1034_ldh_str + ']+'
+ '[' + rfc1034LdhStr + ']+'
+
// Optional second part and following are separated by a dot
- '(?:\\.[' + rfc1034_ldh_str + ']+)*'
+ '(?:\\.[' + rfc1034LdhStr + ']+)*'
+
// End of string
'$',
// RegExp is case insensitive
'i'
);
- return (null !== mailtxt.match( HTML5_email_regexp ) );
+ return (null !== mailtxt.match( html5EmailRegexp ) );
},
/**
* continue loading the jquery and mediawiki modules. This code should work on
* even the most ancient of browsers, so be very careful when editing.
*/
+
/**
* Returns false when run in a black-listed browser
*
* This function will be deleted after it's used, so do not expand it to be
- * generally useful beyond startup
+ * generally useful beyond startup.
*
- * jQuery has minimum requirements of:
- * * Internet Explorer 6.0+
- * * Firefox 3.6+
- * * Safari 5.0+
- * * Opera 11+
- * * Chrome
+ * MediaWiki & jQuery compatibility:
+ * - Internet Explorer 6.0+
+ * - Firefox 10+
+ * - Safari 5.0+
+ * - Opera 11+
+ * - Chrome
*/
+
+/*jshint unused: false */
function isCompatible() {
// IE < 6.0
if ( navigator.appVersion.indexOf( 'MSIE' ) !== -1
{
return false;
}
- // @todo FIXME: Firefox < 3.6
- // @todo FIXME: Safari < 5.0
- // @todo FIXME: Opera < 11
return true;
}
+
/**
- * The startUp() function will be generated and added here (at the bottom)
+ * The startUp() function will be auto-generated and added below.
*/
* @param $elements array
*/
protected function renderNavigation( $elements ) {
- global $wgVectorUseSimpleSearch;
+ global $wgVectorUseSimpleSearch, $wgVectorCombineUserTalk;
// If only one element was given, wrap it in an array, allowing more
// flexible arguments
<div id="p-personal" role="navigation" class="<?php if ( count( $this->data['personal_urls'] ) == 0 ) echo ' emptyPortlet'; ?>">
<h5><?php $this->msg( 'personaltools' ) ?></h5>
<ul<?php $this->html( 'userlangattributes' ) ?>>
-<?php foreach( $this->getPersonalTools() as $key => $item ) { ?>
- <?php echo $this->makeListItem( $key, $item ); ?>
-
-<?php } ?>
+<?php
+ $personalTools = $this->getPersonalTools();
+ if ( $wgVectorCombineUserTalk && isset( $personalTools['userpage'] ) ) {
+?>
+ <li>
+<?php
+ echo $this->makeListItem( 'userpage', $personalTools['userpage'], array( 'tag' => 'span' ) );
+?> <?php
+ $personalTools['mytalk']['links'][0]['text'] = $this->getMsg( 'mytalk-parenthetical' )->text();
+ $talkItem = $this->makeListItem( 'mytalk', $personalTools['mytalk'], array( 'tag' => 'span' ) );
+ echo $this->getMsg( 'parentheses' )->rawParams( $talkItem )->escaped();
+ unset( $personalTools['userpage'], $personalTools['mytalk'] );
+?>
+ </li>
+<?php
+ }
+ foreach ( $personalTools as $key => $item ) {
+ echo $this->makeListItem( $key, $item );
+ }
+?>
</ul>
</div>
<?php
window.importStylesheetURI = function( url, media ) {
var l = document.createElement( 'link' );
- l.type = 'text/css';
l.rel = 'stylesheet';
l.href = url;
- if( media ) {
+ if ( media ) {
l.media = media;
}
document.getElementsByTagName('head')[0].appendChild( l );
*/
global $wgAutoloadClasses;
-$testFolder = __DIR__;
+$testDir = __DIR__;
$wgAutoloadClasses += array(
- //PHPUnit
- 'MediaWikiTestCase' => "$testFolder/phpunit/MediaWikiTestCase.php",
- 'MediaWikiPHPUnitCommand' => "$testFolder/phpunit/MediaWikiPHPUnitCommand.php",
- 'MediaWikiLangTestCase' => "$testFolder/phpunit/MediaWikiLangTestCase.php",
- 'NewParserTest' => "$testFolder/phpunit/includes/parser/NewParserTest.php",
+ # tests
+ 'DbTestPreviewer' => "$testDir/testHelpers.inc",
+ 'DbTestRecorder' => "$testDir/testHelpers.inc",
+ 'DelayedParserTest' => "$testDir/testHelpers.inc",
+ 'TestFileIterator' => "$testDir/testHelpers.inc",
+ 'TestRecorder' => "$testDir/testHelpers.inc",
- //includes
- 'BlockTest' => "$testFolder/phpunit/includes/BlockTest.php",
+ # tests/phpunit
+ 'MediaWikiTestCase' => "$testDir/phpunit/MediaWikiTestCase.php",
+ 'MediaWikiPHPUnitCommand' => "$testDir/phpunit/MediaWikiPHPUnitCommand.php",
+ 'MediaWikiLangTestCase' => "$testDir/phpunit/MediaWikiLangTestCase.php",
+ 'MediaWikiProvide' => "$testDir/phpunit/includes/Providers.php",
+ 'TestUser' => "$testDir/phpunit/includes/TestUser.php",
- //API
- 'ApiFormatTestBase' => "$testFolder/phpunit/includes/api/format/ApiFormatTestBase.php",
- 'ApiTestCase' => "$testFolder/phpunit/includes/api/ApiTestCase.php",
- 'TestUser' => "$testFolder/phpunit/includes/TestUser.php",
- 'MockApi' => "$testFolder/phpunit/includes/api/ApiTestCase.php",
- 'RandomImageGenerator' => "$testFolder/phpunit/includes/api/RandomImageGenerator.php",
- 'UserWrapper' => "$testFolder/phpunit/includes/api/ApiTestCase.php",
+ # tests/phpunit/includes
+ 'BlockTest' => "$testDir/phpunit/includes/BlockTest.php",
+ 'RevisionStorageTest' => "$testDir/phpunit/includes/RevisionStorageTest.php",
+ 'WikiPageTest' => "$testDir/phpunit/includes/WikiPageTest.php",
+
+ //db
+ 'ORMTableTest' => "$testDir/phpunit/includes/db/ORMTableTest.php",
//Selenium
- 'SeleniumTestConstants' => "$testFolder/selenium/SeleniumTestConstants.php",
+ 'SeleniumTestConstants' => "$testDir/selenium/SeleniumTestConstants.php",
+
+ # tests/phpunit/includes/api
+ 'ApiFormatTestBase' => "$testDir/phpunit/includes/api/format/ApiFormatTestBase.php",
+ 'ApiTestCase' => "$testDir/phpunit/includes/api/ApiTestCase.php",
+ 'ApiTestContext' => "$testDir/phpunit/includes/api/ApiTestCase.php",
+ 'MockApi' => "$testDir/phpunit/includes/api/ApiTestCase.php",
+ 'RandomImageGenerator' => "$testDir/phpunit/includes/api/RandomImageGenerator.php",
+ 'UserWrapper' => "$testDir/phpunit/includes/api/ApiTestCase.php",
+
+ # tests/phpunit/includes/content
+ 'DummyContentHandlerForTesting' => "$testDir/phpunit/includes/content/ContentHandlerTest.php",
+ 'DummyContentForTesting' => "$testDir/phpunit/includes/content/ContentHandlerTest.php",
+ 'ContentHandlerTest' => "$testDir/phpunit/includes/content/ContentHandlerTest.php",
+ 'JavascriptContentTest' => "$testDir/phpunit/includes/content/JavascriptContentTest.php",
+ 'TextContentTest' => "$testDir/phpunit/includes/content/TextContentTest.php",
+
+ # tests/phpunit/includes/db
+ 'ORMRowTest' => "$testDir/phpunit/includes/db/ORMRowTest.php",
+
+ # tests/phpunit/includes/parser
+ 'NewParserTest' => "$testDir/phpunit/includes/parser/NewParserTest.php",
+
+ # tests/phpunit/includes/libs
+ 'GenericArrayObjectTest' => "$testDir/phpunit/includes/libs/GenericArrayObjectTest.php",
+
+ # tests/phpunit/includes/site
+ 'SiteObjectTest' => "$testDir/phpunit/includes/site/SiteObjectTest.php",
+ 'TestSites' => "$testDir/phpunit/includes/site/TestSites.php",
+
+ # tests/phpunit/languages
+ 'LanguageClassesTestCase' => "$testDir/phpunit/languages/LanguageClassesTestCase.php",
- //maintenance
- 'DumpTestCase' => "$testFolder/phpunit/maintenance/DumpTestCase.php",
- 'BackupDumper' => "$testFolder/../maintenance/backup.inc",
+ # tests/phpunit/maintenance
+ 'DumpTestCase' => "$testDir/phpunit/maintenance/DumpTestCase.php",
- //language
- 'LanguageClassesTestCase' => "$testFolder/phpunit/languages/LanguageClassesTestCase.php",
+ # tests/parser
+ 'ParserTest' => "$testDir/parser/parserTest.inc",
+ 'ParserTestParserHook' => "$testDir/parser/parserTestsParserHook.php",
- //Generic providers
- 'MediaWikiProvide' => "$testFolder/phpunit/includes/Providers.php",
+ # tests/selenium
+ 'Selenium' => "$testDir/selenium/Selenium.php",
+ 'SeleniumLoader' => "$testDir/selenium/SeleniumLoader.php",
+ 'SeleniumTestCase' => "$testDir/selenium/SeleniumTestCase.php",
+ 'SeleniumTestConsoleLogger' => "$testDir/selenium/SeleniumTestConsoleLogger.php",
+ 'SeleniumTestConstants' => "$testDir/selenium/SeleniumTestConstants.php",
+ 'SeleniumTestHTMLLogger' => "$testDir/selenium/SeleniumTestHTMLLogger.php",
+ 'SeleniumTestListener' => "$testDir/selenium/SeleniumTestListener.php",
+ 'SeleniumTestSuite' => "$testDir/selenium/SeleniumTestSuite.php",
+ 'SeleniumConfig' => "$testDir/selenium/SeleniumConfig.php",
);
!! endarticle
!! article
-Template:!
+Template:pipe
!! text
|
!! endarticle
* item 1
!! endarticle
+!! article
+Template:!
+!! text
+|
+!! endarticle
+
!! article
Template:echo
!! text
{{{1}}}="{{{2}}}"
!! endarticle
+!! article
+Template:table_attribs
+!! text
+<noinclude>
+|</noinclude>style="color: red"| Foo
+!! endarticle
+
###
### Basic tests
###
</p>
!! end
+!! test
+</pre> inside nowiki
+!! input
+<nowiki></pre></nowiki>
+!! result
+<p></pre>
+</p>
+!! end
+
!!test
Templates: Pre: 1a. Templates that break a line should suppress <pre>
!!input
!!input
{{echo| foo}}
+{{echo| foo}}{{echo| bar}}
+
{{echo| foo}}
{{echo| bar}}
!!result
<pre>foo
</pre>
+<pre>foo bar
+</pre>
<pre>foo
bar
</pre>
</pre>
!!end
+!! test
+Templates: Pre: 1f: Wrapping should be based on expanded content
+!! input
+{{echo| }}a
+
+{{echo|
+ }}a
+
+{{echo|
+ b}}
+
+{{echo|a
+ }}b
+
+{{echo|a
+}} b
+!!result
+<pre>a
+</pre>
+<p><br />
+</p>
+<pre>a
+</pre>
+<p><br />
+</p>
+<pre>b
+</pre>
+<p>a
+</p>
+<pre>b
+</pre>
+<p>a
+</p>
+<pre>b
+</pre>
+!!end
+
+!! test
+Templates: Single-line variant of parameter whitespace stripping test
+!! input
+{{echo| a}}
+
+{{echo|1= a}}
+
+{{echo|{{echo| a}}}}
+
+{{echo|1={{echo| a}}}}
+!! result
+<pre>a
+</pre>
+<p>a
+</p>
+<pre>a
+</pre>
+<p>a
+</p>
+!! end
+
+!! test
+Templates: Strip whitespace from named parameters, but not positional ones
+!! input
+{{echo|
+ foo}}
+
+{{echo|
+* foo}}
+
+{{echo| 1 =
+ foo}}
+
+{{echo| 1 =
+* foo}}
+!! result
+<pre>foo
+</pre>
+<p><br />
+</p>
+<ul><li> foo
+</li></ul>
+<p>foo
+</p>
+<ul><li> foo
+</li></ul>
+
+!! end
+
###
### Parsoid-centric tests for testing RT edge cases for pre
###
!!end
!!test
-3. Pre and block tags
+3a. Pre and block tags (single-line html)
!!input
<p> foo </p>
<div> foo </div>
</pre>
!!end
+!!test
+3b. Pre and block tags (pre-content on separate line)
+!!input
+<p>
+ foo
+</p>
+
+<div>
+ foo
+</div>
+
+<center>
+ foo
+</center>
+
+<blockquote>
+ foo
+</blockquote>
+
+<table><tr><td>
+ foo
+</td></tr></table>
+
+<ul><li>
+ foo
+</li></ul>
+
+!!result
+<p>
+ foo
+</p>
+<div>
+<pre>foo
+</pre>
+</div>
+<center>
+<pre>foo
+</pre>
+</center>
+<blockquote>
+ foo
+</blockquote>
+<table><tr><td>
+<pre>foo
+</pre>
+</td></tr></table>
+<ul><li>
+ foo
+</li></ul>
+
+!!end
+
!!test
4. Multiple spaces at start-of-line
!!input
Definition and unordered list using wiki syntax nested in unordered list using html tags.
!! input
<ul><li>
-; term : description
+; term : description
* unordered
</li>
</ul>
!! result
<ul><li>
-<dl><dt> term </dt><dd> description
+<dl><dt> term </dt><dd> description
</dd></dl>
<ul><li> unordered
</li></ul>
</p>
!! end
+!! test
+Bracketed external links with template-generated invalid target
+!! input
+[{{echo|http:/example.com}} title]
+!! result
+<p>[http:/example.com title]
+</p>
+!! end
+
!! test
Bug 2702: Mismatched <i>, <b> and <a> tags are invalid
!! input
!! test
Simple table
!! input
-{|
+{|
| 1 || 2
-|-
+|-
| 3 || 4
|}
!! result
!! test
Simple table but with multiple dashes for row wikitext
!! input
-{|
+{|
| foo
|-----
| bar
Table rowspan
!! input
{| border=1
-| Cell 1, row 1
-|rowspan=2| Cell 2, row 1 (and 2)
-| Cell 3, row 1
-|-
-| Cell 1, row 2
-| Cell 3, row 2
+| Cell 1, row 1
+|rowspan=2| Cell 2, row 1 (and 2)
+| Cell 3, row 1
+|-
+| Cell 1, row 2
+| Cell 3, row 2
|}
!! result
<table border="1">
!! end
+!! test
+Template-generated table cell attributes and cell content
+!! input
+{|
+|{{table_attribs}}
+|}
+!! result
+<table>
+<tr>
+<td style="color: red"> Foo
+</td></tr></table>
+
+!! end
###
### Internal links
</p>
!! end
+!! test
+Broken br tag sanitization
+!! input
+</br>
+!! result
+<p></br>
+</p>
+!! end
+
!! test
Incorrecly removing closing slashes from correctly formed XHTML
!! input
!! test
BUG 553: link with two variables in a piped link
!! input
-{|
+{|
|[[{{{1}}}|{{{2}}}]]
|}
!! result
!! article
Template:table
!! text
-{|
+{|
| 1 || 2
-|-
+|-
| 3 || 4
|}
!! endarticle
!!end
!!test
-Templates: Tables: 1. Generating start of a HTML table
+Templates: HTML Tables: 1. Generating start of a HTML table
!!input
{{echo|<table><tr><td>foo</td>}}</tr></table>
!!result
!!end
!!test
-Templates: Tables: 2a. Generating middle of a HTML table
+Templates: HTML Tables: 2a. Generating middle of a HTML table
!!input
<table><tr>{{echo|<td>foo</td>}}</tr></table>
!!result
!!end
!!test
-Templates: Tables: 2b. Generating middle of a HTML table
+Templates: HTML Tables: 2b. Generating middle of a HTML table
!!input
<table>{{echo|<tr><td>foo</td></tr>}}</table>
!!result
!!end
!!test
-Templates: Tables: 3. Generating end of a HTML table
+Templates: HTML Tables: 3. Generating end of a HTML table
!!input
<table><tr>{{echo|<td>foo</td></tr></table>}}
!!result
!!end
!!test
-Templates: Tables: 4a. Generating a single tag of a HTML table
+Templates: HTML Tables: 4a. Generating a single tag of a HTML table
!!input
{{echo|<table>}}<tr><td>foo</td></tr></table>
!!result
!!end
!!test
-Templates: Tables: 4b. Generating a single tag of a HTML table
+Templates: HTML Tables: 4b. Generating a single tag of a HTML table
!!input
<table>{{echo|<tr>}}<td>foo</td></tr></table>
!!result
!!end
!!test
-Templates: Tables: 4c. Generating a single tag of a HTML table
+Templates: HTML Tables: 4c. Generating a single tag of a HTML table
!!input
<table><tr>{{echo|<td>}}foo</td></tr></table>
!!result
!!end
!!test
-Templates: Tables: 4d. Generating a single tag of a HTML table
+Templates: HTML Tables: 4d. Generating a single tag of a HTML table
!!input
<table><tr><td>foo{{echo|</td>}}</tr></table>
!!result
!!end
!!test
-Templates: Tables: 4e. Generating a single tag of a HTML table
+Templates: HTML Tables: 4e. Generating a single tag of a HTML table
!!input
<table><tr><td>foo</td>{{echo|</tr>}}</table>
!!result
!!end
!!test
-Templates: Tables: 4f. Generating a single tag of a HTML table
+Templates: HTML Tables: 4f. Generating a single tag of a HTML table
!!input
<table><tr><td>foo</td></tr>{{echo|</table>}}
!!result
!!end
+!!test
+Templates: Wiki Tables: 1. Fostering of entire template content
+!!input
+{|
+{{echo|a}}
+|}
+!!result
+<table>
+a
+<tr><td></td></tr></table>
+
+!!end
+
+!!test
+Templates: Wiki Tables: 2. Fostering of partial template content
+!!input
+{|
+{{echo|a
+<div>b</div>}}
+|}
+!!result
+<table>
+a
+<div>b</div>
+<tr><td></td></tr></table>
+
+!!end
+
+!!test
+Templates: Wiki Tables: 3. td-content via multiple templates
+!!input
+{|
+{{echo|{{pipe}}a}}{{echo|b}}
+|}
+!!result
+<table>
+<tr>
+<td>ab
+</td></tr></table>
+
+!!end
+
+!!test
+Templates: Lists: Multi-line list-items via templates
+!!input
+*{{echo|a {{nonexistent|
+unused}}}}
+*{{echo|b {{nonexistent|
+unused}}}}
+!!result
+<ul><li>a <a href="/index.php?title=Template:Nonexistent&action=edit&redlink=1" class="new" title="Template:Nonexistent (page does not exist)">Template:Nonexistent</a>
+</li><li>b <a href="/index.php?title=Template:Nonexistent&action=edit&redlink=1" class="new" title="Template:Nonexistent (page does not exist)">Template:Nonexistent</a>
+</li></ul>
+
+!!end
+
!!test
Templates: Ugly nesting: 1. Quotes opened/closed across templates (echo)
!!input
[[Category:{{echo|Foo}}|{{echo|Bar}}]]
!! end
+!! test
+Category / paragraph interactions
+!! input
+Foo [[Category:Baz]] Bar
+
+Foo [[Category:Baz]]
+Bar
+
+Foo
+[[Category:Baz]]
+Bar
+
+Foo
+[[Category:Baz]] Bar
+
+Foo
+[[Category:Baz]]
+ [[Category:Baz]]
+[[Category:Baz]]
+Bar
+
+[[Category:Baz]]
+ [[Category:Baz]]
+[[Category:Baz]]
+
+[[Category:Baz]]
+ {{echo|[[Category:Baz]]}}
+[[Category:Baz]]
+!! result
+<p>Foo Bar
+</p><p>Foo
+Bar
+</p><p>Foo
+Bar
+</p><p>Foo Bar
+</p><p>Foo
+Bar
+</p>
+!! end
+
###
### Inter-language links
###
!! end
+# Plain MediaWiki does not remove empty lists, but tidy actually does.
+# Templates in Wikipedia rely on this behavior, as tidy has always been
+# enabled there. These tests are normally run *without* tidy, so specify the
+# full output here.
+# To test realistic parsing behavior, apply a tidy-like transformation to both
+# the expected output and your parser's output.
+!! test
+Bug 529: Uncovered bullet leaving empty list, normally removed by tidy
+!! input
+******* Foo {{bullet}}
+!! result
+<ul><li><ul><li><ul><li><ul><li><ul><li><ul><li><ul><li> Foo
+</li></ul>
+</li></ul>
+</li></ul>
+</li></ul>
+</li></ul>
+</li></ul>
+</li><li> Bar
+</li></ul>
+
+!! end
+
!! test
Bug 529: Uncovered table already at line-start
!! input
!!end
!! test
-Headings: 1. Nested inside html
+Headings: 1. Nested inside html
!! options
disabled
!! input
!!end
!! test
-Headings: 3. Nested inside html with wikitext split by html tags
+Headings: 3. Nested inside html with wikitext split by html tags
!! options
disabled
!! input
#### ----------------------------------------
!! test
-Lists: 0. Outside nests
+Lists: 0. Outside nests
!! input
<nowiki>*foo</nowiki>
!!end
!! test
-Lists: 7. Escape bullets in a multi-line context
+Lists: 7. Escape bullets in a multi-line context
!! input
<nowiki>a
*b</nowiki>
#### -----------------------------------
!! test
-HRs: 1. Single line
+HRs: 1. Single line
!! options
disabled
!! input
!! test
2. Link fragments inside <i> and <b>
-(FIXME: Escaping one or both of [[ and ]] is also acceptable --
+(FIXME: Escaping one or both of [[ and ]] is also acceptable --
this is one of the shortcomings of this format)
!! input
''[[foo''<nowiki>]]</nowiki>
--- /dev/null
+<?php
+class AutoLoaderTest extends MediaWikiTestCase {
+
+ public function testAutoLoadConfig() {
+ $results = self::checkAutoLoadConf();
+
+ $this->assertEquals(
+ $results['expected'],
+ $results['actual']
+ );
+ }
+
+ protected static function checkAutoLoadConf() {
+ global $wgAutoloadLocalClasses, $wgAutoloadClasses, $IP;
+ static $supportsParsekit;
+ $supportsParsekit = function_exists( 'parsekit_compile_file' );
+
+ // wgAutoloadLocalClasses has precedence, just like in includes/AutoLoader.php
+ $expected = $wgAutoloadLocalClasses + $wgAutoloadClasses;
+ $actual = array();
+
+ $files = array_unique( $expected );
+
+ foreach ( $files as $file ) {
+ // Only prefix $IP if it doesn't have it already.
+ // Generally local classes don't have it, and those from extensions and test suites do.
+ if ( substr( $file, 0, 1 ) != '/' && substr( $file, 1, 1 ) != ':' ) {
+ $filePath = "$IP/$file";
+ } else {
+ $filePath = $file;
+ }
+ if ( $supportsParsekit ) {
+ $parseInfo = parsekit_compile_file( "$filePath" );
+ $classes = array_keys( $parseInfo['class_table'] );
+ } else {
+ $contents = file_get_contents( "$filePath" );
+ $m = array();
+ preg_match_all( '/\n\s*(?:final)?\s*(?:abstract)?\s*(?:class|interface)\s+([a-zA-Z0-9_]+)/', $contents, $m, PREG_PATTERN_ORDER );
+ $classes = $m[1];
+ }
+ foreach ( $classes as $class ) {
+ $actual[$class] = $file;
+ }
+ }
+
+ return array(
+ 'expected' => $expected,
+ 'actual' => $actual,
+ );
+ }
+}
$dom = new DomDocument();
$dom->load( $fname );
+ // Ensure, the demo is for the current version
+ $this->assertEquals( $dom->documentElement->getAttribute( 'version' ), $version, 'export-demo.xml should have the current version' );
+
try {
$this->assertTrue( $dom->schemaValidate( "../../docs/export-" . $version . ".xsd" ),
"schemaValidate has found an error" );
<?php
/**
- * @group Editing
+ * @group Editing
+ *
+ * @group Database
+ * ^--- tell jenkins this test needs the database
+ *
+ * @group medium
+ * ^--- tell phpunit that these test cases may take longer than 2 seconds.
*/
class EditPageTest extends MediaWikiTestCase {
),
);
}
+
+ protected function forceRevisionDate( WikiPage $page, $timestamp ) {
+ $dbw = wfGetDB( DB_MASTER );
+
+ $dbw->update( 'revision',
+ array( 'rev_timestamp' => $timestamp ),
+ array( 'rev_id' => $page->getLatest() ) );
+
+ $page->clear();
+ }
+
+ /**
+ * User input text is passed to rtrim() by edit page. This is a simple
+ * wrapper around assertEquals() which calls rrtrim() to normalize the
+ * expected and actual texts.
+ */
+ function assertEditedTextEquals( $expected, $actual, $msg='' ) {
+ return $this->assertEquals( rtrim($expected), rtrim($actual), $msg );
+ }
+
+ /**
+ * Performs an edit and checks the result.
+ *
+ * @param String|Title $title The title of the page to edit
+ * @param String|null $baseText Some text to create the page with before attempting the edit.
+ * @param User|String|null $user The user to perform the edit as.
+ * @param array $edit An array of request parameters used to define the edit to perform.
+ * Some well known fields are:
+ * * wpTextbox1: the text to submit
+ * * wpSummary: the edit summary
+ * * wpEditToken: the edit token (will be inserted if not provided)
+ * * wpEdittime: timestamp of the edit's base revision (will be inserted if not provided)
+ * * wpStarttime: timestamp when the edit started (will be inserted if not provided)
+ * * wpSectionTitle: the section to edit
+ * * wpMinorEdit: mark as minor edit
+ * * wpWatchthis: whether to watch the page
+ * @param int|null $expectedCode The expected result code (EditPage::AS_XXX constants).
+ * Set to null to skip the check. Defaults to EditPage::AS_OK.
+ * @param String|null $expectedText The text expected to be on the page after the edit.
+ * Set to null to skip the check.
+ * @param String|null $message An optional message to show along with any error message.
+ *
+ * @return WikiPage The page that was just edited, useful for getting the edit's rev_id, etc.
+ */
+ protected function assertEdit( $title, $baseText, $user = null, array $edit,
+ $expectedCode = EditPage::AS_OK, $expectedText = null, $message = null
+ ) {
+ if ( is_string( $title ) ) {
+ $ns = $this->getDefaultWikitextNS();
+ $title = Title::newFromText( $title, $ns );
+ }
+
+ if ( is_string( $user ) ) {
+ $user = User::newFromName( $user );
+
+ if ( $user->getId() === 0 ) {
+ $user->addToDatabase();
+ }
+ }
+
+ $page = WikiPage::factory( $title );
+
+ if ( $baseText !== null ) {
+ $content = ContentHandler::makeContent( $baseText, $title );
+ $page->doEditContent( $content, "base text for test" );
+ $this->forceRevisionDate( $page, '20120101000000' );
+
+ //sanity check
+ $page->clear();
+ $currentText = ContentHandler::getContentText( $page->getContent() );
+
+ # EditPage rtrim() the user input, so we alter our expected text
+ # to reflect that.
+ $this->assertEditedTextEquals( $baseText, $currentText );
+ }
+
+ if ( $user == null ) {
+ $user = $GLOBALS['wgUser'];
+ } else {
+ $this->setMwGlobals( 'wgUser', $user );
+ }
+
+ if ( !isset( $edit['wpEditToken'] ) ) {
+ $edit['wpEditToken'] = $user->getEditToken();
+ }
+
+ if ( !isset( $edit['wpEdittime'] ) ) {
+ $edit['wpEdittime'] = $page->exists() ? $page->getTimestamp() : '';
+ }
+
+ if ( !isset( $edit['wpStarttime'] ) ) {
+ $edit['wpStarttime'] = wfTimestampNow();
+ }
+
+ $req = new FauxRequest( $edit, true ); // session ??
+
+ $ep = new EditPage( new Article( $title ) );
+ $ep->setContextTitle( $title );
+ $ep->importFormData( $req );
+
+ $bot = isset( $edit['bot'] ) ? (bool)$edit['bot'] : false;
+
+ // this is where the edit happens!
+ // Note: don't want to use EditPage::AttemptSave, because it messes with $wgOut
+ // and throws exceptions like PermissionsError
+ $status = $ep->internalAttemptSave( $result, $bot );
+
+ if ( $expectedCode !== null ) {
+ // check edit code
+ $this->assertEquals( $expectedCode, $status->value,
+ "Expected result code mismatch. $message" );
+ }
+
+ $page = WikiPage::factory( $title );
+
+ if ( $expectedText !== null ) {
+ // check resulting page text
+ $content = $page->getContent();
+ $text = ContentHandler::getContentText( $content );
+
+ # EditPage rtrim() the user input, so we alter our expected text
+ # to reflect that.
+ $this->assertEditedTextEquals( $expectedText, $text,
+ "Expected article text mismatch. $message" );
+ }
+
+ return $page;
+ }
+
+ public function testCreatePage() {
+ $text = "Hello World!";
+ $edit = array(
+ 'wpTextbox1' => $text,
+ 'wpSummary' => 'just testing',
+ );
+
+ $this->assertEdit( 'EditPageTest_testCreatePafe', null, null, $edit,
+ EditPage::AS_SUCCESS_NEW_ARTICLE, $text,
+ "expected successfull creation with given text" );
+ }
+
+ public function testUpdatePage() {
+ $text = "one";
+ $edit = array(
+ 'wpTextbox1' => $text,
+ 'wpSummary' => 'first update',
+ );
+
+ $page = $this->assertEdit( 'EditPageTest_testUpdatePage', "zero", null, $edit,
+ EditPage::AS_SUCCESS_UPDATE, $text,
+ "expected successfull update with given text" );
+
+ $this->forceRevisionDate( $page, '20120101000000' );
+
+ $text = "two";
+ $edit = array(
+ 'wpTextbox1' => $text,
+ 'wpSummary' => 'second update',
+ );
+
+ $this->assertEdit( 'EditPageTest_testUpdatePage', null, null, $edit,
+ EditPage::AS_SUCCESS_UPDATE, $text,
+ "expected successfull update with given text" );
+ }
+
+ public static function provideSectionEdit() {
+ $text =
+'Intro
+
+== one ==
+first section.
+
+== two ==
+second section.
+';
+
+ $sectionOne =
+'== one ==
+hello
+';
+
+ $newSection =
+'== new section ==
+
+hello
+';
+
+ $textWithNewSectionOne = preg_replace( '/== one ==.*== two ==/ms',
+ "$sectionOne\n== two ==", $text );
+
+ $textWithNewSectionAdded = "$text\n$newSection";
+
+ return array(
+ array( #0
+ $text,
+ '',
+ 'hello',
+ 'replace all',
+ 'hello'
+ ),
+
+ array( #1
+ $text,
+ '1',
+ $sectionOne,
+ 'replace first section',
+ $textWithNewSectionOne,
+ ),
+
+ array( #2
+ $text,
+ 'new',
+ 'hello',
+ 'new section',
+ $textWithNewSectionAdded,
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider provideSectionEdit
+ */
+ public function testSectionEdit( $base, $section, $text, $summary, $expected ) {
+ $edit = array(
+ 'wpTextbox1' => $text,
+ 'wpSummary' => $summary,
+ 'wpSection' => $section,
+ );
+
+ $this->assertEdit( 'EditPageTest_testSectionEdit', $base, null, $edit,
+ EditPage::AS_SUCCESS_UPDATE, $expected,
+ "expected successfull update of section" );
+ }
+
+ public static function provideAutoMerge() {
+ $tests = array();
+
+ $tests[] = array( #0: plain conflict
+ "Elmo", # base edit user
+ "one\n\ntwo\n\nthree\n",
+ array( #adam's edit
+ 'wpStarttime' => 1,
+ 'wpTextbox1' => "ONE\n\ntwo\n\nthree\n",
+ ),
+ array( #berta's edit
+ 'wpStarttime' => 2,
+ 'wpTextbox1' => "(one)\n\ntwo\n\nthree\n",
+ ),
+ EditPage::AS_CONFLICT_DETECTED, # expected code
+ "ONE\n\ntwo\n\nthree\n", # expected text
+ 'expected edit conflict', # message
+ );
+
+ $tests[] = array( #1: successful merge
+ "Elmo", # base edit user
+ "one\n\ntwo\n\nthree\n",
+ array( #adam's edit
+ 'wpStarttime' => 1,
+ 'wpTextbox1' => "ONE\n\ntwo\n\nthree\n",
+ ),
+ array( #berta's edit
+ 'wpStarttime' => 2,
+ 'wpTextbox1' => "one\n\ntwo\n\nTHREE\n",
+ ),
+ EditPage::AS_SUCCESS_UPDATE, # expected code
+ "ONE\n\ntwo\n\nTHREE\n", # expected text
+ 'expected automatic merge', # message
+ );
+
+ $text = "Intro\n\n";
+ $text .= "== first section ==\n\n";
+ $text .= "one\n\ntwo\n\nthree\n\n";
+ $text .= "== second section ==\n\n";
+ $text .= "four\n\nfive\n\nsix\n\n";
+
+ // extract the first section.
+ $section = preg_replace( '/.*(== first section ==.*)== second section ==.*/sm', '$1', $text );
+
+ // generate expected text after merge
+ $expected = str_replace( 'one', 'ONE', str_replace( 'three', 'THREE', $text ) );
+
+ $tests[] = array( #2: merge in section
+ "Elmo", # base edit user
+ $text,
+ array( #adam's edit
+ 'wpStarttime' => 1,
+ 'wpTextbox1' => str_replace( 'one', 'ONE', $section ),
+ 'wpSection' => '1'
+ ),
+ array( #berta's edit
+ 'wpStarttime' => 2,
+ 'wpTextbox1' => str_replace( 'three', 'THREE', $section ),
+ 'wpSection' => '1'
+ ),
+ EditPage::AS_SUCCESS_UPDATE, # expected code
+ $expected, # expected text
+ 'expected automatic section merge', # message
+ );
+
+ // see whether it makes a difference who did the base edit
+ $testsWithAdam = array_map( function( $test ) {
+ $test[0] = 'Adam'; // change base edit user
+ return $test;
+ }, $tests );
+
+ $testsWithBerta = array_map( function( $test ) {
+ $test[0] = 'Berta'; // change base edit user
+ return $test;
+ }, $tests );
+
+ return array_merge( $tests, $testsWithAdam, $testsWithBerta );
+ }
+
+ function testHasValidDiff3() {
+ global $wgDiff3;
+
+ if ( !$wgDiff3 ) {
+ $this->markTestSkipped( "Can't test conflict resolution because \$wgDiff3 is not configured" );
+ } elseif ( !file_exists( $wgDiff3 ) ) {
+ #XXX: this sucks, since it uses arcane internal knowledge about TextContentHandler::merge3 and wfMerge.
+ $this->markTestSkipped( "Can't test conflict resolution because \$wgDiff3 is misconfigured: can't find $wgDiff3" );
+ }
+ $this->assertTrue( true );
+ }
+
+ /**
+ * @depend testHasValidDiff3
+ * @dataProvider provideAutoMerge
+ */
+ public function testAutoMerge( $baseUser, $text, $adamsEdit, $bertasEdit,
+ $expectedCode, $expectedText, $message = null
+ ) {
+
+ //create page
+ $ns = $this->getDefaultWikitextNS();
+ $title = Title::newFromText( 'EditPageTest_testAutoMerge', $ns );
+ $page = WikiPage::factory( $title );
+
+ if ( $page->exists() ) {
+ $page->doDeleteArticle( "clean slate for testing" );
+ }
+
+ $baseEdit = array(
+ 'wpTextbox1' => $text,
+ );
+
+ $page = $this->assertEdit( 'EditPageTest_testAutoMerge', null,
+ $baseUser, $baseEdit, null, null, __METHOD__ );
+
+ $this->forceRevisionDate( $page, '20120101000000' );
+
+ $edittime = $page->getTimestamp();
+
+ // start timestamps for conflict detection
+ if ( !isset( $adamsEdit['wpStarttime'] ) ) {
+ $adamsEdit['wpStarttime'] = 1;
+ }
+
+ if ( !isset( $bertasEdit['wpStarttime'] ) ) {
+ $bertasEdit['wpStarttime'] = 2;
+ }
+
+ $starttime = wfTimestampNow();
+ $adamsTime = wfTimestamp( TS_MW, (int)wfTimestamp( TS_UNIX, $starttime ) + (int)$adamsEdit['wpStarttime'] );
+ $bertasTime = wfTimestamp( TS_MW, (int)wfTimestamp( TS_UNIX, $starttime ) + (int)$bertasEdit['wpStarttime'] );
+
+ $adamsEdit['wpStarttime'] = $adamsTime;
+ $bertasEdit['wpStarttime'] = $bertasTime;
+
+ $adamsEdit['wpSummary'] = 'Adam\'s edit';
+ $bertasEdit['wpSummary'] = 'Bertas\'s edit';
+
+ $adamsEdit['wpEdittime'] = $edittime;
+ $bertasEdit['wpEdittime'] = $edittime;
+
+ // first edit
+ $this->assertEdit( 'EditPageTest_testAutoMerge', null, 'Adam', $adamsEdit,
+ EditPage::AS_SUCCESS_UPDATE, null, "expected successfull update" );
+
+ // second edit
+ $this->assertEdit( 'EditPageTest_testAutoMerge', null, 'Berta', $bertasEdit,
+ $expectedCode, $expectedText, $message );
+ }
}
);
}
+ /**
+ * @param String $old: Text as it was in the database
+ * @param String $mine: Text submitted while user was editing
+ * @param String $yours: Text submitted by the user
+ * @param Boolean $expectedMergeResult Whether the merge should be a success
+ * @param String $expectedText: Text after merge has been completed
+ *
+ * @dataProvider provideMerge()
+ */
+ public function testMerge( $old, $mine, $yours, $expectedMergeResult, $expectedText ) {
+ $mergedText = null;
+ $isMerged = wfMerge( $old, $mine, $yours, $mergedText );
+
+ $msg = 'Merge should be a ';
+ $msg .= $expectedMergeResult ? 'success' : 'failure';
+ $this->assertEquals( $expectedMergeResult, $isMerged, $msg );
+
+ if( $isMerged ) {
+ // Verify the merged text
+ $this->assertEquals( $expectedText, $mergedText,
+ 'is merged text as expected?' );
+ }
+ }
+
+ public static function provideMerge() {
+ $EXPECT_MERGE_SUCCESS = true;
+ $EXPECT_MERGE_FAILURE = false;
+
+ return array(
+
+ // #0: clean merge
+ array(
+ // old:
+ "one one one\n" . // trimmed
+ "\n" .
+ "two two two",
+
+ // mine:
+ "one one one ONE ONE\n" .
+ "\n" .
+ "two two two\n", // with tailing whitespace
+
+ // yours:
+ "one one one\n" .
+ "\n" .
+ "two two TWO TWO", // trimmed
+
+ // ok:
+ $EXPECT_MERGE_SUCCESS,
+
+ // result:
+ "one one one ONE ONE\n" .
+ "\n" .
+ "two two TWO TWO\n", // note: will always end in a newline
+ ),
+
+ // #1: conflict, fail
+ array(
+ // old:
+ "one one one", // trimmed
+
+ // mine:
+ "one one one ONE ONE\n" .
+ "\n" .
+ "bla bla\n" .
+ "\n", // with tailing whitespace
+
+ // yours:
+ "one one one\n" .
+ "\n" .
+ "two two", // trimmed
+
+ $EXPECT_MERGE_FAILURE,
+
+ // result:
+ null,
+ ),
+ );
+ }
+
/**
* @dataProvider provideMakeUrlIndexes()
*/
--- /dev/null
+<?php
+
+class RequestContextTest extends MediaWikiTestCase {
+
+ /**
+ * Test the relationship between title and wikipage in RequestContext
+ */
+ public function testWikiPageTitle() {
+ $context = new RequestContext();
+
+ $curTitle = Title::newFromText( "A" );
+ $context->setTitle( $curTitle );
+ $this->assertTrue( $curTitle->equals( $context->getWikiPage()->getTitle() ),
+ "When a title is first set WikiPage should be created on-demand for that title." );
+
+ $curTitle = Title::newFromText( "B" );
+ $context->setWikiPage( WikiPage::factory( $curTitle ) );
+ $this->assertTrue( $curTitle->equals( $context->getTitle() ),
+ "Title must be updated when a new WikiPage is provided." );
+
+ $curTitle = Title::newFromText( "C" );
+ $context->setTitle( $curTitle );
+ $this->assertTrue( $curTitle->equals( $context->getWikiPage()->getTitle() ),
+ "When a title is updated the WikiPage should be purged and recreated on-demand with the new title." );
+
+ }
+
+}
$this->assertEquals( 'hello hello.', $rev->getText() );
}
+ /**
+ * @covers Revision::getContent
+ */
+ public function testGetContent_failure()
+ {
+ $rev = new Revision( array(
+ 'page' => $this->the_page->getId(),
+ 'content_model' => $this->the_page->getContentModel(),
+ 'text_id' => 123456789, // not in the test DB
+ ) );
+
+ $this->assertNull( $rev->getContent(),
+ "getContent() should return null if the revision's text blob could not be loaded." );
+
+ //NOTE: check this twice, once for lazy initialization, and once with the cached value.
+ $this->assertNull( $rev->getContent(),
+ "getContent() should return null if the revision's text blob could not be loaded." );
+ }
+
/**
* @covers Revision::getContent
*/
# - wgDefaultLanguageVariant
# - Optional message
return array(
- array( 'fr', 'Main_page', 'fr', 'fr', false ),
- array( 'es', 'Main_page', 'es', 'zh-tw', false ),
- array( 'zh', 'Main_page', 'zh', 'zh-tw', false ),
+ array( 'fr', 'Help:I_need_somebody', 'fr', 'fr', false ),
+ array( 'es', 'Help:I_need_somebody', 'es', 'zh-tw', false ),
+ array( 'zh', 'Help:I_need_somebody', 'zh', 'zh-tw', false ),
- array( 'es', 'Main_page', 'es', 'zh-tw', 'zh-cn' ),
+ array( 'es', 'Help:I_need_somebody', 'es', 'zh-tw', 'zh-cn' ),
array( 'es', 'MediaWiki:About', 'es', 'zh-tw', 'zh-cn' ),
array( 'es', 'MediaWiki:About/', 'es', 'zh-tw', 'zh-cn' ),
array( 'de', 'MediaWiki:About/de', 'es', 'zh-tw', 'zh-cn' ),
array( 'en', 'User:JohnDoe/Common.js', 'es', 'zh-tw', 'zh-cn' ),
array( 'en', 'User:JohnDoe/Monobook.css', 'es', 'zh-tw', 'zh-cn' ),
- array( 'zh-cn', 'Main_page', 'zh', 'zh-tw', 'zh-cn' ),
+ array( 'zh-cn', 'Help:I_need_somebody', 'zh', 'zh-tw', 'zh-cn' ),
array( 'zh', 'MediaWiki:About', 'zh', 'zh-tw', 'zh-cn' ),
array( 'zh', 'MediaWiki:About/', 'zh', 'zh-tw', 'zh-cn' ),
array( 'de', 'MediaWiki:About/de', 'zh', 'zh-tw', 'zh-cn' ),
$user->addToDatabase();
// let the user have a few (3) edits
- $page = WikiPage::factory( Title::newFromText( 'UserTest_EditCount' ) );
+ $page = WikiPage::factory( Title::newFromText( 'Help:UserTest_EditCount' ) );
for( $i = 0; $i < 3; $i++ ) {
$page->doEdit( (string) $i, 'test', 0, false, $user );
}
}
+ /**
+ * Does the API request and returns the result.
+ *
+ * The returned value is an array containing
+ * - the result data (array)
+ * - the request (WebRequest)
+ * - the session data of the request (array)
+ * - if $appendModule is true, the Api module $module
+ *
+ * @param array $params
+ * @param array|null $session
+ * @param bool $appendModule
+ * @param User|null $user
+ *
+ * @return array
+ */
protected function doApiRequest( array $params, array $session = null, $appendModule = false, User $user = null ) {
global $wgRequest, $wgUser;
if ( is_null( $session ) ) {
- # re-use existing global session by default
+ // re-use existing global session by default
$session = $wgRequest->getSessionArray();
}
- # set up global environment
+ // set up global environment
if ( $user ) {
$wgUser = $user;
}
$wgRequest = new FauxRequest( $params, true, $session );
RequestContext::getMain()->setRequest( $wgRequest );
- # set up local environment
+ // set up local environment
$context = $this->apiContext->newTestContext( $wgRequest, $wgUser );
$module = new ApiMain( $context, true );
- # run it!
+ // run it!
$module->execute();
- # construct result
+ // construct result
$results = array(
$module->getResultData(),
$context->getRequest(),
$context->getRequest()->getSessionArray()
);
- if( $appendModule ) {
+
+ if ( $appendModule ) {
$results[] = $module;
}
CONTENT_MODEL_WIKITEXT,
CONTENT_MODEL_CSS,
CONTENT_MODEL_JAVASCRIPT,
- )
+ ),
+ 'wgAlwaysUseTidy' => false,
) );
$this->context = new RequestContext( new FauxRequest() );
}
}
+ public static function provideConvert() {
+ return array(
+ array( // #0
+ 'Hallo Welt',
+ CONTENT_MODEL_WIKITEXT,
+ 'lossless',
+ 'Hallo Welt'
+ ),
+ array( // #1
+ 'Hallo Welt',
+ CONTENT_MODEL_WIKITEXT,
+ 'lossless',
+ 'Hallo Welt'
+ ),
+ array( // #1
+ 'Hallo Welt',
+ CONTENT_MODEL_CSS,
+ 'lossless',
+ 'Hallo Welt'
+ ),
+ array( // #1
+ 'Hallo Welt',
+ CONTENT_MODEL_JAVASCRIPT,
+ 'lossless',
+ 'Hallo Welt'
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider provideConvert
+ */
+ public function testConvert( $text, $model, $lossy, $expectedNative ) {
+ $content = $this->newContent( $text );
+
+ $converted = $content->convert( $model, $lossy );
+
+ if ( $expectedNative === false ) {
+ $this->assertFalse( $converted, "conversion to $model was expected to fail!" );
+ } else {
+ $this->assertInstanceOf( 'Content', $converted );
+ $this->assertEquals( $expectedNative, $converted->getNativeData() );
+ }
+ }
+
}
/**
* @dataProvider constructorTestProvider
+ * @depends testSave()
*/
public function testRemove( array $data, $loadDefaults ) {
$item = $this->getRowInstance( $data, $loadDefaults );
- $this->assertTrue( $item->save() );
-
$this->assertTrue( $item->remove() );
$this->assertFalse( $item->hasIdField() );
--- /dev/null
+<?php
+/**
+ * Abstract class to construct tests for ORMTable deriving classes.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @since 1.21
+ *
+ * @ingroup Test
+ *
+ * @group ORM
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+abstract class ORMTableTest extends MediaWikiTestCase {
+
+ /**
+ * @since 1.21
+ * @return string
+ */
+ protected abstract function getTableClass();
+
+ /**
+ * @since 1.21
+ * @return IORMTable
+ */
+ public function getTable() {
+ $class = $this->getTableClass();
+ return $class::singleton();
+ }
+
+ /**
+ * @since 1.21
+ * @return string
+ */
+ public function getRowClass() {
+ return $this->getTable()->getRowClass();
+ }
+
+ /**
+ * @since 1.21
+ */
+ public function testSingleton() {
+ $class = $this->getTableClass();
+
+ $this->assertInstanceOf( $class, $class::singleton() );
+ $this->assertTrue( $class::singleton() === $class::singleton() );
+ }
+
+}
array(
array(
'name' => 'Foobar',
+ 'time' => '20120101020202',
'age' => 42,
'height' => 9000.1,
'awesome' => true,
$this->assertEquals( null, $tmpFile, "Local ref of not existing file is null ($backendName)." );
}
+ /**
+ * @dataProvider provider_testGetFileHttpUrl
+ */
+ public function testGetFileHttpUrl( $source, $content ) {
+ $this->backend = $this->singleBackend;
+ $this->tearDownFiles();
+ $this->doTestGetFileHttpUrl( $source, $content );
+ $this->tearDownFiles();
+
+ $this->backend = $this->multiBackend;
+ $this->tearDownFiles();
+ $this->doTestGetFileHttpUrl( $source, $content );
+ $this->tearDownFiles();
+ }
+
+ private function doTestGetFileHttpUrl( $source, $content ) {
+ $backendName = $this->backendClass();
+
+ $this->prepare( array( 'dir' => dirname( $source ) ) );
+ $status = $this->backend->doOperation(
+ array( 'op' => 'create', 'content' => $content, 'dst' => $source ) );
+ $this->assertGoodStatus( $status,
+ "Creation of file at $source succeeded ($backendName)." );
+
+ $url = $this->backend->getFileHttpUrl( array( 'src' => $source ) );
+
+ if ( $url !== null ) { // supported
+ $data = Http::request( "GET", $url );
+ $this->assertEquals( $content, $data,
+ "HTTP GET of URL has right contents ($backendName)." );
+ }
+ }
+
+ function provider_testGetFileHttpUrl() {
+ $cases = array();
+
+ $base = self::baseStorePath();
+ $cases[] = array( "$base/unittest-cont1/e/a/z/some_file.txt", "some file contents" );
+ $cases[] = array( "$base/unittest-cont1/e/a/some-other_file.txt", "more file contents" );
+ $cases[] = array( "$base/unittest-cont1/e/a/\$odd&.txt", "test file contents" );
+
+ return $cases;
+ }
+
/**
* @dataProvider provider_testPrepareAndClean
*/
public static function provideBadNames() {
return array( array( "foo<bar" ), array( "foo>bar" ), array( "foo\nbar" ), array( "foo\rbar" ) );
}
-
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->setMwGlobals( 'wgAlwaysUseTidy', false );
+ }
+
/**
* @dataProvider provideValidNames
*/
* @ingroup Test
*
* @group Site
+ * @group Database
*
* @licence GNU GPL v2+
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
public function constructorTestProvider() {
$argLists = array();
- $argLists[] = array( 'global_key' => '42' );
+ $argLists[] = array( 'global_key' => 'foo' );
- $argLists[] = array( 'global_key' => '42', 'type' => Site::TYPE_MEDIAWIKI );
+ $argLists[] = array( 'global_key' => 'bar', 'type' => Site::TYPE_MEDIAWIKI );
$constructorArgs = array();
$this->assertEquals( $path, $site->getPath( 'foo' ) );
}
+ public function testProtocolRelativePath() {
+ /* @var SiteObject $site */
+ $site = $this->getRowInstance( $this->getMockFields(), false );
+
+ $type = $site->getLinkPathType();
+ $path = '//acme.com/'; // protocol-relative URL
+ $site->setPath( $type, $path );
+
+ $this->assertEquals( '', $site->getProtocol() );
+ }
+
public function provideGetPageUrl() {
//NOTE: the assumption that the URL is built by replacing $1
// with the urlencoded version of $page
array( 'other', 3 ), // Plural
);
}
+
+ /** @dataProvider providerGrammar */
+ function testGrammar( $result, $word, $case ) {
+ $this->assertEquals( $result, $this->getLang()->convertGrammar( $word, $case ) );
+ }
+
+ // The comments in the beginning of the line help avoid RTL problems
+ // with text editors.
+ function providerGrammar() {
+ return array (
+ array(
+ /* result */ 'וויקיפדיה',
+ /* word */ 'ויקיפדיה',
+ /* case */ 'תחילית',
+ ),
+ array(
+ /* result */ 'וולפגנג',
+ /* word */ 'וולפגנג',
+ /* case */ 'prefixed',
+ ),
+ array(
+ /* result */ 'קובץ',
+ /* word */ 'הקובץ',
+ /* case */ 'תחילית',
+ ),
+ array(
+ /* result */ '־Wikipedia',
+ /* word */ 'Wikipedia',
+ /* case */ 'תחילית',
+ ),
+ array(
+ /* result */ '־1995',
+ /* word */ '1995',
+ /* case */ 'תחילית',
+ ),
+ );
+ }
}
-mw.loader.testCallback();
+mediaWiki.loader.testCallback();
. "// 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"
+ // This file will contain unquoted JSON strings as javascript native object literals,
+ // flip the quotemark convention for this file.
+ . "/*jshint quotmark: double */\n"
. "\n"
. 'mediaWiki.libs.phpParserData = ' . FormatJson::encode( $phpParserData, true ) . ";\n";
// This file stores the output from the PHP parser for various messages, arguments,
// 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 Sun, 07 Oct 2012 07:30:16 +0000
+// Last generated with generateJqueryMsgData.php at Sat, 03 Nov 2012 21:32:01 +0000
+/*jshint quotmark: double */
mediaWiki.libs.phpParserData = {
"messages": {
-( function ( $, mw, QUnit, undefined ) {
/*global CompletenessTest */
-/*jshint evil:true */
-'use strict';
-
-var mwTestIgnore, mwTester, addons;
-
-/**
- * Add bogus to url to prevent IE crazy caching
- *
- * @param value {String} a relative path (eg. 'data/foo.js'
- * or 'data/test.php?foo=bar').
- * @return {String} Such as 'data/foo.js?131031765087663960'
- */
-QUnit.fixurl = function ( value ) {
- return value + (/\?/.test( value ) ? '&' : '?')
- + String( new Date().getTime() )
- + String( parseInt( Math.random() * 100000, 10 ) );
-};
-
-/**
- * Configuration
- */
-
-// When a test() indicates asynchronicity with stop(),
-// allow 10 seconds to pass before killing the test(),
-// and assuming failure.
-QUnit.config.testTimeout = 10 * 1000;
-
-// Add a checkbox to QUnit header to toggle MediaWiki ResourceLoader debug mode.
-QUnit.config.urlConfig.push( {
- id: 'debug',
- label: 'Enable ResourceLoaderDebug',
- tooltip: 'Enable debug mode in ResourceLoader'
-} );
-
-/**
- * Load TestSwarm agent
- */
-// Only if the current url indicates that there is a TestSwarm instance watching us
-// (TestSwarm appends swarmURL to the test suites url it loads in iframes).
-// Otherwise this is just a simple view of Special:JavaScriptTest/qunit directly,
-// no point in loading inject.js in that case. Also, make sure that this instance
-// of MediaWiki has actually been configured with the required url to that inject.js
-// script. By default it is false.
-if ( QUnit.urlParams.swarmURL && mw.config.get( 'QUnitTestSwarmInjectJSPath' ) ) {
- document.write( "<scr" + "ipt src='" + QUnit.fixurl( mw.config.get( 'QUnitTestSwarmInjectJSPath' ) ) + "'></scr" + "ipt>" );
-}
-
-/**
- * CompletenessTest
- */
-// Adds toggle checkbox to header
-QUnit.config.urlConfig.push( {
- id: 'completenesstest',
- label: 'Run CompletenessTest',
- tooltip: 'Run the completeness test'
-} );
-
-// Initiate when enabled
-if ( QUnit.urlParams.completenesstest ) {
-
- // Return true to ignore
- mwTestIgnore = function ( val, tester, funcPath ) {
-
- // Don't record methods of the properties of constructors,
- // to avoid getting into a loop (prototype.constructor.prototype..).
- // Since we're therefor skipping any injection for
- // "new mw.Foo()", manually set it to true here.
- if ( val instanceof mw.Map ) {
- tester.methodCallTracker.Map = true;
- return true;
- }
- if ( val instanceof mw.Title ) {
- tester.methodCallTracker.Title = true;
- return true;
- }
-
- // Don't record methods of the properties of a jQuery object
- if ( val instanceof $ ) {
- return true;
- }
-
- return false;
+/*jshint evil: true */
+( function ( $, mw, QUnit, undefined ) {
+ 'use strict';
+
+ var mwTestIgnore, mwTester,
+ addons,
+ envExecCount;
+
+ /**
+ * Add bogus to url to prevent IE crazy caching
+ *
+ * @param value {String} a relative path (eg. 'data/foo.js'
+ * or 'data/test.php?foo=bar').
+ * @return {String} Such as 'data/foo.js?131031765087663960'
+ */
+ QUnit.fixurl = function ( value ) {
+ return value + (/\?/.test( value ) ? '&' : '?')
+ + String( new Date().getTime() )
+ + String( parseInt( Math.random() * 100000, 10 ) );
};
- mwTester = new CompletenessTest( mw, mwTestIgnore );
-}
-
-/**
- * Test environment recommended for all QUnit test modules
- */
-// Whether to log environment changes to the console
-QUnit.config.urlConfig.push( 'mwlogenv' );
-
-/**
- * Reset mw.config and others to a fresh copy of the live config for each test(),
- * and restore it back to the live one afterwards.
- * @param localEnv {Object} [optional]
- * @example (see test suite at the bottom of this file)
- * </code>
- */
-QUnit.newMwEnvironment = ( function () {
- var log, liveConfig, liveMessages;
-
- liveConfig = mw.config.values;
- liveMessages = mw.messages.values;
-
- function freshConfigCopy( custom ) {
- // "deep=true" is important here.
- // Otherwise we just create a new object with values referring to live config.
- // e.g. mw.config.set( 'wgFileExtensions', [] ) would not effect liveConfig,
- // but mw.config.get( 'wgFileExtensions' ).push( 'png' ) would as the array
- // was passed by reference in $.extend's loop.
- return $.extend( {}, liveConfig, custom, /*deep=*/true );
+ /**
+ * Configuration
+ */
+
+ // When a test() indicates asynchronicity with stop(),
+ // allow 10 seconds to pass before killing the test(),
+ // and assuming failure.
+ QUnit.config.testTimeout = 10 * 1000;
+
+ // Add a checkbox to QUnit header to toggle MediaWiki ResourceLoader debug mode.
+ QUnit.config.urlConfig.push( {
+ id: 'debug',
+ label: 'Enable ResourceLoaderDebug',
+ tooltip: 'Enable debug mode in ResourceLoader'
+ } );
+
+ /**
+ * Load TestSwarm agent
+ */
+ // Only if the current url indicates that there is a TestSwarm instance watching us
+ // (TestSwarm appends swarmURL to the test suites url it loads in iframes).
+ // Otherwise this is just a simple view of Special:JavaScriptTest/qunit directly,
+ // no point in loading inject.js in that case. Also, make sure that this instance
+ // of MediaWiki has actually been configured with the required url to that inject.js
+ // script. By default it is false.
+ if ( QUnit.urlParams.swarmURL && mw.config.get( 'QUnitTestSwarmInjectJSPath' ) ) {
+ document.write( '<scr' + 'ipt src="' + QUnit.fixurl( mw.config.get( 'QUnitTestSwarmInjectJSPath' ) ) + '"></scr' + 'ipt>' );
}
- function freshMessagesCopy( custom ) {
- return $.extend( {}, liveMessages, custom, /*deep=*/true );
+ /**
+ * CompletenessTest
+ */
+ // Adds toggle checkbox to header
+ QUnit.config.urlConfig.push( {
+ id: 'completenesstest',
+ label: 'Run CompletenessTest',
+ tooltip: 'Run the completeness test'
+ } );
+
+ // Initiate when enabled
+ if ( QUnit.urlParams.completenesstest ) {
+
+ // Return true to ignore
+ mwTestIgnore = function ( val, tester ) {
+
+ // Don't record methods of the properties of constructors,
+ // to avoid getting into a loop (prototype.constructor.prototype..).
+ // Since we're therefor skipping any injection for
+ // "new mw.Foo()", manually set it to true here.
+ if ( val instanceof mw.Map ) {
+ tester.methodCallTracker.Map = true;
+ return true;
+ }
+ if ( val instanceof mw.Title ) {
+ tester.methodCallTracker.Title = true;
+ return true;
+ }
+
+ // Don't record methods of the properties of a jQuery object
+ if ( val instanceof $ ) {
+ return true;
+ }
+
+ return false;
+ };
+
+ mwTester = new CompletenessTest( mw, mwTestIgnore );
}
- log = QUnit.urlParams.mwlogenv ? mw.log : function () {};
+ /**
+ * Test environment recommended for all QUnit test modules
+ */
+ // Whether to log environment changes to the console
+ QUnit.config.urlConfig.push( 'mwlogenv' );
+
+ /**
+ * Reset mw.config and others to a fresh copy of the live config for each test(),
+ * and restore it back to the live one afterwards.
+ * @param localEnv {Object} [optional]
+ * @example (see test suite at the bottom of this file)
+ * </code>
+ */
+ QUnit.newMwEnvironment = ( function () {
+ var log, liveConfig, liveMessages;
+
+ liveConfig = mw.config.values;
+ liveMessages = mw.messages.values;
+
+ function freshConfigCopy( custom ) {
+ // "deep=true" is important here.
+ // Otherwise we just create a new object with values referring to live config.
+ // e.g. mw.config.set( 'wgFileExtensions', [] ) would not effect liveConfig,
+ // but mw.config.get( 'wgFileExtensions' ).push( 'png' ) would as the array
+ // was passed by reference in $.extend's loop.
+ return $.extend( {}, liveConfig, custom, /*deep=*/true );
+ }
- return function ( localEnv ) {
- localEnv = $.extend( {
- // QUnit
- setup: $.noop,
- teardown: $.noop,
- // MediaWiki
- config: {},
- messages: {}
- }, localEnv );
+ function freshMessagesCopy( custom ) {
+ return $.extend( {}, liveMessages, custom, /*deep=*/true );
+ }
- return {
- setup: function () {
- log( 'MwEnvironment> SETUP for "' + QUnit.config.current.module
- + ': ' + QUnit.config.current.testName + '"' );
+ log = QUnit.urlParams.mwlogenv ? mw.log : function () {};
+
+ return function ( localEnv ) {
+ localEnv = $.extend( {
+ // QUnit
+ setup: $.noop,
+ teardown: $.noop,
+ // MediaWiki
+ config: {},
+ messages: {}
+ }, localEnv );
+
+ return {
+ setup: function () {
+ log( 'MwEnvironment> SETUP for "' + QUnit.config.current.module
+ + ': ' + QUnit.config.current.testName + '"' );
+
+ // Greetings, mock environment!
+ mw.config.values = freshConfigCopy( localEnv.config );
+ mw.messages.values = freshMessagesCopy( localEnv.messages );
+
+ localEnv.setup();
+ },
+
+ teardown: function () {
+ log( 'MwEnvironment> TEARDOWN for "' + QUnit.config.current.module
+ + ': ' + QUnit.config.current.testName + '"' );
+
+ localEnv.teardown();
+
+ // Farewell, mock environment!
+ mw.config.values = liveConfig;
+ mw.messages.values = liveMessages;
+ }
+ };
+ };
+ }() );
- // Greetings, mock environment!
- mw.config.values = freshConfigCopy( localEnv.config );
- mw.messages.values = freshMessagesCopy( localEnv.messages );
+ // $.when stops as soon as one fails, which makes sense in most
+ // practical scenarios, but not in a unit test where we really do
+ // need to wait until all of them are finished.
+ QUnit.whenPromisesComplete = function () {
+ var altPromises = [];
- localEnv.setup();
- },
+ $.each( arguments, function ( i, arg ) {
+ var alt = $.Deferred();
+ altPromises.push( alt );
- teardown: function () {
- log( 'MwEnvironment> TEARDOWN for "' + QUnit.config.current.module
- + ': ' + QUnit.config.current.testName + '"' );
+ // Whether this one fails or not, forwards it to
+ // the 'done' (resolve) callback of the alternative promise.
+ arg.always( alt.resolve );
+ });
- localEnv.teardown();
+ return $.when.apply( $, altPromises );
+ };
- // Farewell, mock environment!
- mw.config.values = liveConfig;
- mw.messages.values = liveMessages;
- }
- };
+ /**
+ * Add-on assertion helpers
+ */
+ // Define the add-ons
+ addons = {
+
+ // Expect boolean true
+ assertTrue: function ( actual, message ) {
+ QUnit.push( actual === true, actual, true, message );
+ },
+
+ // Expect boolean false
+ assertFalse: function ( actual, message ) {
+ QUnit.push( actual === false, actual, false, message );
+ },
+
+ // Expect numerical value less than X
+ lt: function ( actual, expected, message ) {
+ QUnit.push( actual < expected, actual, 'less than ' + expected, message );
+ },
+
+ // Expect numerical value less than or equal to X
+ ltOrEq: function ( actual, expected, message ) {
+ QUnit.push( actual <= expected, actual, 'less than or equal to ' + expected, message );
+ },
+
+ // Expect numerical value greater than X
+ gt: function ( actual, expected, message ) {
+ QUnit.push( actual > expected, actual, 'greater than ' + expected, message );
+ },
+
+ // Expect numerical value greater than or equal to X
+ gtOrEq: function ( actual, expected, message ) {
+ QUnit.push( actual >= expected, actual, 'greater than or equal to ' + expected, message );
+ }
};
-}() );
-// $.when stops as soon as one fails, which makes sense in most
-// practical scenarios, but not in a unit test where we really do
-// need to wait until all of them are finished.
-QUnit.whenPromisesComplete = function () {
- var altPromises = [];
+ $.extend( QUnit.assert, addons );
+
+ /**
+ * Small test suite to confirm proper functionality of the utilities and
+ * initializations defined above in this file.
+ */
+ envExecCount = 0;
+ QUnit.module( 'mediawiki.tests.qunit.testrunner', QUnit.newMwEnvironment({
+ setup: function () {
+ envExecCount += 1;
+ this.mwHtmlLive = mw.html;
+ mw.html = {
+ escape: function () {
+ return 'mocked-' + envExecCount;
+ }
+ };
+ },
+ teardown: function () {
+ mw.html = this.mwHtmlLive;
+ },
+ config: {
+ testVar: 'foo'
+ },
+ messages: {
+ testMsg: 'Foo.'
+ }
+ }) );
- $.each( arguments, function ( i, arg ) {
- var alt = $.Deferred();
- altPromises.push( alt );
+ QUnit.test( 'Setup', 3, function ( assert ) {
+ assert.equal( mw.html.escape( 'foo' ), 'mocked-1', 'extra setup() callback was ran.' );
+ assert.equal( mw.config.get( 'testVar' ), 'foo', 'config object applied' );
+ assert.equal( mw.messages.get( 'testMsg' ), 'Foo.', 'messages object applied' );
- // Whether this one fails or not, forwards it to
- // the 'done' (resolve) callback of the alternative promise.
- arg.always( alt.resolve );
+ mw.config.set( 'testVar', 'bar' );
+ mw.messages.set( 'testMsg', 'Bar.' );
});
- return $.when.apply( $, altPromises );
-};
-
-/**
- * Add-on assertion helpers
- */
-// Define the add-ons
-addons = {
-
- // Expect boolean true
- assertTrue: function ( actual, message ) {
- QUnit.push( actual === true, actual, true, message );
- },
-
- // Expect boolean false
- assertFalse: function ( actual, message ) {
- QUnit.push( actual === false, actual, false, message );
- },
-
- // Expect numerical value less than X
- lt: function ( actual, expected, message ) {
- QUnit.push( actual < expected, actual, 'less than ' + expected, message );
- },
-
- // Expect numerical value less than or equal to X
- ltOrEq: function ( actual, expected, message ) {
- QUnit.push( actual <= expected, actual, 'less than or equal to ' + expected, message );
- },
-
- // Expect numerical value greater than X
- gt: function ( actual, expected, message ) {
- QUnit.push( actual > expected, actual, 'greater than ' + expected, message );
- },
-
- // Expect numerical value greater than or equal to X
- gtOrEq: function ( actual, expected, message ) {
- QUnit.push( actual >= expected, actual, 'greater than or equal to ' + expected, message );
- }
-};
-
-$.extend( QUnit.assert, addons );
-
-/**
- * Small test suite to confirm proper functionality of the utilities and
- * initializations in this file.
- */
-var envExecCount = 0;
-QUnit.module( 'mediawiki.tests.qunit.testrunner', QUnit.newMwEnvironment({
- setup: function () {
- envExecCount += 1;
- this.mwHtmlLive = mw.html;
- mw.html = {
- escape: function () {
- return 'mocked-' + envExecCount;
- }
- };
- },
- teardown: function () {
- mw.html = this.mwHtmlLive;
- },
- config: {
- testVar: 'foo'
- },
- messages: {
- testMsg: 'Foo.'
- }
-}) );
-
-QUnit.test( 'Setup', 3, function ( assert ) {
- assert.equal( mw.html.escape( 'foo' ), 'mocked-1', 'extra setup() callback was ran.' );
- assert.equal( mw.config.get( 'testVar' ), 'foo', 'config object applied' );
- assert.equal( mw.messages.get( 'testMsg' ), 'Foo.', 'messages object applied' );
-
- mw.config.set( 'testVar', 'bar' );
- mw.messages.set( 'testMsg', 'Bar.' );
-});
-
-QUnit.test( 'Teardown', 3, function ( assert ) {
- assert.equal( mw.html.escape( 'foo' ), 'mocked-2', 'extra setup() callback was re-ran.' );
- assert.equal( mw.config.get( 'testVar' ), 'foo', 'config object restored and re-applied after test()' );
- assert.equal( mw.messages.get( 'testMsg' ), 'Foo.', 'messages object restored and re-applied after test()' );
-});
-
-QUnit.module( 'mediawiki.tests.qunit.testrunner-after', QUnit.newMwEnvironment() );
-
-QUnit.test( 'Teardown', 3, function ( assert ) {
- assert.equal( mw.html.escape( '<' ), '<', 'extra teardown() callback was ran.' );
- assert.equal( mw.config.get( 'testVar' ), null, 'config object restored to live in next module()' );
- assert.equal( mw.messages.get( 'testMsg' ), null, 'messages object restored to live in next module()' );
-});
+ QUnit.test( 'Teardown', 3, function ( assert ) {
+ assert.equal( mw.html.escape( 'foo' ), 'mocked-2', 'extra setup() callback was re-ran.' );
+ assert.equal( mw.config.get( 'testVar' ), 'foo', 'config object restored and re-applied after test()' );
+ assert.equal( mw.messages.get( 'testMsg' ), 'Foo.', 'messages object restored and re-applied after test()' );
+ });
+
+ QUnit.module( 'mediawiki.tests.qunit.testrunner-after', QUnit.newMwEnvironment() );
+
+ QUnit.test( 'Teardown', 3, function ( assert ) {
+ assert.equal( mw.html.escape( '<' ), '<', 'extra teardown() callback was ran.' );
+ assert.equal( mw.config.get( 'testVar' ), null, 'config object restored to live in next module()' );
+ assert.equal( mw.messages.get( 'testMsg' ), null, 'messages object restored to live in next module()' );
+ });
}( jQuery, mediaWiki, QUnit ) );
-( function ( mw, $ ) {
+( function ( $ ) {
-QUnit.module( 'jquery.autoEllipsis', QUnit.newMwEnvironment() );
+ QUnit.module( 'jquery.autoEllipsis', QUnit.newMwEnvironment() );
-function createWrappedDiv( text, width ) {
- var $wrapper = $( '<div>' ).css( 'width', width );
- var $div = $( '<div>' ).text( text );
- $wrapper.append( $div );
- return $wrapper;
-}
-
-function findDivergenceIndex( a, b ) {
- var i = 0;
- while ( i < a.length && i < b.length && a[i] === b[i] ) {
- i++;
+ function createWrappedDiv( text, width ) {
+ var $wrapper = $( '<div>' ).css( 'width', width ),
+ $div = $( '<div>' ).text( text );
+ $wrapper.append( $div );
+ return $wrapper;
}
- return i;
-}
-
-QUnit.test( 'Position right', 4, function ( assert ) {
- // We need this thing to be visible, so append it to the DOM
- var origText = 'This is a really long random string and there is no way it fits in 100 pixels.';
- var $wrapper = createWrappedDiv( origText, '100px' );
- $( '#qunit-fixture' ).append( $wrapper );
- $wrapper.autoEllipsis( { position: 'right' } );
-
- // Verify that, and only one, span element was created
- var $span = $wrapper.find( '> span' );
- assert.strictEqual( $span.length, 1, 'autoEllipsis wrapped the contents in a span element' );
-
- // Check that the text fits by turning on word wrapping
- $span.css( 'whiteSpace', 'nowrap' );
- assert.ltOrEq( $span.width(), $span.parent().width(), "Text fits (making the span 'white-space:nowrap' does not make it wider than its parent)" );
-
- // Add two characters using scary black magic
- var spanText = $span.text();
- var d = findDivergenceIndex( origText, spanText );
- var spanTextNew = spanText.substr( 0, d ) + origText[d] + origText[d] + '...';
-
- assert.gt( spanTextNew.length, spanText.length, 'Verify that the new span-length is indeed greater' );
-
- // Put this text in the span and verify it doesn't fit
- $span.text( spanTextNew );
- // In IE6 width works like min-width, allow IE6's width to be "equal to"
- if ( $.browser.msie && Number( $.browser.version ) === 6 ) {
- assert.gtOrEq( $span.width(), $span.parent().width(), 'Fit is maximal (adding two characters makes it not fit any more) - IE6: Maybe equal to as well due to width behaving like min-width in IE6' );
- } else {
- assert.gt( $span.width(), $span.parent().width(), 'Fit is maximal (adding two characters makes it not fit any more)' );
+
+ function findDivergenceIndex( a, b ) {
+ var i = 0;
+ while ( i < a.length && i < b.length && a[i] === b[i] ) {
+ i++;
+ }
+ return i;
}
-});
-}( mediaWiki, jQuery ) );
+ QUnit.test( 'Position right', 4, function ( assert ) {
+ // We need this thing to be visible, so append it to the DOM
+ var $span, spanText, d, spanTextNew,
+ origText = 'This is a really long random string and there is no way it fits in 100 pixels.',
+ $wrapper = createWrappedDiv( origText, '100px' );
+
+ $( '#qunit-fixture' ).append( $wrapper );
+ $wrapper.autoEllipsis( { position: 'right' } );
+
+ // Verify that, and only one, span element was created
+ $span = $wrapper.find( '> span' );
+ assert.strictEqual( $span.length, 1, 'autoEllipsis wrapped the contents in a span element' );
+
+ // Check that the text fits by turning on word wrapping
+ $span.css( 'whiteSpace', 'nowrap' );
+ assert.ltOrEq(
+ $span.width(),
+ $span.parent().width(),
+ 'Text fits (making the span "white-space: nowrap" does not make it wider than its parent)'
+ );
+
+ // Add two characters using scary black magic
+ spanText = $span.text();
+ d = findDivergenceIndex( origText, spanText );
+ spanTextNew = spanText.substr( 0, d ) + origText[d] + origText[d] + '...';
+
+ assert.gt( spanTextNew.length, spanText.length, 'Verify that the new span-length is indeed greater' );
+
+ // Put this text in the span and verify it doesn't fit
+ $span.text( spanTextNew );
+ // In IE6 width works like min-width, allow IE6's width to be "equal to"
+ if ( $.browser.msie && Number( $.browser.version ) === 6 ) {
+ assert.gtOrEq( $span.width(), $span.parent().width(), 'Fit is maximal (adding two characters makes it not fit any more) - IE6: Maybe equal to as well due to width behaving like min-width in IE6' );
+ } else {
+ assert.gt( $span.width(), $span.parent().width(), 'Fit is maximal (adding two characters makes it not fit any more)' );
+ }
+ });
+
+}( jQuery ) );
-QUnit.module( 'jquery.byteLength', QUnit.newMwEnvironment() );
+( function ( $ ) {
+ QUnit.module( 'jquery.byteLength', QUnit.newMwEnvironment() );
-QUnit.test( 'Simple text', 5, function ( assert ) {
- var azLc = 'abcdefghijklmnopqrstuvwxyz',
- azUc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
- num = '0123456789',
- x = '*',
- space = ' ';
+ QUnit.test( 'Simple text', 5, function ( assert ) {
+ var azLc = 'abcdefghijklmnopqrstuvwxyz',
+ azUc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ num = '0123456789',
+ x = '*',
+ space = ' ';
- assert.equal( $.byteLength( azLc ), 26, 'Lowercase a-z' );
- assert.equal( $.byteLength( azUc ), 26, 'Uppercase A-Z' );
- assert.equal( $.byteLength( num ), 10, 'Numbers 0-9' );
- assert.equal( $.byteLength( x ), 1, 'An asterisk' );
- assert.equal( $.byteLength( space ), 3, '3 spaces' );
+ assert.equal( $.byteLength( azLc ), 26, 'Lowercase a-z' );
+ assert.equal( $.byteLength( azUc ), 26, 'Uppercase A-Z' );
+ assert.equal( $.byteLength( num ), 10, 'Numbers 0-9' );
+ assert.equal( $.byteLength( x ), 1, 'An asterisk' );
+ assert.equal( $.byteLength( space ), 3, '3 spaces' );
-} );
+ } );
-QUnit.test( 'Special text', 5, function ( assert ) {
- // http://en.wikipedia.org/wiki/UTF-8
- var U_0024 = '\u0024',
- U_00A2 = '\u00A2',
- U_20AC = '\u20AC',
- U_024B62 = '\u024B62',
- // The normal one doesn't display properly, try the below which is the same
- // according to http://www.fileformat.info/info/unicode/char/24B62/index.htm
- U_024B62_alt = '\uD852\uDF62';
+ QUnit.test( 'Special text', 5, function ( assert ) {
+ // http://en.wikipedia.org/wiki/UTF-8
+ var u0024 = '$',
+ u00A2 = '\u00A2',
+ u20AC = '\u20AC',
+ u024B62 = '\u024B62',
+ // The normal one doesn't display properly, try the below which is the same
+ // according to http://www.fileformat.info/info/unicode/char/24B62/index.htm
+ u024B62alt = '\uD852\uDF62';
- assert.strictEqual( $.byteLength( U_0024 ), 1, 'U+0024: 1 byte. \u0024 (dollar sign)' );
- assert.strictEqual( $.byteLength( U_00A2 ), 2, 'U+00A2: 2 bytes. \u00A2 (cent sign)' );
- assert.strictEqual( $.byteLength( U_20AC ), 3, 'U+20AC: 3 bytes. \u20AC (euro sign)' );
- assert.strictEqual( $.byteLength( U_024B62 ), 4, 'U+024B62: 4 bytes. \uD852\uDF62 (a Han character)' );
- assert.strictEqual( $.byteLength( U_024B62_alt ), 4, 'U+024B62: 4 bytes. \uD852\uDF62 (a Han character) - alternative method' );
-} );
+ assert.strictEqual( $.byteLength( u0024 ), 1, 'U+0024: 1 byte. $ (dollar sign)' );
+ assert.strictEqual( $.byteLength( u00A2 ), 2, 'U+00A2: 2 bytes. \u00A2 (cent sign)' );
+ assert.strictEqual( $.byteLength( u20AC ), 3, 'U+20AC: 3 bytes. \u20AC (euro sign)' );
+ assert.strictEqual( $.byteLength( u024B62 ), 4, 'U+024B62: 4 bytes. \uD852\uDF62 (a Han character)' );
+ assert.strictEqual( $.byteLength( u024B62alt ), 4, 'U+024B62: 4 bytes. \uD852\uDF62 (a Han character) - alternative method' );
+ } );
+}( jQuery ) );
// Basic sendkey-implementation
function addChars( $input, charstr ) {
var c, len;
+ function x( $input, i ) {
+ // Add character to the value
+ return $input.val() + charstr.charAt( i );
+ }
for ( c = 0, len = charstr.length; c < len; c += 1 ) {
$input
- .val( function ( i, val ) {
- // Add character to the value
- return val + charstr.charAt( c );
- } )
+ .val( x( $input, c ) )
.trigger( 'change' );
}
}
-QUnit.module( 'jquery.client', QUnit.newMwEnvironment() );
+( function ( $ ) {
+ var uacount, uas, testMap;
-/** Number of user-agent defined */
-var uacount = 0;
+ QUnit.module( 'jquery.client', QUnit.newMwEnvironment() );
-var uas = (function () {
+ /** Number of user-agent defined */
+ uacount = 0;
- // Object keyed by userAgent. Value is an array (human-readable name, client-profile object, navigator.platform value)
- // Info based on results from http://toolserver.org/~krinkle/testswarm/job/174/
- var uas = {
- // Internet Explorer 6
- // Internet Explorer 7
- 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)': {
- title: 'Internet Explorer 7',
- platform: 'Win32',
- profile: {
- "name": "msie",
- "layout": "trident",
- "layoutVersion": "unknown",
- "platform": "win",
- "version": "7.0",
- "versionBase": "7",
- "versionNumber": 7
- },
- wikiEditor: {
- ltr: true,
- rtl: false
- }
- },
- // Internet Explorer 8
- // Internet Explorer 9
- // Internet Explorer 10
- 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)': {
- title: 'Internet Explorer 10',
- platform: 'Win32',
- profile: {
- "name": "msie",
- "layout": "trident",
- "layoutVersion": "unknown", // should be able to report 6?
- "platform": "win",
- "version": "10.0",
- "versionBase": "10",
- "versionNumber": 10
+ uas = ( function () {
+
+ // Object keyed by userAgent. Value is an array (human-readable name, client-profile object, navigator.platform value)
+ // Info based on results from http://toolserver.org/~krinkle/testswarm/job/174/
+ var uas = {
+ // Internet Explorer 6
+ // Internet Explorer 7
+ 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)': {
+ title: 'Internet Explorer 7',
+ platform: 'Win32',
+ profile: {
+ name: 'msie',
+ layout: 'trident',
+ layoutVersion: 'unknown',
+ platform: 'win',
+ version: '7.0',
+ versionBase: '7',
+ versionNumber: 7
+ },
+ wikiEditor: {
+ ltr: true,
+ rtl: false
+ }
},
- wikiEditor: {
- ltr: true,
- rtl: true
- }
- },
- // Firefox 2
- // Firefox 3.5
- 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.19) Gecko/20110420 Firefox/3.5.19': {
- title: 'Firefox 3.5',
- platform: 'MacIntel',
- profile: {
- "name": "firefox",
- "layout": "gecko",
- "layoutVersion": 20110420,
- "platform": "mac",
- "version": "3.5.19",
- "versionBase": "3",
- "versionNumber": 3.5
+ // Internet Explorer 8
+ // Internet Explorer 9
+ // Internet Explorer 10
+ 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)': {
+ title: 'Internet Explorer 10',
+ platform: 'Win32',
+ profile: {
+ name: 'msie',
+ layout: 'trident',
+ layoutVersion: 'unknown', // should be able to report 6?
+ platform: 'win',
+ version: '10.0',
+ versionBase: '10',
+ versionNumber: 10
+ },
+ wikiEditor: {
+ ltr: true,
+ rtl: true
+ }
},
- wikiEditor: {
- ltr: true,
- rtl: true
- }
- },
- // Firefox 3.6
- 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110422 Ubuntu/10.10 (maverick) Firefox/3.6.17': {
- title: 'Firefox 3.6',
- platform: 'Linux i686',
- profile: {
- "name": "firefox",
- "layout": "gecko",
- "layoutVersion": 20110422,
- "platform": "linux",
- "version": "3.6.17",
- "versionBase": "3",
- "versionNumber": 3.6
+ // Firefox 2
+ // Firefox 3.5
+ 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.19) Gecko/20110420 Firefox/3.5.19': {
+ title: 'Firefox 3.5',
+ platform: 'MacIntel',
+ profile: {
+ name: 'firefox',
+ layout: 'gecko',
+ layoutVersion: 20110420,
+ platform: 'mac',
+ version: '3.5.19',
+ versionBase: '3',
+ versionNumber: 3.5
+ },
+ wikiEditor: {
+ ltr: true,
+ rtl: true
+ }
},
- wikiEditor: {
- ltr: true,
- rtl: true
- }
- },
- // Firefox 4
- 'Mozilla/5.0 (Windows NT 6.0; rv:2.0.1) Gecko/20100101 Firefox/4.0.1': {
- title: 'Firefox 4',
- platform: 'Win32',
- profile: {
- "name": "firefox",
- "layout": "gecko",
- "layoutVersion": 20100101,
- "platform": "win",
- "version": "4.0.1",
- "versionBase": "4",
- "versionNumber": 4
+ // Firefox 3.6
+ 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110422 Ubuntu/10.10 (maverick) Firefox/3.6.17': {
+ title: 'Firefox 3.6',
+ platform: 'Linux i686',
+ profile: {
+ name: 'firefox',
+ layout: 'gecko',
+ layoutVersion: 20110422,
+ platform: 'linux',
+ version: '3.6.17',
+ versionBase: '3',
+ versionNumber: 3.6
+ },
+ wikiEditor: {
+ ltr: true,
+ rtl: true
+ }
},
- wikiEditor: {
- ltr: true,
- rtl: true
- }
- },
- // Firefox 10 nightly build
- 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0a1) Gecko/20111103 Firefox/10.0a1': {
- title: 'Firefox 10 nightly',
- platform: 'Linux',
- profile: {
- "name": "firefox",
- "layout": "gecko",
- "layoutVersion": 20111103,
- "platform": "linux",
- "version": "10.0a1",
- "versionBase": "10",
- "versionNumber": 10
+ // Firefox 4
+ 'Mozilla/5.0 (Windows NT 6.0; rv:2.0.1) Gecko/20100101 Firefox/4.0.1': {
+ title: 'Firefox 4',
+ platform: 'Win32',
+ profile: {
+ name: 'firefox',
+ layout: 'gecko',
+ layoutVersion: 20100101,
+ platform: 'win',
+ version: '4.0.1',
+ versionBase: '4',
+ versionNumber: 4
+ },
+ wikiEditor: {
+ ltr: true,
+ rtl: true
+ }
},
- wikiEditor: {
- ltr: true,
- rtl: true
- }
- },
- // Firefox 5
- // Safari 3
- // Safari 4
- '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': {
- title: 'Safari 4',
- platform: 'MacIntel',
- profile: {
- "name": "safari",
- "layout": "webkit",
- "layoutVersion": 531,
- "platform": "mac",
- "version": "4.0.5",
- "versionBase": "4",
- "versionNumber": 4
+ // Firefox 10 nightly build
+ 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0a1) Gecko/20111103 Firefox/10.0a1': {
+ title: 'Firefox 10 nightly',
+ platform: 'Linux',
+ profile: {
+ name: 'firefox',
+ layout: 'gecko',
+ layoutVersion: 20111103,
+ platform: 'linux',
+ version: '10.0a1',
+ versionBase: '10',
+ versionNumber: 10
+ },
+ wikiEditor: {
+ ltr: true,
+ rtl: true
+ }
},
- wikiEditor: {
- ltr: true,
- rtl: true
- }
- },
- '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': {
- title: 'Safari 4',
- platform: 'Win32',
- profile: {
- "name": "safari",
- "layout": "webkit",
- "layoutVersion": 533,
- "platform": "win",
- "version": "4.0.5",
- "versionBase": "4",
- "versionNumber": 4
+ // Firefox 5
+ // Safari 3
+ // Safari 4
+ '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': {
+ title: 'Safari 4',
+ platform: 'MacIntel',
+ profile: {
+ name: 'safari',
+ layout: 'webkit',
+ layoutVersion: 531,
+ platform: 'mac',
+ version: '4.0.5',
+ versionBase: '4',
+ versionNumber: 4
+ },
+ wikiEditor: {
+ ltr: true,
+ rtl: true
+ }
},
- wikiEditor: {
- ltr: true,
- rtl: true
- }
- },
- // Safari 5
- // Opera 10
- // Chrome 5
- // Chrome 6
- // Chrome 7
- // Chrome 8
- // Chrome 9
- // Chrome 10
- // Chrome 11
- // Chrome 12
- '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': {
- title: 'Chrome 12',
- platform: 'MacIntel',
- profile: {
- "name": "chrome",
- "layout": "webkit",
- "layoutVersion": 534,
- "platform": "mac",
- "version": "12.0.742.112",
- "versionBase": "12",
- "versionNumber": 12
+ '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': {
+ title: 'Safari 4',
+ platform: 'Win32',
+ profile: {
+ name: 'safari',
+ layout: 'webkit',
+ layoutVersion: 533,
+ platform: 'win',
+ version: '4.0.5',
+ versionBase: '4',
+ versionNumber: 4
+ },
+ wikiEditor: {
+ ltr: true,
+ rtl: true
+ }
},
- wikiEditor: {
- ltr: true,
- rtl: true
- }
- },
- 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.68 Safari/534.30': {
- title: 'Chrome 12',
- platform: 'Linux i686',
- profile: {
- "name": "chrome",
- "layout": "webkit",
- "layoutVersion": 534,
- "platform": "linux",
- "version": "12.0.742.68",
- "versionBase": "12",
- "versionNumber": 12
+ // Safari 5
+ // Opera 10
+ // Chrome 5
+ // Chrome 6
+ // Chrome 7
+ // Chrome 8
+ // Chrome 9
+ // Chrome 10
+ // Chrome 11
+ // Chrome 12
+ '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': {
+ title: 'Chrome 12',
+ platform: 'MacIntel',
+ profile: {
+ name: 'chrome',
+ layout: 'webkit',
+ layoutVersion: 534,
+ platform: 'mac',
+ version: '12.0.742.112',
+ versionBase: '12',
+ versionNumber: 12
+ },
+ wikiEditor: {
+ ltr: true,
+ rtl: true
+ }
},
- wikiEditor: {
- ltr: true,
- rtl: true
- }
- },
- // Bug #34924
- 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.34 (KHTML, like Gecko) rekonq Safari/534.34': {
- title: 'Rekonq',
- platform: 'Linux i686',
- profile: {
- "name": "rekonq",
- "layout": "webkit",
- "layoutVersion": 534,
- "platform": "linux",
- "version": "534.34",
- "versionBase": "534",
- "versionNumber": 534.34
+ 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.68 Safari/534.30': {
+ title: 'Chrome 12',
+ platform: 'Linux i686',
+ profile: {
+ name: 'chrome',
+ layout: 'webkit',
+ layoutVersion: 534,
+ platform: 'linux',
+ version: '12.0.742.68',
+ versionBase: '12',
+ versionNumber: 12
+ },
+ wikiEditor: {
+ ltr: true,
+ rtl: true
+ }
},
- wikiEditor: {
- ltr: true,
- rtl: true
+ // Bug #34924
+ 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.34 (KHTML, like Gecko) rekonq Safari/534.34': {
+ title: 'Rekonq',
+ platform: 'Linux i686',
+ profile: {
+ name: 'rekonq',
+ layout: 'webkit',
+ layoutVersion: 534,
+ platform: 'linux',
+ version: '534.34',
+ versionBase: '534',
+ versionNumber: 534.34
+ },
+ wikiEditor: {
+ ltr: true,
+ rtl: true
+ }
}
- }
- };
- $.each( uas, function () {
- uacount++;
- });
- return uas;
-}());
+ };
+ $.each( uas, function () {
+ uacount++;
+ });
+ return uas;
+ }() );
-QUnit.test( 'profile userAgent support', uacount, function ( assert ) {
- // Generate a client profile object and compare recursively
- var uaTest = function( rawUserAgent, data ) {
- var ret = $.client.profile( {
- userAgent: rawUserAgent,
- platform: data.platform
- } );
- assert.deepEqual( ret, data.profile, 'Client profile support check for ' + data.title + ' (' + data.platform + '): ' + rawUserAgent );
- };
+ QUnit.test( 'profile userAgent support', uacount, function ( assert ) {
+ // Generate a client profile object and compare recursively
+ var uaTest = function( rawUserAgent, data ) {
+ var ret = $.client.profile( {
+ userAgent: rawUserAgent,
+ platform: data.platform
+ } );
+ assert.deepEqual( ret, data.profile, 'Client profile support check for ' + data.title + ' (' + data.platform + '): ' + rawUserAgent );
+ };
- // Loop through and run tests
- $.each( uas, uaTest );
-} );
+ // Loop through and run tests
+ $.each( uas, uaTest );
+ } );
-QUnit.test( 'profile return validation for current user agent', 7, function ( assert ) {
- var p = $.client.profile();
- function unknownOrType( val, type, summary ) {
- assert.ok( typeof val === type || val === 'unknown', summary );
- }
+ QUnit.test( 'profile return validation for current user agent', 7, function ( assert ) {
+ var p = $.client.profile();
+ function unknownOrType( val, type, summary ) {
+ assert.ok( typeof val === type || val === 'unknown', summary );
+ }
- assert.equal( typeof p, 'object', 'profile returns an object' );
- unknownOrType( p.layout, 'string', 'p.layout is a string (or "unknown")' );
- unknownOrType( p.layoutVersion, 'number', 'p.layoutVersion is a number (or "unknown")' );
- unknownOrType( p.platform, 'string', 'p.platform is a string (or "unknown")' );
- unknownOrType( p.version, 'string', 'p.version is a string (or "unknown")' );
- unknownOrType( p.versionBase, 'string', 'p.versionBase is a string (or "unknown")' );
- assert.equal( typeof p.versionNumber, 'number', 'p.versionNumber is a number' );
-});
+ assert.equal( typeof p, 'object', 'profile returns an object' );
+ unknownOrType( p.layout, 'string', 'p.layout is a string (or "unknown")' );
+ unknownOrType( p.layoutVersion, 'number', 'p.layoutVersion is a number (or "unknown")' );
+ unknownOrType( p.platform, 'string', 'p.platform is a string (or "unknown")' );
+ unknownOrType( p.version, 'string', 'p.version is a string (or "unknown")' );
+ unknownOrType( p.versionBase, 'string', 'p.versionBase is a string (or "unknown")' );
+ assert.equal( typeof p.versionNumber, 'number', 'p.versionNumber is a number' );
+ });
-// Example from WikiEditor
-// Make sure to use raw numbers, a string like "7.0" would fail on a
-// version 10 browser since in string comparaison "10" is before "7.0" :)
-var testMap = {
- 'ltr': {
- 'msie': [['>=', 7.0]],
- 'firefox': [['>=', 2]],
- 'opera': [['>=', 9.6]],
- 'safari': [['>=', 3]],
- 'chrome': [['>=', 3]],
- 'netscape': [['>=', 9]],
- 'blackberry': false,
- 'ipod': false,
- 'iphone': false
- },
- 'rtl': {
- 'msie': [['>=', 8]],
- 'firefox': [['>=', 2]],
- 'opera': [['>=', 9.6]],
- 'safari': [['>=', 3]],
- 'chrome': [['>=', 3]],
- 'netscape': [['>=', 9]],
- 'blackberry': false,
- 'ipod': false,
- 'iphone': false
- }
-};
+ // Example from WikiEditor
+ // Make sure to use raw numbers, a string like "7.0" would fail on a
+ // version 10 browser since in string comparaison "10" is before "7.0" :)
+ testMap = {
+ 'ltr': {
+ 'msie': [['>=', 7.0]],
+ 'firefox': [['>=', 2]],
+ 'opera': [['>=', 9.6]],
+ 'safari': [['>=', 3]],
+ 'chrome': [['>=', 3]],
+ 'netscape': [['>=', 9]],
+ 'blackberry': false,
+ 'ipod': false,
+ 'iphone': false
+ },
+ 'rtl': {
+ 'msie': [['>=', 8]],
+ 'firefox': [['>=', 2]],
+ 'opera': [['>=', 9.6]],
+ 'safari': [['>=', 3]],
+ 'chrome': [['>=', 3]],
+ 'netscape': [['>=', 9]],
+ 'blackberry': false,
+ 'ipod': false,
+ 'iphone': false
+ }
+ };
-QUnit.test( 'test', 1, function ( assert ) {
- // .test() uses eval, make sure no exceptions are thrown
- // then do a basic return value type check
- var testMatch = $.client.test( testMap );
+ QUnit.test( 'test', 1, function ( assert ) {
+ // .test() uses eval, make sure no exceptions are thrown
+ // then do a basic return value type check
+ var testMatch = $.client.test( testMap );
- assert.equal( typeof testMatch, 'boolean', 'test returns a boolean value' );
+ assert.equal( typeof testMatch, 'boolean', 'test returns a boolean value' );
-});
+ });
-QUnit.test( 'User-agent matches against WikiEditor\'s compatibility map', uacount * 2, function ( assert ) {
- var $body = $( 'body' ),
- bodyClasses = $body.attr( 'class' );
+ QUnit.test( 'User-agent matches against WikiEditor\'s compatibility map', uacount * 2, function ( assert ) {
+ var $body = $( 'body' ),
+ bodyClasses = $body.attr( 'class' );
- // Loop through and run tests
- $.each( uas, function ( agent, data ) {
- $.each( ['ltr', 'rtl'], function ( i, dir ) {
- $body.removeClass( 'ltr rtl' ).addClass( dir );
- var profile = $.client.profile( {
- userAgent: agent,
- platform: data.platform
- } );
- var testMatch = $.client.test( testMap, profile );
- $body.removeClass( dir );
+ // Loop through and run tests
+ $.each( uas, function ( agent, data ) {
+ $.each( ['ltr', 'rtl'], function ( i, dir ) {
+ var profile, testMatch;
+ $body.removeClass( 'ltr rtl' ).addClass( dir );
+ profile = $.client.profile( {
+ userAgent: agent,
+ platform: data.platform
+ } );
+ testMatch = $.client.test( testMap, profile );
+ $body.removeClass( dir );
- assert.equal( testMatch, data.wikiEditor[dir], 'testing comparison based on ' + dir + ', ' + agent );
+ assert.equal( testMatch, data.wikiEditor[dir], 'testing comparison based on ' + dir + ', ' + agent );
+ });
});
- });
-
- // Restore body classes
- $body.attr( 'class', bodyClasses );
-});
+ // Restore body classes
+ $body.attr( 'class', bodyClasses );
+ });
+}( jQuery ) );
-QUnit.module( 'jquery.colorUtil', QUnit.newMwEnvironment() );
-
-QUnit.test( 'getRGB', 18, function ( assert ) {
- assert.strictEqual( $.colorUtil.getRGB(), undefined, 'No arguments' );
- assert.strictEqual( $.colorUtil.getRGB( '' ), undefined, 'Empty string' );
- assert.deepEqual( $.colorUtil.getRGB( [0, 100, 255] ), [0, 100, 255], 'Parse array of rgb values' );
- assert.deepEqual( $.colorUtil.getRGB( 'rgb(0,100,255)' ), [0, 100, 255], 'Parse simple rgb string' );
- assert.deepEqual( $.colorUtil.getRGB( 'rgb(0, 100, 255)' ), [0, 100, 255], 'Parse simple rgb string with spaces' );
- assert.deepEqual( $.colorUtil.getRGB( 'rgb(0%,20%,40%)' ), [0, 51, 102], 'Parse rgb string with percentages' );
- assert.deepEqual( $.colorUtil.getRGB( 'rgb(0%, 20%, 40%)' ), [0, 51, 102], 'Parse rgb string with percentages and spaces' );
- assert.deepEqual( $.colorUtil.getRGB( '#f2ddee' ), [242, 221, 238], 'Hex string: 6 char lowercase' );
- assert.deepEqual( $.colorUtil.getRGB( '#f2DDEE' ), [242, 221, 238], 'Hex string: 6 char uppercase' );
- assert.deepEqual( $.colorUtil.getRGB( '#f2DdEe' ), [242, 221, 238], 'Hex string: 6 char mixed' );
- assert.deepEqual( $.colorUtil.getRGB( '#eee' ), [238, 238, 238], 'Hex string: 3 char lowercase' );
- assert.deepEqual( $.colorUtil.getRGB( '#EEE' ), [238, 238, 238], 'Hex string: 3 char uppercase' );
- assert.deepEqual( $.colorUtil.getRGB( '#eEe' ), [238, 238, 238], 'Hex string: 3 char mixed' );
- assert.deepEqual( $.colorUtil.getRGB( 'rgba(0, 0, 0, 0)' ), [255, 255, 255], 'Zero rgba for Safari 3; Transparent (whitespace)' );
-
- // Perhaps this is a bug in colorUtil, but it is the current behaviour so, let's keep
- // track of it, so we will know in case it would ever change.
- assert.strictEqual( $.colorUtil.getRGB( 'rgba(0,0,0,0)' ), undefined, 'Zero rgba without whitespace' );
-
- assert.deepEqual( $.colorUtil.getRGB( 'lightGreen' ), [144, 238, 144], 'Color names (lightGreen)' );
- assert.deepEqual( $.colorUtil.getRGB( 'transparent' ), [255, 255, 255], 'Color names (transparent)' );
- assert.strictEqual( $.colorUtil.getRGB( 'mediaWiki' ), undefined, 'Inexisting color name' );
-});
-
-QUnit.test( 'rgbToHsl', 1, function ( assert ) {
- var hsl = $.colorUtil.rgbToHsl( 144, 238, 144 );
-
- // Cross-browser differences in decimals...
- // Round to two decimals so they can be more reliably checked.
- var dualDecimals = function(a,b){
- return Math.round(a*100)/100;
- };
- // Re-create the rgbToHsl return array items, limited to two decimals.
- var ret = [dualDecimals(hsl[0]), dualDecimals(hsl[1]), dualDecimals(hsl[2])];
-
- assert.deepEqual( ret, [0.33, 0.73, 0.75], 'rgb(144, 238, 144): hsl(0.33, 0.73, 0.75)' );
-});
-
-QUnit.test( 'hslToRgb', 1, function ( assert ) {
- var rgb = $.colorUtil.hslToRgb( 0.3, 0.7, 0.8 );
-
- // Cross-browser differences in decimals...
- // Re-create the hslToRgb return array items, rounded to whole numbers.
- var ret = [Math.round(rgb[0]), Math.round(rgb[1]), Math.round(rgb[2])];
-
- assert.deepEqual( ret ,[183, 240, 168], 'hsl(0.3, 0.7, 0.8): rgb(183, 240, 168)' );
-});
-
-QUnit.test( 'getColorBrightness', 2, function ( assert ) {
- var a = $.colorUtil.getColorBrightness( 'red', +0.1 );
- assert.equal( a, 'rgb(255,50,50)', 'Start with named color "red", brighten 10%' );
-
- var b = $.colorUtil.getColorBrightness( 'rgb(200,50,50)', -0.2 );
- assert.equal( b, 'rgb(118,29,29)', 'Start with rgb string "rgb(200,50,50)", darken 20%' );
-});
+( function ( $ ) {
+ QUnit.module( 'jquery.colorUtil', QUnit.newMwEnvironment() );
+
+ QUnit.test( 'getRGB', 18, function ( assert ) {
+ assert.strictEqual( $.colorUtil.getRGB(), undefined, 'No arguments' );
+ assert.strictEqual( $.colorUtil.getRGB( '' ), undefined, 'Empty string' );
+ assert.deepEqual( $.colorUtil.getRGB( [0, 100, 255] ), [0, 100, 255], 'Parse array of rgb values' );
+ assert.deepEqual( $.colorUtil.getRGB( 'rgb(0,100,255)' ), [0, 100, 255], 'Parse simple rgb string' );
+ assert.deepEqual( $.colorUtil.getRGB( 'rgb(0, 100, 255)' ), [0, 100, 255], 'Parse simple rgb string with spaces' );
+ assert.deepEqual( $.colorUtil.getRGB( 'rgb(0%,20%,40%)' ), [0, 51, 102], 'Parse rgb string with percentages' );
+ assert.deepEqual( $.colorUtil.getRGB( 'rgb(0%, 20%, 40%)' ), [0, 51, 102], 'Parse rgb string with percentages and spaces' );
+ assert.deepEqual( $.colorUtil.getRGB( '#f2ddee' ), [242, 221, 238], 'Hex string: 6 char lowercase' );
+ assert.deepEqual( $.colorUtil.getRGB( '#f2DDEE' ), [242, 221, 238], 'Hex string: 6 char uppercase' );
+ assert.deepEqual( $.colorUtil.getRGB( '#f2DdEe' ), [242, 221, 238], 'Hex string: 6 char mixed' );
+ assert.deepEqual( $.colorUtil.getRGB( '#eee' ), [238, 238, 238], 'Hex string: 3 char lowercase' );
+ assert.deepEqual( $.colorUtil.getRGB( '#EEE' ), [238, 238, 238], 'Hex string: 3 char uppercase' );
+ assert.deepEqual( $.colorUtil.getRGB( '#eEe' ), [238, 238, 238], 'Hex string: 3 char mixed' );
+ assert.deepEqual( $.colorUtil.getRGB( 'rgba(0, 0, 0, 0)' ), [255, 255, 255], 'Zero rgba for Safari 3; Transparent (whitespace)' );
+
+ // Perhaps this is a bug in colorUtil, but it is the current behaviour so, let's keep
+ // track of it, so we will know in case it would ever change.
+ assert.strictEqual( $.colorUtil.getRGB( 'rgba(0,0,0,0)' ), undefined, 'Zero rgba without whitespace' );
+
+ assert.deepEqual( $.colorUtil.getRGB( 'lightGreen' ), [144, 238, 144], 'Color names (lightGreen)' );
+ assert.deepEqual( $.colorUtil.getRGB( 'transparent' ), [255, 255, 255], 'Color names (transparent)' );
+ assert.strictEqual( $.colorUtil.getRGB( 'mediaWiki' ), undefined, 'Inexisting color name' );
+ });
+
+ QUnit.test( 'rgbToHsl', 1, function ( assert ) {
+ var hsl, ret;
+
+ // Cross-browser differences in decimals...
+ // Round to two decimals so they can be more reliably checked.
+ function dualDecimals( a ) {
+ return Math.round( a * 100 ) / 100;
+ }
+ // Re-create the rgbToHsl return array items, limited to two decimals.
+ hsl = $.colorUtil.rgbToHsl( 144, 238, 144 );
+ ret = [ dualDecimals( hsl[0] ), dualDecimals( hsl[1] ), dualDecimals( hsl[2] ) ];
+
+ assert.deepEqual( ret, [0.33, 0.73, 0.75], 'rgb(144, 238, 144): hsl(0.33, 0.73, 0.75)' );
+ });
+
+ QUnit.test( 'hslToRgb', 1, function ( assert ) {
+ var rgb, ret;
+ rgb = $.colorUtil.hslToRgb( 0.3, 0.7, 0.8 );
+
+ // Re-create the hslToRgb return array items, rounded to whole numbers.
+ ret = [ Math.round(rgb[0]), Math.round(rgb[1]), Math.round(rgb[2]) ];
+
+ assert.deepEqual( ret ,[183, 240, 168], 'hsl(0.3, 0.7, 0.8): rgb(183, 240, 168)' );
+ });
+
+ QUnit.test( 'getColorBrightness', 2, function ( assert ) {
+ var a, b;
+ a = $.colorUtil.getColorBrightness( 'red', +0.1 );
+ assert.equal( a, 'rgb(255,50,50)', 'Start with named color "red", brighten 10%' );
+
+ b = $.colorUtil.getColorBrightness( 'rgb(200,50,50)', -0.2 );
+ assert.equal( b, 'rgb(118,29,29)', 'Start with rgb string "rgb(200,50,50)", darken 20%' );
+ });
+}( jQuery ) );
-QUnit.asyncTest('jquery.delayedBind with data option', 2, function ( assert ) {
- var $fixture = $('<div>').appendTo('#qunit-fixture'),
- data = { magic: "beeswax" },
- delay = 50;
+( function ( $ ) {
+ QUnit.asyncTest('jquery.delayedBind with data option', 2, function ( assert ) {
+ var $fixture = $('<div>').appendTo('#qunit-fixture'),
+ data = {
+ magic: 'beeswax'
+ },
+ delay = 50;
- $fixture.delayedBind(delay, 'testevent', data, function ( e ) {
- QUnit.start(); // continue!
- assert.ok( true, 'testevent fired');
- assert.ok( e.data === data, 'data is passed through delayedBind');
+ $fixture.delayedBind(delay, 'testevent', data, function ( e ) {
+ assert.ok( true, 'testevent fired');
+ assert.ok( e.data === data, 'data is passed through delayedBind');
+ QUnit.start();
+ });
+
+ // We'll trigger it thrice, but it should only happen once.
+ $fixture.trigger( 'testevent', {} );
+ $fixture.trigger( 'testevent', {} );
+ $fixture.trigger( 'testevent', {} );
+ $fixture.trigger( 'testevent', {} );
});
- // We'll trigger it thrice, but it should only happen once.
- $fixture.trigger( 'testevent', {} );
- $fixture.trigger( 'testevent', {} );
- $fixture.trigger( 'testevent', {} );
- $fixture.trigger( 'testevent', {} );
-});
+ QUnit.asyncTest('jquery.delayedBind without data option', 1, function ( assert ) {
+ var $fixture = $('<div>').appendTo('#qunit-fixture'),
+ delay = 50;
-QUnit.asyncTest('jquery.delayedBind without data option', 1, function ( assert ) {
- var $fixture = $('<div>').appendTo('#qunit-fixture'),
- data = { magic: "beeswax" },
- delay = 50;
+ $fixture.delayedBind(delay, 'testevent', function () {
+ assert.ok(true, 'testevent fired');
+ QUnit.start();
+ });
- $fixture.delayedBind(delay, 'testevent', function ( e ) {
- QUnit.start(); // continue!
- assert.ok(true, 'testevent fired');
+ // We'll trigger it thrice, but it should only happen once.
+ $fixture.trigger( 'testevent', {} );
+ $fixture.trigger( 'testevent', {} );
+ $fixture.trigger( 'testevent', {} );
+ $fixture.trigger( 'testevent', {} );
});
-
- // We'll trigger it thrice, but it should only happen once.
- $fixture.trigger( 'testevent', {} );
- $fixture.trigger( 'testevent', {} );
- $fixture.trigger( 'testevent', {} );
- $fixture.trigger( 'testevent', {} );
-});
-
+}( jQuery ) );
-QUnit.module( 'jquery.getAttrs', QUnit.newMwEnvironment() );
+( function ( $ ) {
+ QUnit.module( 'jquery.getAttrs', QUnit.newMwEnvironment() );
-QUnit.test( 'Check', 1, function ( assert ) {
- var attrs = {
- foo: 'bar',
- 'class': 'lorem'
- },
- $el = jQuery( '<div>', attrs );
+ QUnit.test( 'Check', 1, function ( assert ) {
+ var attrs = {
+ foo: 'bar',
+ 'class': 'lorem'
+ },
+ $el = $( '<div>' ).attr( attrs );
- assert.deepEqual( $el.getAttrs(), attrs, 'getAttrs() return object should match the attributes set, no more, no less' );
-} );
+ assert.deepEqual( $el.getAttrs(), attrs, 'getAttrs() return object should match the attributes set, no more, no less' );
+ } );
+}( jQuery ) );
-QUnit.module( 'jquery.hidpi', QUnit.newMwEnvironment() );
+( function ( $ ) {
+ QUnit.module( 'jquery.hidpi', QUnit.newMwEnvironment() );
-QUnit.test( 'devicePixelRatio', function ( assert ) {
- var devicePixelRatio = $.devicePixelRatio();
- assert.equal( typeof devicePixelRatio, 'number', '$.devicePixelRatio() returns a number' );
-});
+ QUnit.test( 'devicePixelRatio', function ( assert ) {
+ var devicePixelRatio = $.devicePixelRatio();
+ assert.equal( typeof devicePixelRatio, 'number', '$.devicePixelRatio() returns a number' );
+ });
-QUnit.test( 'matchSrcSet', function ( assert ) {
- var srcset = 'onefive.png 1.5x, two.png 2x';
+ QUnit.test( 'matchSrcSet', function ( assert ) {
+ var srcset = 'onefive.png 1.5x, two.png 2x';
- // Nice exact matches
- assert.equal( $.matchSrcSet( 1, srcset ), null, '1.0 gives no match' );
- assert.equal( $.matchSrcSet( 1.5, srcset ), 'onefive.png', '1.5 gives match' );
- assert.equal( $.matchSrcSet( 2, srcset ), 'two.png', '2 gives match' );
+ // Nice exact matches
+ assert.equal( $.matchSrcSet( 1, srcset ), null, '1.0 gives no match' );
+ assert.equal( $.matchSrcSet( 1.5, srcset ), 'onefive.png', '1.5 gives match' );
+ assert.equal( $.matchSrcSet( 2, srcset ), 'two.png', '2 gives match' );
- // Non-exact matches; should return the next-biggest specified
- assert.equal( $.matchSrcSet( 1.25, srcset ), null, '1.25 gives no match' );
- assert.equal( $.matchSrcSet( 1.75, srcset ), 'onefive.png', '1.75 gives match to 1.5' );
- assert.equal( $.matchSrcSet( 2.25, srcset ), 'two.png', '2.25 gives match to 2' );
-});
+ // Non-exact matches; should return the next-biggest specified
+ assert.equal( $.matchSrcSet( 1.25, srcset ), null, '1.25 gives no match' );
+ assert.equal( $.matchSrcSet( 1.75, srcset ), 'onefive.png', '1.75 gives match to 1.5' );
+ assert.equal( $.matchSrcSet( 2.25, srcset ), 'two.png', '2.25 gives match to 2' );
+ });
+}( jQuery ) );
-QUnit.module( 'jquery.highlightText', QUnit.newMwEnvironment() );
+( function ( $ ) {
+ 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>ل إيردوس'
- }
- ];
- QUnit.expect( cases.length );
+ 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>ل إيردوس'
+ }
+ ];
+ QUnit.expect( cases.length );
- $.each( cases, function ( i, item ) {
- $fixture = $( '<p>' ).text( item.text ).highlightText( item.highlight );
- assert.equal(
- $fixture.html(),
- $( '<p>' ).html( item.expected ).html(), // re-parse to normalize!
- item.desc || undefined
- );
+ $.each( cases, function ( i, item ) {
+ $fixture = $( '<p>' ).text( item.text ).highlightText( item.highlight );
+ assert.equal(
+ $fixture.html(),
+ // Re-parse to normalize
+ $( '<p>' ).html( item.expected ).html(),
+ item.desc || undefined
+ );
+ } );
} );
-} );
+}( jQuery ) );
-QUnit.module( 'jquery.localize', QUnit.newMwEnvironment() );
+( function ( $, mw ) {
+ QUnit.module( 'jquery.localize', QUnit.newMwEnvironment() );
-QUnit.test( 'Handle basic replacements', 4, function ( assert ) {
- var html, $lc;
- mw.messages.set( 'basic', 'Basic stuff' );
+ QUnit.test( 'Handle basic replacements', 4, function ( assert ) {
+ var html, $lc;
+ mw.messages.set( 'basic', 'Basic stuff' );
- // Tag: html:msg
- html = '<div><span><html:msg key="basic" /></span></div>';
- $lc = $( html ).localize().find( 'span' );
+ // Tag: html:msg
+ html = '<div><span><html:msg key="basic" /></span></div>';
+ $lc = $( html ).localize().find( 'span' );
- assert.strictEqual( $lc.text(), 'Basic stuff', 'Tag: html:msg' );
+ assert.strictEqual( $lc.text(), 'Basic stuff', 'Tag: html:msg' );
- // Attribute: title-msg
- html = '<div><span title-msg="basic"></span></div>';
- $lc = $( html ).localize().find( 'span' );
+ // Attribute: title-msg
+ html = '<div><span title-msg="basic"></span></div>';
+ $lc = $( html ).localize().find( 'span' );
- assert.strictEqual( $lc.attr( 'title' ), 'Basic stuff', 'Attribute: title-msg' );
+ assert.strictEqual( $lc.attr( 'title' ), 'Basic stuff', 'Attribute: title-msg' );
- // Attribute: alt-msg
- html = '<div><span alt-msg="basic"></span></div>';
- $lc = $( html ).localize().find( 'span' );
+ // Attribute: alt-msg
+ html = '<div><span alt-msg="basic"></span></div>';
+ $lc = $( html ).localize().find( 'span' );
- assert.strictEqual( $lc.attr( 'alt' ), 'Basic stuff', 'Attribute: alt-msg' );
+ assert.strictEqual( $lc.attr( 'alt' ), 'Basic stuff', 'Attribute: alt-msg' );
- // Attribute: placeholder-msg
- html = '<div><input placeholder-msg="basic" /></div>';
- $lc = $( html ).localize().find( 'input' );
+ // Attribute: placeholder-msg
+ html = '<div><input placeholder-msg="basic" /></div>';
+ $lc = $( html ).localize().find( 'input' );
- assert.strictEqual( $lc.attr( 'placeholder' ), 'Basic stuff', 'Attribute: placeholder-msg' );
-} );
+ assert.strictEqual( $lc.attr( 'placeholder' ), 'Basic stuff', 'Attribute: placeholder-msg' );
+ } );
+
+ QUnit.test( 'Proper escaping', 2, function ( assert ) {
+ var html, $lc;
+ mw.messages.set( 'properfoo', '<proper esc="test">' );
+
+ // This is handled by jQuery inside $.fn.localize, just a simple sanity checked
+ // making sure it is actually using text() and attr() (or something with the same effect)
-QUnit.test( 'Proper escaping', 2, function ( assert ) {
- var html, $lc;
- mw.messages.set( 'properfoo', '<proper esc="test">' );
+ // Text escaping
+ html = '<div><span><html:msg key="properfoo"></span></div>';
+ $lc = $( html ).localize().find( 'span' );
- // This is handled by jQuery inside $.fn.localize, just a simple sanity checked
- // making sure it is actually using text() and attr() (or something with the same effect)
+ assert.strictEqual( $lc.text(), mw.msg( 'properfoo' ), 'Content is inserted as text, not as html.' );
- // Text escaping
- html = '<div><span><html:msg key="properfoo"></span></div>';
- $lc = $( html ).localize().find( 'span' );
+ // Attribute escaping
+ html = '<div><span title-msg="properfoo"></span></div>';
+ $lc = $( html ).localize().find( 'span' );
- assert.strictEqual( $lc.text(), mw.msg( 'properfoo' ), 'Content is inserted as text, not as html.' );
+ assert.strictEqual( $lc.attr( 'title' ), mw.msg( 'properfoo' ), 'Attributes are not inserted raw.' );
+ } );
- // Attribute escaping
- html = '<div><span title-msg="properfoo"></span></div>';
- $lc = $( html ).localize().find( 'span' );
+ QUnit.test( 'Options', 7, function ( assert ) {
+ mw.messages.set( {
+ 'foo-lorem': 'Lorem',
+ 'foo-ipsum': 'Ipsum',
+ 'foo-bar-title': 'Read more about bars',
+ 'foo-bar-label': 'The Bars',
+ 'foo-bazz-title': 'Read more about bazz at $1 (last modified: $2)',
+ '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>';
+ $lc = $( html ).localize( {
+ prefix: 'foo-'
+ } ).find( 'span' );
+
+ assert.strictEqual( $lc.attr( 'title' ), 'Lorem', 'Message key prefix - attr' );
+ assert.strictEqual( $lc.text(), 'Ipsum', 'Message key prefix - text' );
+
+ // Variable keys mapping
+ x = 'bar';
+ html = '<div><span title-msg="title"><html:msg key="label"></span></div>';
+ $lc = $( html ).localize( {
+ keys: {
+ 'title': 'foo-' + x + '-title',
+ 'label': 'foo-' + x + '-label'
+ }
+ } ).find( 'span' );
+
+ assert.strictEqual( $lc.attr( 'title' ), 'Read more about bars', 'Variable keys mapping - attr' );
+ assert.strictEqual( $lc.text(), 'The Bars', 'Variable keys mapping - text' );
+
+ // Passing parameteters to mw.msg
+ html = '<div><span><html:msg key="foo-welcome"></span></div>';
+ $lc = $( html ).localize( {
+ params: {
+ 'foo-welcome': [sitename, 'yesterday']
+ }
+ } ).find( 'span' );
+
+ assert.strictEqual( $lc.text(), 'Welcome to Wikipedia! (last visit: yesterday)', 'Passing parameteters to mw.msg' );
+
+ // Combination of options prefix, params and keys
+ x = 'bazz';
+ html = '<div><span title-msg="title"><html:msg key="label"></span></div>';
+ $lc = $( html ).localize( {
+ prefix: 'foo-',
+ keys: {
+ 'title': x + '-title',
+ 'label': x + '-label'
+ },
+ params: {
+ 'title': [sitename, '3 minutes ago'],
+ 'label': [sitename, '3 minutes ago']
+
+ }
+ } ).find( 'span' );
+
+ assert.strictEqual( $lc.text(), 'The Bazz (Wikipedia)', 'Combination of options prefix, params and keys - text' );
+ assert.strictEqual( $lc.attr( 'title' ), 'Read more about bazz at Wikipedia (last modified: 3 minutes ago)', 'Combination of options prefix, params and keys - attr' );
+ } );
- assert.strictEqual( $lc.attr( 'title' ), mw.msg( 'properfoo' ), 'Attributes are not inserted raw.' );
-} );
+ QUnit.test( 'Handle data text', 2, function ( assert ) {
+ var html, $lc;
+ mw.messages.set( 'option-one', 'Item 1' );
+ mw.messages.set( 'option-two', 'Item 2' );
+ html = '<select><option data-msg-text="option-one"></option><option data-msg-text="option-two"></option></select>';
+ $lc = $( html ).localize().find( 'option' );
+ assert.strictEqual( $lc.eq( 0 ).text(), mw.msg( 'option-one' ), 'data-msg-text becomes text of options' );
+ assert.strictEqual( $lc.eq( 1 ).text(), mw.msg( 'option-two' ), 'data-msg-text becomes text of options' );
+ } );
-QUnit.test( 'Options', 7, function ( assert ) {
- mw.messages.set( {
- 'foo-lorem': 'Lorem',
- 'foo-ipsum': 'Ipsum',
- 'foo-bar-title': 'Read more about bars',
- 'foo-bar-label': 'The Bars',
- 'foo-bazz-title': 'Read more about bazz at $1 (last modified: $2)',
- 'foo-bazz-label': 'The Bazz ($1)',
- 'foo-welcome': 'Welcome to $1! (last visit: $2)'
+ QUnit.test( 'Handle data html', 2, function ( assert ) {
+ var html, $lc;
+ mw.messages.set( 'html', 'behold... there is a <a>link</a> here!!' );
+ html = '<div><div data-msg-html="html"></div></div>';
+ $lc = $( html ).localize().find( 'a' );
+ assert.strictEqual( $lc.length, 1, 'link is created' );
+ assert.strictEqual( $lc.text(), 'link', 'the link text got added' );
} );
- var html, $lc, attrs, x, sitename = 'Wikipedia';
-
- // Message key prefix
- html = '<div><span title-msg="lorem"><html:msg key="ipsum"></span></div>';
- $lc = $( html ).localize( {
- prefix: 'foo-'
- } ).find( 'span' );
-
- assert.strictEqual( $lc.attr( 'title' ), 'Lorem', 'Message key prefix - attr' );
- assert.strictEqual( $lc.text(), 'Ipsum', 'Message key prefix - text' );
-
- // Variable keys mapping
- x = 'bar';
- html = '<div><span title-msg="title"><html:msg key="label"></span></div>';
- $lc = $( html ).localize( {
- keys: {
- 'title': 'foo-' + x + '-title',
- 'label': 'foo-' + x + '-label'
- }
- } ).find( 'span' );
-
- assert.strictEqual( $lc.attr( 'title' ), 'Read more about bars', 'Variable keys mapping - attr' );
- assert.strictEqual( $lc.text(), 'The Bars', 'Variable keys mapping - text' );
-
- // Passing parameteters to mw.msg
- html = '<div><span><html:msg key="foo-welcome"></span></div>';
- $lc = $( html ).localize( {
- params: {
- 'foo-welcome': [sitename, 'yesterday']
- }
- } ).find( 'span' );
-
- assert.strictEqual( $lc.text(), 'Welcome to Wikipedia! (last visit: yesterday)', 'Passing parameteters to mw.msg' );
-
- // Combination of options prefix, params and keys
- x = 'bazz';
- html = '<div><span title-msg="title"><html:msg key="label"></span></div>';
- $lc = $( html ).localize( {
- prefix: 'foo-',
- keys: {
- 'title': x + '-title',
- 'label': x + '-label'
- },
- params: {
- 'title': [sitename, '3 minutes ago'],
- 'label': [sitename, '3 minutes ago']
-
- }
- } ).find( 'span' );
-
- assert.strictEqual( $lc.text(), 'The Bazz (Wikipedia)', 'Combination of options prefix, params and keys - text' );
- assert.strictEqual( $lc.attr( 'title' ), 'Read more about bazz at Wikipedia (last modified: 3 minutes ago)', 'Combination of options prefix, params and keys - attr' );
-} );
-
-QUnit.test( 'Handle data text', 2, function ( assert ) {
- var html, $lc;
- mw.messages.set( 'option-one', 'Item 1' );
- mw.messages.set( 'option-two', 'Item 2' );
- html = '<select><option data-msg-text="option-one"></option><option data-msg-text="option-two"></option></select>';
- $lc = $( html ).localize().find( 'option' );
- assert.strictEqual( $lc.eq( 0 ).text(), mw.msg( 'option-one' ), 'data-msg-text becomes text of options' );
- assert.strictEqual( $lc.eq( 1 ).text(), mw.msg( 'option-two' ), 'data-msg-text becomes text of options' );
-} );
-
-QUnit.test( 'Handle data html', 2, function ( assert ) {
- var html, $lc;
- mw.messages.set( 'html', 'behold... there is a <a>link</a> here!!' );
- html = '<div><div data-msg-html="html"></div></div>';
- $lc = $( html ).localize().find( 'a' );
- assert.strictEqual( $lc.length, 1, 'link is created' );
- assert.strictEqual( $lc.text(), 'link', 'the link text got added' );
-} );
+}( jQuery, mediaWiki ) ) ;
-QUnit.module( 'jquery.mwExtension', QUnit.newMwEnvironment() );
-
-QUnit.test( 'String functions', function ( assert ) {
-
- assert.equal( $.trimLeft( ' foo bar ' ), 'foo bar ', 'trimLeft' );
- assert.equal( $.trimRight( ' foo bar ' ), ' foo bar', 'trimRight' );
- assert.equal( $.ucFirst( 'foo' ), 'Foo', 'ucFirst' );
-
- assert.equal( $.escapeRE( '<!-- ([{+mW+}]) $^|?>' ),
- '<!\\-\\- \\(\\[\\{\\+mW\\+\\}\\]\\) \\$\\^\\|\\?>', 'escapeRE - Escape specials' );
- assert.equal( $.escapeRE( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ),
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'escapeRE - Leave uppercase alone' );
- assert.equal( $.escapeRE( 'abcdefghijklmnopqrstuvwxyz' ),
- 'abcdefghijklmnopqrstuvwxyz', 'escapeRE - Leave lowercase alone' );
- assert.equal( $.escapeRE( '0123456789' ), '0123456789', 'escapeRE - Leave numbers alone' );
-});
-
-QUnit.test( 'Is functions', function ( assert ) {
-
- assert.strictEqual( $.isDomElement( document.getElementById( 'qunit-header' ) ), true,
- 'isDomElement: #qunit-header Node' );
- assert.strictEqual( $.isDomElement( document.getElementById( 'random-name' ) ), false,
- 'isDomElement: #random-name (null)' );
- assert.strictEqual( $.isDomElement( document.getElementsByTagName( 'div' ) ), false,
- 'isDomElement: getElementsByTagName Array' );
- assert.strictEqual( $.isDomElement( document.getElementsByTagName( 'div' )[0] ), true,
- 'isDomElement: getElementsByTagName(..)[0] Node' );
- assert.strictEqual( $.isDomElement( $( 'div' ) ), false,
- 'isDomElement: jQuery object' );
- assert.strictEqual( $.isDomElement( $( 'div' ).get(0) ), true,
- 'isDomElement: jQuery object > Get node' );
- assert.strictEqual( $.isDomElement( document.createElement( 'div' ) ), true,
- 'isDomElement: createElement' );
- assert.strictEqual( $.isDomElement( { foo: 1 } ), false,
- 'isDomElement: Object' );
-
- assert.strictEqual( $.isEmpty( 'string' ), false, 'isEmptry: "string"' );
- assert.strictEqual( $.isEmpty( '0' ), true, 'isEmptry: "0"' );
- assert.strictEqual( $.isEmpty( '' ), true, 'isEmptry: ""' );
- assert.strictEqual( $.isEmpty( 1 ), false, 'isEmptry: 1' );
- assert.strictEqual( $.isEmpty( [] ), true, 'isEmptry: []' );
- assert.strictEqual( $.isEmpty( {} ), true, 'isEmptry: {}' );
-
- // Documented behaviour
- assert.strictEqual( $.isEmpty( { length: 0 } ), true, 'isEmptry: { length: 0 }' );
-});
-
-QUnit.test( 'Comparison functions', function ( assert ) {
-
- assert.ok( $.compareArray( [0, 'a', [], [2, 'b'] ], [0, "a", [], [2, "b"] ] ),
- 'compareArray: Two deep arrays that are excactly the same' );
- assert.ok( !$.compareArray( [1], [2] ), 'compareArray: Two different arrays (false)' );
-
- assert.ok( $.compareObject( {}, {} ), 'compareObject: Two empty objects' );
- assert.ok( $.compareObject( { foo: 1 }, { foo: 1 } ), 'compareObject: Two the same objects' );
- assert.ok( !$.compareObject( { bar: true }, { baz: false } ),
- 'compareObject: Two different objects (false)' );
-});
+( function ( $ ) {
+ QUnit.module( 'jquery.mwExtension', QUnit.newMwEnvironment() );
+
+ QUnit.test( 'String functions', function ( assert ) {
+
+ assert.equal( $.trimLeft( ' foo bar ' ), 'foo bar ', 'trimLeft' );
+ assert.equal( $.trimRight( ' foo bar ' ), ' foo bar', 'trimRight' );
+ assert.equal( $.ucFirst( 'foo' ), 'Foo', 'ucFirst' );
+
+ assert.equal( $.escapeRE( '<!-- ([{+mW+}]) $^|?>' ),
+ '<!\\-\\- \\(\\[\\{\\+mW\\+\\}\\]\\) \\$\\^\\|\\?>', 'escapeRE - Escape specials' );
+ assert.equal( $.escapeRE( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ),
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'escapeRE - Leave uppercase alone' );
+ assert.equal( $.escapeRE( 'abcdefghijklmnopqrstuvwxyz' ),
+ 'abcdefghijklmnopqrstuvwxyz', 'escapeRE - Leave lowercase alone' );
+ assert.equal( $.escapeRE( '0123456789' ), '0123456789', 'escapeRE - Leave numbers alone' );
+ });
+
+ QUnit.test( 'Is functions', function ( assert ) {
+
+ assert.strictEqual( $.isDomElement( document.getElementById( 'qunit-header' ) ), true,
+ 'isDomElement: #qunit-header Node' );
+ assert.strictEqual( $.isDomElement( document.getElementById( 'random-name' ) ), false,
+ 'isDomElement: #random-name (null)' );
+ assert.strictEqual( $.isDomElement( document.getElementsByTagName( 'div' ) ), false,
+ 'isDomElement: getElementsByTagName Array' );
+ assert.strictEqual( $.isDomElement( document.getElementsByTagName( 'div' )[0] ), true,
+ 'isDomElement: getElementsByTagName(..)[0] Node' );
+ assert.strictEqual( $.isDomElement( $( 'div' ) ), false,
+ 'isDomElement: jQuery object' );
+ assert.strictEqual( $.isDomElement( $( 'div' ).get(0) ), true,
+ 'isDomElement: jQuery object > Get node' );
+ assert.strictEqual( $.isDomElement( document.createElement( 'div' ) ), true,
+ 'isDomElement: createElement' );
+ assert.strictEqual( $.isDomElement( { foo: 1 } ), false,
+ 'isDomElement: Object' );
+
+ assert.strictEqual( $.isEmpty( 'string' ), false, 'isEmptry: "string"' );
+ assert.strictEqual( $.isEmpty( '0' ), true, 'isEmptry: "0"' );
+ assert.strictEqual( $.isEmpty( '' ), true, 'isEmptry: ""' );
+ assert.strictEqual( $.isEmpty( 1 ), false, 'isEmptry: 1' );
+ assert.strictEqual( $.isEmpty( [] ), true, 'isEmptry: []' );
+ assert.strictEqual( $.isEmpty( {} ), true, 'isEmptry: {}' );
+
+ // Documented behaviour
+ assert.strictEqual( $.isEmpty( { length: 0 } ), true, 'isEmptry: { length: 0 }' );
+ });
+
+ QUnit.test( 'Comparison functions', function ( assert ) {
+
+ assert.ok( $.compareArray( [0, 'a', [], [2, 'b'] ], [0, 'a', [], [2, 'b'] ] ),
+ 'compareArray: Two deep arrays that are excactly the same' );
+ assert.ok( !$.compareArray( [1], [2] ), 'compareArray: Two different arrays (false)' );
+
+ assert.ok( $.compareObject( {}, {} ), 'compareObject: Two empty objects' );
+ assert.ok( $.compareObject( { foo: 1 }, { foo: 1 } ), 'compareObject: Two the same objects' );
+ assert.ok( !$.compareObject( { bar: true }, { baz: false } ),
+ 'compareObject: Two different objects (false)' );
+ });
+}( jQuery ) );
-QUnit.module( 'jquery.tabIndex', QUnit.newMwEnvironment() );
+( function ( $ ) {
+ QUnit.module( 'jquery.tabIndex', QUnit.newMwEnvironment() );
-QUnit.test( 'firstTabIndex', 2, function ( assert ) {
- var testEnvironment =
-'<form>' +
- '<input tabindex="7" />' +
- '<input tabindex="9" />' +
- '<textarea tabindex="2">Foobar</textarea>' +
- '<textarea tabindex="5">Foobar</textarea>' +
-'</form>';
+ QUnit.test( 'firstTabIndex', 2, function ( assert ) {
+ var html, $testA, $testB;
+ html =
+ '<form>' +
+ '<input tabindex="7" />' +
+ '<input tabindex="9" />' +
+ '<textarea tabindex="2">Foobar</textarea>' +
+ '<textarea tabindex="5">Foobar</textarea>' +
+ '</form>';
- var $testA = $( '<div>' ).html( testEnvironment ).appendTo( '#qunit-fixture' );
- assert.strictEqual( $testA.firstTabIndex(), 2, 'First tabindex should be 2 within this context.' );
+ $testA = $( '<div>' ).html( html ).appendTo( '#qunit-fixture' );
+ assert.strictEqual( $testA.firstTabIndex(), 2, 'First tabindex should be 2 within this context.' );
- var $testB = $( '<div>' );
- assert.strictEqual( $testB.firstTabIndex(), null, 'Return null if none available.' );
-});
+ $testB = $( '<div>' );
+ assert.strictEqual( $testB.firstTabIndex(), null, 'Return null if none available.' );
+ });
-QUnit.test( 'lastTabIndex', 2, function ( assert ) {
- var testEnvironment =
-'<form>' +
- '<input tabindex="7" />' +
- '<input tabindex="9" />' +
- '<textarea tabindex="2">Foobar</textarea>' +
- '<textarea tabindex="5">Foobar</textarea>' +
-'</form>';
+ QUnit.test( 'lastTabIndex', 2, function ( assert ) {
+ var html, $testA, $testB;
+ html =
+ '<form>' +
+ '<input tabindex="7" />' +
+ '<input tabindex="9" />' +
+ '<textarea tabindex="2">Foobar</textarea>' +
+ '<textarea tabindex="5">Foobar</textarea>' +
+ '</form>';
- var $testA = $( '<div>' ).html( testEnvironment ).appendTo( '#qunit-fixture' );
- assert.strictEqual( $testA.lastTabIndex(), 9, 'Last tabindex should be 9 within this context.' );
+ $testA = $( '<div>' ).html( html ).appendTo( '#qunit-fixture' );
+ assert.strictEqual( $testA.lastTabIndex(), 9, 'Last tabindex should be 9 within this context.' );
- var $testB = $( '<div>' );
- assert.strictEqual( $testB.lastTabIndex(), null, 'Return null if none available.' );
-});
+ $testB = $( '<div>' );
+ assert.strictEqual( $testB.lastTabIndex(), null, 'Return null if none available.' );
+ });
+}( jQuery ) );
( function ( $, mw ) {
-
-var config = {
- wgMonthNames: ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
- wgMonthNamesShort: ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
- wgDefaultDateFormat: 'dmy',
- wgContentLanguage: 'en'
-};
-
-QUnit.module( 'jquery.tablesorter', QUnit.newMwEnvironment({ config: config }) );
-
-/**
- * Create an HTML table from an array of row arrays containing text strings.
- * First row will be header row. No fancy rowspan/colspan stuff.
- *
- * @param {String[]} header
- * @param {String[][]} data
- * @return jQuery
- */
-function tableCreate( header, data ) {
- var i,
- $table = $( '<table class="sortable"><thead></thead><tbody></tbody></table>' ),
- $thead = $table.find( 'thead' ),
- $tbody = $table.find( 'tbody' ),
- $tr = $( '<tr>' );
-
- $.each( header, function ( i, str ) {
- var $th = $( '<th>' );
- $th.text( str ).appendTo( $tr );
- });
- $tr.appendTo( $thead );
-
- for ( i = 0; i < data.length; i++ ) {
- $tr = $( '<tr>' );
- $.each( data[i], function ( j, str ) {
- var $td = $( '<td>' );
- $td.text( str ).appendTo( $tr );
+ /*jshint onevar: false */
+
+ var config = {
+ wgMonthNames: ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+ wgMonthNamesShort: ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+ wgDefaultDateFormat: 'dmy',
+ wgContentLanguage: 'en'
+ };
+
+ QUnit.module( 'jquery.tablesorter', QUnit.newMwEnvironment({ config: config }) );
+
+ /**
+ * Create an HTML table from an array of row arrays containing text strings.
+ * First row will be header row. No fancy rowspan/colspan stuff.
+ *
+ * @param {String[]} header
+ * @param {String[][]} data
+ * @return jQuery
+ */
+ function tableCreate( header, data ) {
+ var i,
+ $table = $( '<table class="sortable"><thead></thead><tbody></tbody></table>' ),
+ $thead = $table.find( 'thead' ),
+ $tbody = $table.find( 'tbody' ),
+ $tr = $( '<tr>' );
+
+ $.each( header, function ( i, str ) {
+ var $th = $( '<th>' );
+ $th.text( str ).appendTo( $tr );
});
- $tr.appendTo( $tbody );
+ $tr.appendTo( $thead );
+
+ for ( i = 0; i < data.length; i++ ) {
+ /*jshint loopfunc: true */
+ $tr = $( '<tr>' );
+ $.each( data[i], function ( j, str ) {
+ var $td = $( '<td>' );
+ $td.text( str ).appendTo( $tr );
+ });
+ $tr.appendTo( $tbody );
+ }
+ return $table;
}
- return $table;
-}
-
-/**
- * Extract text from table.
- *
- * @param {jQuery} $table
- * @return String[][]
- */
-function tableExtract( $table ) {
- var data = [];
-
- $table.find( 'tbody' ).find( 'tr' ).each( function( i, tr ) {
- var row = [];
- $( tr ).find( 'td,th' ).each( function( i, td ) {
- row.push( $( td ).text() );
+
+ /**
+ * Extract text from table.
+ *
+ * @param {jQuery} $table
+ * @return String[][]
+ */
+ function tableExtract( $table ) {
+ var data = [];
+
+ $table.find( 'tbody' ).find( 'tr' ).each( function( i, tr ) {
+ var row = [];
+ $( tr ).find( 'td,th' ).each( function( i, td ) {
+ row.push( $( td ).text() );
+ });
+ data.push( row );
});
- data.push( row );
- });
- return data;
-}
-
-/**
- * Run a table test by building a table with the given data,
- * running some callback on it, then checking the results.
- *
- * @param {String} msg text to pass on to qunit for the comparison
- * @param {String[]} header cols to make the table
- * @param {String[][]} data rows/cols to make the table
- * @param {String[][]} expected rows/cols to compare against at end
- * @param {function($table)} callback something to do with the table before we compare
- */
-function tableTest( msg, header, data, expected, callback ) {
- QUnit.test( msg, 1, function ( assert ) {
- var $table = tableCreate( header, data );
-
- // Give caller a chance to set up sorting and manipulate the table.
- callback( $table );
-
- // Table sorting is done synchronously; if it ever needs to change back
- // to asynchronous, we'll need a timeout or a callback here.
- var extracted = tableExtract( $table );
- assert.deepEqual( extracted, expected, msg );
- });
-}
-
-function reversed(arr) {
- // Clone array
- var arr2 = arr.slice(0);
-
- arr2.reverse();
-
- return arr2;
-}
-
-// Sample data set using planets named and their radius
-var header = [ 'Planet' , 'Radius (km)'],
- mercury = [ 'Mercury', '2439.7' ],
- venus = [ 'Venus' , '6051.8' ],
- earth = [ 'Earth' , '6371.0' ],
- mars = [ 'Mars' , '3390.0' ],
- jupiter = [ 'Jupiter', '69911' ],
- saturn = [ 'Saturn' , '58232' ];
-
-// Initial data set
-var planets = [mercury, venus, earth, mars, jupiter, saturn];
-var ascendingName = [earth, jupiter, mars, mercury, saturn, venus];
-var ascendingRadius = [mercury, mars, venus, earth, saturn, jupiter];
-
-tableTest(
- 'Basic planet table: sorting initially - ascending by name',
- header,
- planets,
- ascendingName,
- function ( $table ) {
- $table.tablesorter( { sortList: [ { 0: 'asc' } ] } );
- }
-);
-tableTest(
- 'Basic planet table: sorting initially - descending by radius',
- header,
- planets,
- reversed(ascendingRadius),
- function ( $table ) {
- $table.tablesorter( { sortList: [ { 1: 'desc' } ] } );
- }
-);
-tableTest(
- 'Basic planet table: ascending by name',
- header,
- planets,
- ascendingName,
- function ( $table ) {
- $table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click();
- }
-);
-tableTest(
- 'Basic planet table: ascending by name a second time',
- header,
- planets,
- ascendingName,
- function ( $table ) {
- $table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click();
- }
-);
-tableTest(
- 'Basic planet table: descending by name',
- header,
- planets,
- reversed(ascendingName),
- function ( $table ) {
- $table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click().click();
+ return data;
}
-);
-tableTest(
- 'Basic planet table: ascending radius',
- header,
- planets,
- ascendingRadius,
- function ( $table ) {
- $table.tablesorter();
- $table.find( '.headerSort:eq(1)' ).click();
+
+ /**
+ * Run a table test by building a table with the given data,
+ * running some callback on it, then checking the results.
+ *
+ * @param {String} msg text to pass on to qunit for the comparison
+ * @param {String[]} header cols to make the table
+ * @param {String[][]} data rows/cols to make the table
+ * @param {String[][]} expected rows/cols to compare against at end
+ * @param {function($table)} callback something to do with the table before we compare
+ */
+ function tableTest( msg, header, data, expected, callback ) {
+ QUnit.test( msg, 1, function ( assert ) {
+ var $table = tableCreate( header, data );
+
+ // Give caller a chance to set up sorting and manipulate the table.
+ callback( $table );
+
+ // Table sorting is done synchronously; if it ever needs to change back
+ // to asynchronous, we'll need a timeout or a callback here.
+ var extracted = tableExtract( $table );
+ assert.deepEqual( extracted, expected, msg );
+ });
}
-);
-tableTest(
- 'Basic planet table: descending radius',
- header,
- planets,
- reversed(ascendingRadius),
- function ( $table ) {
- $table.tablesorter();
- $table.find( '.headerSort:eq(1)' ).click().click();
+
+ function reversed(arr) {
+ // Clone array
+ var arr2 = arr.slice(0);
+
+ arr2.reverse();
+
+ return arr2;
}
-);
-
-// Sample data set to test multiple column sorting
-var header = [ 'column1' , 'column2'],
- a1 = [ 'A', '1' ],
- a2 = [ 'A', '2' ],
- a3 = [ 'A', '3' ],
- b1 = [ 'B', '1' ],
- b2 = [ 'B', '2' ],
- b3 = [ 'B', '3' ];
-var initial = [a2, b3, a1, a3, b2, b1];
-var asc = [a1, a2, a3, b1, b2, b3];
-var descasc = [b1, b2, b3, a1, a2, a3];
-
-tableTest(
- 'Sorting multiple columns by passing sort list',
- header,
- initial,
- asc,
- function ( $table ) {
+
+ // Sample data set using planets named and their radius
+ var header = [ 'Planet' , 'Radius (km)'],
+ mercury = [ 'Mercury', '2439.7' ],
+ venus = [ 'Venus' , '6051.8' ],
+ earth = [ 'Earth' , '6371.0' ],
+ mars = [ 'Mars' , '3390.0' ],
+ jupiter = [ 'Jupiter', '69911' ],
+ saturn = [ 'Saturn' , '58232' ];
+
+ // Initial data set
+ var planets = [mercury, venus, earth, mars, jupiter, saturn];
+ var ascendingName = [earth, jupiter, mars, mercury, saturn, venus];
+ var ascendingRadius = [mercury, mars, venus, earth, saturn, jupiter];
+
+ tableTest(
+ 'Basic planet table: sorting initially - ascending by name',
+ header,
+ planets,
+ ascendingName,
+ function ( $table ) {
+ $table.tablesorter( { sortList: [ { 0: 'asc' } ] } );
+ }
+ );
+ tableTest(
+ 'Basic planet table: sorting initially - descending by radius',
+ header,
+ planets,
+ reversed(ascendingRadius),
+ function ( $table ) {
+ $table.tablesorter( { sortList: [ { 1: 'desc' } ] } );
+ }
+ );
+ tableTest(
+ 'Basic planet table: ascending by name',
+ header,
+ planets,
+ ascendingName,
+ function ( $table ) {
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click();
+ }
+ );
+ tableTest(
+ 'Basic planet table: ascending by name a second time',
+ header,
+ planets,
+ ascendingName,
+ function ( $table ) {
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click();
+ }
+ );
+ tableTest(
+ 'Basic planet table: descending by name',
+ header,
+ planets,
+ reversed(ascendingName),
+ function ( $table ) {
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click().click();
+ }
+ );
+ tableTest(
+ 'Basic planet table: ascending radius',
+ header,
+ planets,
+ ascendingRadius,
+ function ( $table ) {
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(1)' ).click();
+ }
+ );
+ tableTest(
+ 'Basic planet table: descending radius',
+ header,
+ planets,
+ reversed(ascendingRadius),
+ function ( $table ) {
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(1)' ).click().click();
+ }
+ );
+
+ // Sample data set to test multiple column sorting
+ header = [ 'column1' , 'column2'];
+ var
+ a1 = [ 'A', '1' ],
+ a2 = [ 'A', '2' ],
+ a3 = [ 'A', '3' ],
+ b1 = [ 'B', '1' ],
+ b2 = [ 'B', '2' ],
+ b3 = [ 'B', '3' ];
+ var initial = [a2, b3, a1, a3, b2, b1];
+ var asc = [a1, a2, a3, b1, b2, b3];
+ var descasc = [b1, b2, b3, a1, a2, a3];
+
+ tableTest(
+ 'Sorting multiple columns by passing sort list',
+ header,
+ initial,
+ asc,
+ function ( $table ) {
+ $table.tablesorter(
+ { sortList: [ { 0: 'asc' }, { 1: 'asc' } ] }
+ );
+ }
+ );
+ tableTest(
+ 'Sorting multiple columns by programmatically triggering sort()',
+ header,
+ initial,
+ descasc,
+ function ( $table ) {
+ $table.tablesorter();
+ $table.data( 'tablesorter' ).sort(
+ [ { 0: 'desc' }, { 1: 'asc' } ]
+ );
+ }
+ );
+ tableTest(
+ 'Reset to initial sorting by triggering sort() without any parameters',
+ header,
+ initial,
+ asc,
+ function ( $table ) {
+ $table.tablesorter(
+ { sortList: [ { 0: 'asc' }, { 1: 'asc' } ] }
+ );
+ $table.data( 'tablesorter' ).sort(
+ [ { 0: 'desc' }, { 1: 'asc' } ]
+ );
+ $table.data( 'tablesorter' ).sort();
+ }
+ );
+ QUnit.test( 'Reset sorting making table appear unsorted', 3, function ( assert ) {
+ var $table = tableCreate( header, initial );
$table.tablesorter(
- { sortList: [ { 0: 'asc' }, { 1: 'asc' } ] }
+ { sortList: [ { 0: 'desc' }, { 1: 'asc' } ] }
);
- }
-);
-tableTest(
- 'Sorting multiple columns by programmatically triggering sort()',
- header,
- initial,
- descasc,
- function ( $table ) {
- $table.tablesorter();
- $table.data( 'tablesorter' ).sort(
- [ { 0: 'desc' }, { 1: 'asc' } ]
+ $table.data( 'tablesorter' ).sort( [] );
+
+ assert.equal(
+ $table.find( 'th.headerSortUp' ).length + $table.find( 'th.headerSortDown' ).length,
+ 0,
+ 'No sort specific sort classes addign to header cells'
);
- }
-);
-tableTest(
- 'Reset to initial sorting by triggering sort() without any parameters',
- header,
- initial,
- asc,
- function ( $table ) {
- $table.tablesorter(
- { sortList: [ { 0: 'asc' }, { 1: 'asc' } ] }
+
+ assert.equal(
+ $table.find( 'th' ).first().attr( 'title' ),
+ mw.msg( 'sort-ascending' ),
+ 'First header cell has default title'
);
- $table.data( 'tablesorter' ).sort(
- [ { 0: 'desc' }, { 1: 'asc' } ]
+
+ assert.equal(
+ $table.find( 'th' ).first().attr( 'title' ),
+ $table.find( 'th' ).last().attr( 'title' ),
+ 'Both header cells\' titles match'
);
- $table.data( 'tablesorter' ).sort();
- }
-);
-QUnit.test( 'Reset sorting making table appear unsorted', 3, function ( assert ) {
- var $table = tableCreate( header, initial );
- $table.tablesorter(
- { sortList: [ { 0: 'desc' }, { 1: 'asc' } ] }
+ } );
+
+ // Regression tests!
+ tableTest(
+ 'Bug 28775: German-style (dmy) short numeric dates',
+ ['Date'],
+ [ // German-style dates are day-month-year
+ ['11.11.2011'],
+ ['01.11.2011'],
+ ['02.10.2011'],
+ ['03.08.2011'],
+ ['09.11.2011']
+ ],
+ [ // Sorted by ascending date
+ ['03.08.2011'],
+ ['02.10.2011'],
+ ['01.11.2011'],
+ ['09.11.2011'],
+ ['11.11.2011']
+ ],
+ function ( $table ) {
+ mw.config.set( 'wgDefaultDateFormat', 'dmy' );
+ mw.config.set( 'wgContentLanguage', 'de' );
+
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click();
+ }
);
- $table.data( 'tablesorter' ).sort( [] );
- assert.equal(
- $table.find( 'th.headerSortUp' ).length + $table.find( 'th.headerSortDown' ).length,
- 0,
- 'No sort specific sort classes addign to header cells'
+ tableTest(
+ 'Bug 28775: American-style (mdy) short numeric dates',
+ ['Date'],
+ [ // American-style dates are month-day-year
+ ['11.11.2011'],
+ ['01.11.2011'],
+ ['02.10.2011'],
+ ['03.08.2011'],
+ ['09.11.2011']
+ ],
+ [ // Sorted by ascending date
+ ['01.11.2011'],
+ ['02.10.2011'],
+ ['03.08.2011'],
+ ['09.11.2011'],
+ ['11.11.2011']
+ ],
+ function ( $table ) {
+ mw.config.set( 'wgDefaultDateFormat', 'mdy' );
+
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click();
+ }
);
- assert.equal(
- $table.find( 'th' ).first().attr( 'title' ),
- mw.msg( 'sort-ascending' ),
- 'First header cell has default title'
+ var ipv4 = [
+ // Some randomly generated fake IPs
+ ['45.238.27.109'],
+ ['44.172.9.22'],
+ ['247.240.82.209'],
+ ['204.204.132.158'],
+ ['170.38.91.162'],
+ ['197.219.164.9'],
+ ['45.68.154.72'],
+ ['182.195.149.80']
+ ];
+ var ipv4Sorted = [
+ // Sort order should go octet by octet
+ ['44.172.9.22'],
+ ['45.68.154.72'],
+ ['45.238.27.109'],
+ ['170.38.91.162'],
+ ['182.195.149.80'],
+ ['197.219.164.9'],
+ ['204.204.132.158'],
+ ['247.240.82.209']
+ ];
+
+ tableTest(
+ 'Bug 17141: IPv4 address sorting',
+ ['IP'],
+ ipv4,
+ ipv4Sorted,
+ function ( $table ) {
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click();
+ }
);
-
- assert.equal(
- $table.find( 'th' ).first().attr( 'title' ),
- $table.find( 'th' ).last().attr( 'title' ),
- 'Both header cells\' titles match'
+ tableTest(
+ 'Bug 17141: IPv4 address sorting (reverse)',
+ ['IP'],
+ ipv4,
+ reversed(ipv4Sorted),
+ function ( $table ) {
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click().click();
+ }
);
-} );
-
-// Regression tests!
-tableTest(
- 'Bug 28775: German-style (dmy) short numeric dates',
- ['Date'],
- [ // German-style dates are day-month-year
- ['11.11.2011'],
- ['01.11.2011'],
- ['02.10.2011'],
- ['03.08.2011'],
- ['09.11.2011']
- ],
- [ // Sorted by ascending date
- ['03.08.2011'],
- ['02.10.2011'],
- ['01.11.2011'],
- ['09.11.2011'],
- ['11.11.2011']
- ],
- function ( $table ) {
- mw.config.set( 'wgDefaultDateFormat', 'dmy' );
- mw.config.set( 'wgContentLanguage', 'de' );
- $table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click();
- }
-);
-
-tableTest(
- 'Bug 28775: American-style (mdy) short numeric dates',
- ['Date'],
- [ // American-style dates are month-day-year
- ['11.11.2011'],
- ['01.11.2011'],
- ['02.10.2011'],
- ['03.08.2011'],
- ['09.11.2011']
- ],
- [ // Sorted by ascending date
- ['01.11.2011'],
- ['02.10.2011'],
- ['03.08.2011'],
- ['09.11.2011'],
- ['11.11.2011']
- ],
- function ( $table ) {
- mw.config.set( 'wgDefaultDateFormat', 'mdy' );
-
- $table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click();
- }
-);
-
-var ipv4 = [
- // Some randomly generated fake IPs
- ['45.238.27.109'],
- ['44.172.9.22'],
- ['247.240.82.209'],
- ['204.204.132.158'],
- ['170.38.91.162'],
- ['197.219.164.9'],
- ['45.68.154.72'],
- ['182.195.149.80']
-];
-var ipv4Sorted = [
- // Sort order should go octet by octet
- ['44.172.9.22'],
- ['45.68.154.72'],
- ['45.238.27.109'],
- ['170.38.91.162'],
- ['182.195.149.80'],
- ['197.219.164.9'],
- ['204.204.132.158'],
- ['247.240.82.209']
-];
-
-tableTest(
- 'Bug 17141: IPv4 address sorting',
- ['IP'],
- ipv4,
- ipv4Sorted,
- function ( $table ) {
- $table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click();
- }
-);
-tableTest(
- 'Bug 17141: IPv4 address sorting (reverse)',
- ['IP'],
- ipv4,
- reversed(ipv4Sorted),
- function ( $table ) {
- $table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click().click();
- }
-);
-
-var umlautWords = [
- // Some words with Umlauts
- ['Günther'],
- ['Peter'],
- ['Björn'],
- ['Bjorn'],
- ['Apfel'],
- ['Äpfel'],
- ['Strasse'],
- ['Sträßschen']
-];
-
-var umlautWordsSorted = [
- // Some words with Umlauts
- ['Äpfel'],
- ['Apfel'],
- ['Björn'],
- ['Bjorn'],
- ['Günther'],
- ['Peter'],
- ['Sträßschen'],
- ['Strasse']
-];
-
-tableTest(
- 'Accented Characters with custom collation',
- ['Name'],
- umlautWords,
- umlautWordsSorted,
- function ( $table ) {
- mw.config.set( 'tableSorterCollation', {
- 'ä': 'ae',
- 'ö': 'oe',
- 'ß': 'ss',
- 'ü':'ue'
- } );
-
- $table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click();
- }
-);
-
-var planetsRowspan = [["Earth","6051.8"], jupiter, ["Mars","6051.8"], mercury, saturn, venus];
-var planetsRowspanII = [jupiter, mercury, saturn, venus, ['Venus', '6371.0'], ['Venus', '3390.0']];
-
-tableTest(
- 'Basic planet table: same value for multiple rows via rowspan',
- header,
- planets,
- planetsRowspan,
- function ( $table ) {
- // Modify the table to have a multiple-row-spanning cell:
- // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row.
- $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove();
- // - Set rowspan for 2nd cell of 3rd row to 3.
- // This covers the removed cell in the 4th and 5th row.
- $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' );
-
- $table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click();
- }
-);
-tableTest(
- 'Basic planet table: same value for multiple rows via rowspan (sorting initially)',
- header,
- planets,
- planetsRowspan,
- function ( $table ) {
- // Modify the table to have a multiple-row-spanning cell:
- // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row.
- $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove();
- // - Set rowspan for 2nd cell of 3rd row to 3.
- // This covers the removed cell in the 4th and 5th row.
- $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' );
-
- $table.tablesorter( { sortList: [ { 0: 'asc' } ] } );
- }
-);
-tableTest(
- 'Basic planet table: Same value for multiple rows via rowspan II',
- header,
- planets,
- planetsRowspanII,
- function ( $table ) {
- // Modify the table to have a multiple-row-spanning cell:
- // - Remove 1st cell of 4th row, and, 1st cell or 5th row.
- $table.find( 'tr:eq(3) td:eq(0), tr:eq(4) td:eq(0)' ).remove();
- // - Set rowspan for 1st cell of 3rd row to 3.
- // This covers the removed cell in the 4th and 5th row.
- $table.find( 'tr:eq(2) td:eq(0)' ).prop( 'rowspan', '3' );
-
- $table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click();
- }
-);
-
-var complexMDYDates = [
- // Some words with Umlauts
- ['January, 19 2010'],
- ['April 21 1991'],
- ['04 22 1991'],
- ['5.12.1990'],
- ['December 12 \'10']
-];
-
-var complexMDYSorted = [
- ['5.12.1990'],
- ['April 21 1991'],
- ['04 22 1991'],
- ['January, 19 2010'],
- ['December 12 \'10']
-];
-
-tableTest(
- 'Complex date parsing I',
- ['date'],
- complexMDYDates,
- complexMDYSorted,
- function ( $table ) {
- mw.config.set( 'wgDefaultDateFormat', 'mdy' );
+ var umlautWords = [
+ // Some words with Umlauts
+ ['Günther'],
+ ['Peter'],
+ ['Björn'],
+ ['Bjorn'],
+ ['Apfel'],
+ ['Äpfel'],
+ ['Strasse'],
+ ['Sträßschen']
+ ];
+
+ var umlautWordsSorted = [
+ // Some words with Umlauts
+ ['Äpfel'],
+ ['Apfel'],
+ ['Björn'],
+ ['Bjorn'],
+ ['Günther'],
+ ['Peter'],
+ ['Sträßschen'],
+ ['Strasse']
+ ];
+
+ tableTest(
+ 'Accented Characters with custom collation',
+ ['Name'],
+ umlautWords,
+ umlautWordsSorted,
+ function ( $table ) {
+ mw.config.set( 'tableSorterCollation', {
+ 'ä': 'ae',
+ 'ö': 'oe',
+ 'ß': 'ss',
+ 'ü':'ue'
+ } );
- $table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click();
- }
-);
-
-var currencyUnsorted = [
- ['1.02 $'],
- ['$ 3.00'],
- ['€ 2,99'],
- ['$ 1.00'],
- ['$3.50'],
- ['$ 1.50'],
- ['€ 0.99']
-];
-
-var currencySorted = [
- ['€ 0.99'],
- ['$ 1.00'],
- ['1.02 $'],
- ['$ 1.50'],
- ['$ 3.00'],
- ['$3.50'],
- // Comma's sort after dots
- // Not intentional but test to detect changes
- ['€ 2,99']
-];
-
-tableTest(
- 'Currency parsing I',
- ['currency'],
- currencyUnsorted,
- currencySorted,
- function ( $table ) {
- $table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click();
- }
-);
-
-var ascendingNameLegacy = ascendingName.slice(0);
-ascendingNameLegacy[4] = ascendingNameLegacy[5];
-ascendingNameLegacy.pop();
-
-tableTest(
- 'Legacy compat with .sortbottom',
- header,
- planets,
- ascendingNameLegacy,
- function( $table ) {
- $table.find( 'tr:last' ).addClass( 'sortbottom' );
- $table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click();
- }
-);
-
-QUnit.test( 'Test detection routine', function ( assert ) {
- var $table;
- $table = $(
- '<table class="sortable">' +
- '<caption>CAPTION</caption>' +
- '<tr><th>THEAD</th></tr>' +
- '<tr><td>1</td></tr>' +
- '<tr class="sortbottom"><td>text</td></tr>' +
- '</table>'
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click();
+ }
);
- $table.tablesorter();
- assert.equal(
- $table.data( 'tablesorter' ).config.parsers[0].id,
- 'number',
- 'Correctly detected column content skipping sortbottom'
+ var planetsRowspan = [ [ 'Earth', '6051.8' ], jupiter, [ 'Mars', '6051.8' ], mercury, saturn, venus ];
+ var planetsRowspanII = [ jupiter, mercury, saturn, venus, [ 'Venus', '6371.0' ], [ 'Venus', '3390.0' ] ];
+
+ tableTest(
+ 'Basic planet table: same value for multiple rows via rowspan',
+ header,
+ planets,
+ planetsRowspan,
+ function ( $table ) {
+ // Modify the table to have a multiple-row-spanning cell:
+ // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row.
+ $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove();
+ // - Set rowspan for 2nd cell of 3rd row to 3.
+ // This covers the removed cell in the 4th and 5th row.
+ $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' );
+
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click();
+ }
);
-} );
-
-/** FIXME: the diff output is not very readeable. */
-QUnit.test( 'bug 32047 - caption must be before thead', function ( assert ) {
- var $table;
- $table = $(
- '<table class="sortable">' +
- '<caption>CAPTION</caption>' +
- '<tr><th>THEAD</th></tr>' +
- '<tr><td>A</td></tr>' +
- '<tr><td>B</td></tr>' +
- '<tr class="sortbottom"><td>TFOOT</td></tr>' +
- '</table>'
- );
- $table.tablesorter();
-
- assert.equal(
- $table.children( ).get( 0 ).nodeName,
- 'CAPTION',
- 'First element after <thead> must be <caption> (bug 32047)'
+ tableTest(
+ 'Basic planet table: same value for multiple rows via rowspan (sorting initially)',
+ header,
+ planets,
+ planetsRowspan,
+ function ( $table ) {
+ // Modify the table to have a multiple-row-spanning cell:
+ // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row.
+ $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove();
+ // - Set rowspan for 2nd cell of 3rd row to 3.
+ // This covers the removed cell in the 4th and 5th row.
+ $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' );
+
+ $table.tablesorter( { sortList: [ { 0: 'asc' } ] } );
+ }
);
-});
-
-QUnit.test( 'data-sort-value attribute, when available, should override sorting position', function ( assert ) {
- var $table, data;
-
- // Example 1: All cells except one cell without data-sort-value,
- // which should be sorted at it's text content value.
- $table = $(
- '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' +
- '<tbody>' +
- '<tr><td>Cheetah</td></tr>' +
- '<tr><td data-sort-value="Apple">Bird</td></tr>' +
- '<tr><td data-sort-value="Bananna">Ferret</td></tr>' +
- '<tr><td data-sort-value="Drupe">Elephant</td></tr>' +
- '<tr><td data-sort-value="Cherry">Dolphin</td></tr>' +
- '</tbody></table>'
+ tableTest(
+ 'Basic planet table: Same value for multiple rows via rowspan II',
+ header,
+ planets,
+ planetsRowspanII,
+ function ( $table ) {
+ // Modify the table to have a multiple-row-spanning cell:
+ // - Remove 1st cell of 4th row, and, 1st cell or 5th row.
+ $table.find( 'tr:eq(3) td:eq(0), tr:eq(4) td:eq(0)' ).remove();
+ // - Set rowspan for 1st cell of 3rd row to 3.
+ // This covers the removed cell in the 4th and 5th row.
+ $table.find( 'tr:eq(2) td:eq(0)' ).prop( 'rowspan', '3' );
+
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click();
+ }
);
- $table.tablesorter().find( '.headerSort:eq(0)' ).click();
-
- data = [];
- $table.find( 'tbody > tr' ).each( function( i, tr ) {
- $( tr ).find( 'td' ).each( function( i, td ) {
- data.push( {
- data: $( td ).data( 'sortValue' ),
- text: $( td ).text()
- } );
- });
- });
- assert.deepEqual( data, [
- {
- data: 'Apple',
- text: 'Bird'
- }, {
- data: 'Bananna',
- text: 'Ferret'
- }, {
- data: undefined,
- text: 'Cheetah'
- }, {
- data: 'Cherry',
- text: 'Dolphin'
- }, {
- data: 'Drupe',
- text: 'Elephant'
+ var complexMDYDates = [
+ // Some words with Umlauts
+ ['January, 19 2010'],
+ ['April 21 1991'],
+ ['04 22 1991'],
+ ['5.12.1990'],
+ ['December 12 \'10']
+ ];
+
+ var complexMDYSorted = [
+ ['5.12.1990'],
+ ['April 21 1991'],
+ ['04 22 1991'],
+ ['January, 19 2010'],
+ ['December 12 \'10']
+ ];
+
+ tableTest(
+ 'Complex date parsing I',
+ ['date'],
+ complexMDYDates,
+ complexMDYSorted,
+ function ( $table ) {
+ mw.config.set( 'wgDefaultDateFormat', 'mdy' );
+
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click();
}
- ], 'Order matches expected order (based on data-sort-value attribute values)' );
-
- // Example 2
- $table = $(
- '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' +
- '<tbody>' +
- '<tr><td>D</td></tr>' +
- '<tr><td data-sort-value="E">A</td></tr>' +
- '<tr><td>B</td></tr>' +
- '<tr><td>G</td></tr>' +
- '<tr><td data-sort-value="F">C</td></tr>' +
- '</tbody></table>'
);
- $table.tablesorter().find( '.headerSort:eq(0)' ).click();
-
- data = [];
- $table.find( 'tbody > tr' ).each( function ( i, tr ) {
- $( tr ).find( 'td' ).each( function ( i, td ) {
- data.push( {
- data: $( td ).data( 'sortValue' ),
- text: $( td ).text()
- } );
- });
- });
- assert.deepEqual( data, [
- {
- data: undefined,
- text: 'B'
- }, {
- data: undefined,
- text: 'D'
- }, {
- data: 'E',
- text: 'A'
- }, {
- data: 'F',
- text: 'C'
- }, {
- data: undefined,
- text: 'G'
+ var currencyUnsorted = [
+ ['1.02 $'],
+ ['$ 3.00'],
+ ['€ 2,99'],
+ ['$ 1.00'],
+ ['$3.50'],
+ ['$ 1.50'],
+ ['€ 0.99']
+ ];
+
+ var currencySorted = [
+ ['€ 0.99'],
+ ['$ 1.00'],
+ ['1.02 $'],
+ ['$ 1.50'],
+ ['$ 3.00'],
+ ['$3.50'],
+ // Comma's sort after dots
+ // Not intentional but test to detect changes
+ ['€ 2,99']
+ ];
+
+ tableTest(
+ 'Currency parsing I',
+ ['currency'],
+ currencyUnsorted,
+ currencySorted,
+ function ( $table ) {
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click();
}
- ], 'Order matches expected order (based on data-sort-value attribute values)' );
-
- // Example 3: Test that live changes are used from data-sort-value,
- // even if they change after the tablesorter is constructed (bug 38152).
- $table = $(
- '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' +
- '<tbody>' +
- '<tr><td>D</td></tr>' +
- '<tr><td data-sort-value="1">A</td></tr>' +
- '<tr><td>B</td></tr>' +
- '<tr><td data-sort-value="2">G</td></tr>' +
- '<tr><td>C</td></tr>' +
- '</tbody></table>'
);
- // initialize table sorter and sort once
- $table
- .tablesorter()
- .find( '.headerSort:eq(0)' ).click();
-
- // Change the sortValue data properties (bug 38152)
- // - change data
- $table.find( 'td:contains(A)' ).data( 'sortValue', 3 );
- // - add data
- $table.find( 'td:contains(B)' ).data( 'sortValue', 1 );
- // - remove data, bring back attribute: 2
- $table.find( 'td:contains(G)' ).removeData( 'sortValue' );
-
- // Now sort again (twice, so it is back at Ascending)
- $table.find( '.headerSort:eq(0)' ).click();
- $table.find( '.headerSort:eq(0)' ).click();
-
- data = [];
- $table.find( 'tbody > tr' ).each( function( i, tr ) {
- $( tr ).find( 'td' ).each( function( i, td ) {
- data.push( {
- data: $( td ).data( 'sortValue' ),
- text: $( td ).text()
- } );
- });
- });
- assert.deepEqual( data, [
- {
- data: 1,
- text: "B"
- }, {
- data: 2,
- text: "G"
- }, {
- data: 3,
- text: "A"
- }, {
- data: undefined,
- text: "C"
- }, {
- data: undefined,
- text: "D"
+ var ascendingNameLegacy = ascendingName.slice(0);
+ ascendingNameLegacy[4] = ascendingNameLegacy[5];
+ ascendingNameLegacy.pop();
+
+ tableTest(
+ 'Legacy compat with .sortbottom',
+ header,
+ planets,
+ ascendingNameLegacy,
+ function( $table ) {
+ $table.find( 'tr:last' ).addClass( 'sortbottom' );
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click();
}
- ], 'Order matches expected order, using the current sortValue in $.data()' );
-
-});
-
-var numbers = [
- [ '12' ],
- [ '7' ],
- [ '13,000'],
- [ '9' ],
- [ '14' ],
- [ '8.0' ]
-];
-var numbersAsc = [
- [ '7' ],
- [ '8.0' ],
- [ '9' ],
- [ '12' ],
- [ '14' ],
- [ '13,000']
-];
-
-tableTest( 'bug 8115: sort numbers with commas (ascending)',
- ['Numbers'], numbers, numbersAsc,
- function( $table ) {
+ );
+
+ QUnit.test( 'Test detection routine', function ( assert ) {
+ var $table;
+ $table = $(
+ '<table class="sortable">' +
+ '<caption>CAPTION</caption>' +
+ '<tr><th>THEAD</th></tr>' +
+ '<tr><td>1</td></tr>' +
+ '<tr class="sortbottom"><td>text</td></tr>' +
+ '</table>'
+ );
$table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click();
- }
-);
-tableTest( 'bug 8115: sort numbers with commas (descending)',
- ['Numbers'], numbers, reversed(numbersAsc),
- function( $table ) {
+ assert.equal(
+ $table.data( 'tablesorter' ).config.parsers[0].id,
+ 'number',
+ 'Correctly detected column content skipping sortbottom'
+ );
+ } );
+
+ /** FIXME: the diff output is not very readeable. */
+ QUnit.test( 'bug 32047 - caption must be before thead', function ( assert ) {
+ var $table;
+ $table = $(
+ '<table class="sortable">' +
+ '<caption>CAPTION</caption>' +
+ '<tr><th>THEAD</th></tr>' +
+ '<tr><td>A</td></tr>' +
+ '<tr><td>B</td></tr>' +
+ '<tr class="sortbottom"><td>TFOOT</td></tr>' +
+ '</table>'
+ );
$table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click().click();
- }
-);
-// TODO add numbers sorting tests for bug 8115 with a different language
-
-QUnit.test( 'bug 32888 - Tables inside a tableheader cell', 2, function ( assert ) {
- var $table;
- $table = $(
- '<table class="sortable" id="mw-bug-32888">' +
- '<tr><th>header<table id="mw-bug-32888-2">'+
- '<tr><th>1</th><th>2</th></tr>' +
- '</table></th></tr>' +
- '<tr><td>A</td></tr>' +
- '<tr><td>B</td></tr>' +
- '</table>'
+
+ assert.equal(
+ $table.children( ).get( 0 ).nodeName,
+ 'CAPTION',
+ 'First element after <thead> must be <caption> (bug 32047)'
);
- $table.tablesorter();
+ });
- assert.equal(
- $table.find('> thead:eq(0) > tr > th.headerSort').length,
- 1,
- 'Child tables inside a headercell should not interfere with sortable headers (bug 32888)'
- );
- assert.equal(
- $( '#mw-bug-32888-2' ).find('th.headerSort').length,
- 0,
- 'The headers of child tables inside a headercell should not be sortable themselves (bug 32888)'
- );
-});
+ QUnit.test( 'data-sort-value attribute, when available, should override sorting position', function ( assert ) {
+ var $table, data;
+
+ // Example 1: All cells except one cell without data-sort-value,
+ // which should be sorted at it's text content value.
+ $table = $(
+ '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' +
+ '<tbody>' +
+ '<tr><td>Cheetah</td></tr>' +
+ '<tr><td data-sort-value="Apple">Bird</td></tr>' +
+ '<tr><td data-sort-value="Bananna">Ferret</td></tr>' +
+ '<tr><td data-sort-value="Drupe">Elephant</td></tr>' +
+ '<tr><td data-sort-value="Cherry">Dolphin</td></tr>' +
+ '</tbody></table>'
+ );
+ $table.tablesorter().find( '.headerSort:eq(0)' ).click();
+
+ data = [];
+ $table.find( 'tbody > tr' ).each( function( i, tr ) {
+ $( tr ).find( 'td' ).each( function( i, td ) {
+ data.push( {
+ data: $( td ).data( 'sortValue' ),
+ text: $( td ).text()
+ } );
+ });
+ });
+ assert.deepEqual( data, [
+ {
+ data: 'Apple',
+ text: 'Bird'
+ }, {
+ data: 'Bananna',
+ text: 'Ferret'
+ }, {
+ data: undefined,
+ text: 'Cheetah'
+ }, {
+ data: 'Cherry',
+ text: 'Dolphin'
+ }, {
+ data: 'Drupe',
+ text: 'Elephant'
+ }
+ ], 'Order matches expected order (based on data-sort-value attribute values)' );
+
+ // Example 2
+ $table = $(
+ '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' +
+ '<tbody>' +
+ '<tr><td>D</td></tr>' +
+ '<tr><td data-sort-value="E">A</td></tr>' +
+ '<tr><td>B</td></tr>' +
+ '<tr><td>G</td></tr>' +
+ '<tr><td data-sort-value="F">C</td></tr>' +
+ '</tbody></table>'
+ );
+ $table.tablesorter().find( '.headerSort:eq(0)' ).click();
+
+ data = [];
+ $table.find( 'tbody > tr' ).each( function ( i, tr ) {
+ $( tr ).find( 'td' ).each( function ( i, td ) {
+ data.push( {
+ data: $( td ).data( 'sortValue' ),
+ text: $( td ).text()
+ } );
+ });
+ });
-var correctDateSorting1 = [
- ['01 January 2010'],
- ['05 February 2010'],
- ['16 January 2010']
-];
+ assert.deepEqual( data, [
+ {
+ data: undefined,
+ text: 'B'
+ }, {
+ data: undefined,
+ text: 'D'
+ }, {
+ data: 'E',
+ text: 'A'
+ }, {
+ data: 'F',
+ text: 'C'
+ }, {
+ data: undefined,
+ text: 'G'
+ }
+ ], 'Order matches expected order (based on data-sort-value attribute values)' );
+
+ // Example 3: Test that live changes are used from data-sort-value,
+ // even if they change after the tablesorter is constructed (bug 38152).
+ $table = $(
+ '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' +
+ '<tbody>' +
+ '<tr><td>D</td></tr>' +
+ '<tr><td data-sort-value="1">A</td></tr>' +
+ '<tr><td>B</td></tr>' +
+ '<tr><td data-sort-value="2">G</td></tr>' +
+ '<tr><td>C</td></tr>' +
+ '</tbody></table>'
+ );
+ // initialize table sorter and sort once
+ $table
+ .tablesorter()
+ .find( '.headerSort:eq(0)' ).click();
+
+ // Change the sortValue data properties (bug 38152)
+ // - change data
+ $table.find( 'td:contains(A)' ).data( 'sortValue', 3 );
+ // - add data
+ $table.find( 'td:contains(B)' ).data( 'sortValue', 1 );
+ // - remove data, bring back attribute: 2
+ $table.find( 'td:contains(G)' ).removeData( 'sortValue' );
+
+ // Now sort again (twice, so it is back at Ascending)
+ $table.find( '.headerSort:eq(0)' ).click();
+ $table.find( '.headerSort:eq(0)' ).click();
-var correctDateSortingSorted1 = [
- ['01 January 2010'],
- ['16 January 2010'],
- ['05 February 2010']
-];
+ data = [];
+ $table.find( 'tbody > tr' ).each( function( i, tr ) {
+ $( tr ).find( 'td' ).each( function( i, td ) {
+ data.push( {
+ data: $( td ).data( 'sortValue' ),
+ text: $( td ).text()
+ } );
+ });
+ });
-tableTest(
- 'Correct date sorting I',
- ['date'],
- correctDateSorting1,
- correctDateSortingSorted1,
- function ( $table ) {
- mw.config.set( 'wgDefaultDateFormat', 'mdy' );
+ assert.deepEqual( data, [
+ {
+ data: 1,
+ text: 'B'
+ }, {
+ data: 2,
+ text: 'G'
+ }, {
+ data: 3,
+ text: 'A'
+ }, {
+ data: undefined,
+ text: 'C'
+ }, {
+ data: undefined,
+ text: 'D'
+ }
+ ], 'Order matches expected order, using the current sortValue in $.data()' );
- $table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click();
- }
-);
-
-var correctDateSorting2 = [
- ['January 01 2010'],
- ['February 05 2010'],
- ['January 16 2010']
-];
-
-var correctDateSortingSorted2 = [
- ['January 01 2010'],
- ['January 16 2010'],
- ['February 05 2010']
-];
-
-tableTest(
- 'Correct date sorting II',
- ['date'],
- correctDateSorting2,
- correctDateSortingSorted2,
- function ( $table ) {
- mw.config.set( 'wgDefaultDateFormat', 'dmy' );
+ });
+ var numbers = [
+ [ '12' ],
+ [ '7' ],
+ [ '13,000'],
+ [ '9' ],
+ [ '14' ],
+ [ '8.0' ]
+ ];
+ var numbersAsc = [
+ [ '7' ],
+ [ '8.0' ],
+ [ '9' ],
+ [ '12' ],
+ [ '14' ],
+ [ '13,000']
+ ];
+
+ tableTest( 'bug 8115: sort numbers with commas (ascending)',
+ ['Numbers'], numbers, numbersAsc,
+ function( $table ) {
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click();
+ }
+ );
+
+ tableTest( 'bug 8115: sort numbers with commas (descending)',
+ ['Numbers'], numbers, reversed(numbersAsc),
+ function( $table ) {
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click().click();
+ }
+ );
+ // TODO add numbers sorting tests for bug 8115 with a different language
+
+ QUnit.test( 'bug 32888 - Tables inside a tableheader cell', 2, function ( assert ) {
+ var $table;
+ $table = $(
+ '<table class="sortable" id="mw-bug-32888">' +
+ '<tr><th>header<table id="mw-bug-32888-2">'+
+ '<tr><th>1</th><th>2</th></tr>' +
+ '</table></th></tr>' +
+ '<tr><td>A</td></tr>' +
+ '<tr><td>B</td></tr>' +
+ '</table>'
+ );
$table.tablesorter();
- $table.find( '.headerSort:eq(0)' ).click();
- }
-);
+
+ assert.equal(
+ $table.find('> thead:eq(0) > tr > th.headerSort').length,
+ 1,
+ 'Child tables inside a headercell should not interfere with sortable headers (bug 32888)'
+ );
+ assert.equal(
+ $( '#mw-bug-32888-2' ).find('th.headerSort').length,
+ 0,
+ 'The headers of child tables inside a headercell should not be sortable themselves (bug 32888)'
+ );
+ });
+
+
+ var correctDateSorting1 = [
+ ['01 January 2010'],
+ ['05 February 2010'],
+ ['16 January 2010']
+ ];
+
+ var correctDateSortingSorted1 = [
+ ['01 January 2010'],
+ ['16 January 2010'],
+ ['05 February 2010']
+ ];
+
+ tableTest(
+ 'Correct date sorting I',
+ ['date'],
+ correctDateSorting1,
+ correctDateSortingSorted1,
+ function ( $table ) {
+ mw.config.set( 'wgDefaultDateFormat', 'mdy' );
+
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click();
+ }
+ );
+
+ var correctDateSorting2 = [
+ ['January 01 2010'],
+ ['February 05 2010'],
+ ['January 16 2010']
+ ];
+
+ var correctDateSortingSorted2 = [
+ ['January 01 2010'],
+ ['January 16 2010'],
+ ['February 05 2010']
+ ];
+
+ tableTest(
+ 'Correct date sorting II',
+ ['date'],
+ correctDateSorting2,
+ correctDateSortingSorted2,
+ function ( $table ) {
+ mw.config.set( 'wgDefaultDateFormat', 'dmy' );
+
+ $table.tablesorter();
+ $table.find( '.headerSort:eq(0)' ).click();
+ }
+ );
}( jQuery, mediaWiki ) );
-QUnit.module( 'jquery.textSelection', QUnit.newMwEnvironment() );
-
-/**
- * Test factory for $.fn.textSelection( 'encapsulateText' )
- *
- * @param options {object} associative array containing:
- * description {string}
- * input {string}
- * output {string}
- * start {int} starting char for selection
- * end {int} ending char for selection
- * params {object} add'l parameters for $().textSelection( 'encapsulateText' )
- */
-function encapsulateTest( options ) {
- var opt = $.extend({
- description: '',
- before: {},
- after: {},
- replace: {}
- }, options);
-
- opt.before = $.extend({
- text: '',
- start: 0,
- end: 0
- }, opt.before);
- opt.after = $.extend({
- text: '',
- selected: null
- }, opt.after);
-
- QUnit.test( opt.description, function ( assert ) {
- var tests = 1;
- if ( opt.after.selected !== null ) {
- tests++;
- }
- QUnit.expect( tests );
-
- var $textarea = $( '<textarea>' );
-
- $( '#qunit-fixture' ).append( $textarea );
-
- //$textarea.textSelection( 'setContents', opt.before.text); // this method is actually missing atm...
- $textarea.val( opt.before.text ); // won't work with the WikiEditor iframe?
-
- var start = opt.before.start,
- end = opt.before.end;
- if ( window.opera ) {
- // Compensate for Opera's craziness converting "\n" to "\r\n" and counting that as two chars
- var newLinesBefore = opt.before.text.substring( 0, start ).split( "\n" ).length - 1,
- newLinesInside = opt.before.text.substring( start, end ).split( "\n" ).length - 1;
- start += newLinesBefore;
- end += newLinesBefore + newLinesInside;
- }
-
- var options = $.extend( {}, opt.replace ); // Clone opt.replace
- options.selectionStart = start;
- options.selectionEnd = end;
- $textarea.textSelection( 'encapsulateSelection', options );
-
- var text = $textarea.textSelection( 'getContents' ).replace( /\r\n/g, "\n" );
-
- assert.equal( text, opt.after.text, 'Checking full text after encapsulation' );
-
- if (opt.after.selected !== null) {
- var selected = $textarea.textSelection( 'getSelection' );
- assert.equal( selected, opt.after.selected, 'Checking selected text after encapsulation.' );
- }
-
- } );
-}
-
-var 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: {
- text: "Wikilove dude! ",
- start: 15,
- end: 15
- },
- after: {
- text: "Wikilove dude! --~~~~",
- selected: ""
- },
- replace: sig
-});
-
-encapsulateTest({
- description: "Adding bold to empty",
- before: {
- text: "",
- start: 0,
- end: 0
- },
- after: {
- text: "'''Bold text'''",
- selected: "Bold text" // selected because it's the default
- },
- replace: bold
-});
-
-encapsulateTest({
- description: "Adding bold to existing text",
- before: {
- text: "Now is the time for all good men to come to the aid of their country",
- start: 20,
- end: 32
- },
- after: {
- text: "Now is the time for '''all good men''' to come to the aid of their country",
- selected: "" // empty because it's not the default'
- },
- replace: bold
-});
-
-encapsulateTest({
- description: "ownline option: adding new h2",
- before: {
- text:"Before\nAfter",
- start: 7,
- end: 7
- },
- after: {
- text: "Before\n== Heading 2 ==\nAfter",
- selected: "Heading 2"
- },
- replace: h2
-});
-
-encapsulateTest({
- description: "ownline option: turn a whole line into new h2",
- before: {
- text:"Before\nMy heading\nAfter",
- start: 7,
- end: 17
- },
- after: {
- text: "Before\n== My heading ==\nAfter",
- selected: ""
- },
- replace: h2
-});
-
-
-encapsulateTest({
- description: "ownline option: turn a partial line into new h2",
- before: {
- text:"BeforeMy headingAfter",
- start: 6,
- end: 16
- },
- after: {
- text: "Before\n== My heading ==\nAfter",
- selected: ""
- },
- replace: h2
-});
-
-
-encapsulateTest({
- description: "splitlines option: no selection, insert new list item",
- before: {
- text: "Before\nAfter",
- start: 7,
- end: 7
- },
- after: {
- text: "Before\n* Bulleted list item\nAfter"
- },
- replace: ulist
-});
-
-encapsulateTest({
- description: "splitlines option: single partial line selection, insert new list item",
- before: {
- text: "BeforeMy List ItemAfter",
- start: 6,
- end: 18
- },
- after: {
- text: "Before\n* My List Item\nAfter"
- },
- replace: ulist
-});
-
-encapsulateTest({
- description: "splitlines option: multiple lines",
- before: {
- text: "Before\nFirst\nSecond\nThird\nAfter",
- start: 7,
- end: 25
- },
- after: {
- text: "Before\n* First\n* Second\n* Third\nAfter"
- },
- replace: ulist
-});
-
-
-function caretTest( options ) {
- QUnit.test( options.description, 2, function ( assert ) {
- var $textarea = $( '<textarea>' ).text( options.text );
-
- $( '#qunit-fixture' ).append( $textarea );
-
- if ( options.mode === 'set' ) {
- $textarea.textSelection('setSelection', {
- start: options.start,
- end: options.end
- });
- }
-
- function among( actual, expected, message ) {
- if ( $.isArray( expected ) ) {
- assert.ok( $.inArray( actual, expected ) !== -1 , message + ' (got ' + actual + '; expected one of ' + expected.join(', ') + ')' );
- } else {
- assert.equal( actual, expected, message );
+( function ( $ ) {
+
+ QUnit.module( 'jquery.textSelection', QUnit.newMwEnvironment() );
+
+ /**
+ * Test factory for $.fn.textSelection( 'encapsulateText' )
+ *
+ * @param options {object} associative array containing:
+ * description {string}
+ * input {string}
+ * output {string}
+ * start {int} starting char for selection
+ * end {int} ending char for selection
+ * params {object} add'l parameters for $().textSelection( 'encapsulateText' )
+ */
+ function encapsulateTest( options ) {
+ var opt = $.extend({
+ description: '',
+ before: {},
+ after: {},
+ replace: {}
+ }, options);
+
+ opt.before = $.extend({
+ text: '',
+ start: 0,
+ end: 0
+ }, opt.before);
+ opt.after = $.extend({
+ text: '',
+ selected: null
+ }, opt.after);
+
+ QUnit.test( opt.description, function ( assert ) {
+ /*jshint onevar: false */
+ var tests = 1;
+ if ( opt.after.selected !== null ) {
+ tests++;
+ }
+ QUnit.expect( tests );
+
+ var $textarea = $( '<textarea>' );
+
+ $( '#qunit-fixture' ).append( $textarea );
+
+ //$textarea.textSelection( 'setContents', opt.before.text); // this method is actually missing atm...
+ $textarea.val( opt.before.text ); // won't work with the WikiEditor iframe?
+
+ var start = opt.before.start,
+ end = opt.before.end;
+ if ( window.opera ) {
+ // Compensate for Opera's craziness converting \n to \r\n and counting that as two chars
+ var newLinesBefore = opt.before.text.substring( 0, start ).split( '\n' ).length - 1,
+ newLinesInside = opt.before.text.substring( start, end ).split( '\n' ).length - 1;
+ start += newLinesBefore;
+ end += newLinesBefore + newLinesInside;
+ }
+
+ var options = $.extend( {}, opt.replace ); // Clone opt.replace
+ options.selectionStart = start;
+ options.selectionEnd = end;
+ $textarea.textSelection( 'encapsulateSelection', options );
+
+ var text = $textarea.textSelection( 'getContents' ).replace( /\r\n/g, '\n' );
+
+ assert.equal( text, opt.after.text, 'Checking full text after encapsulation' );
+
+ if ( opt.after.selected !== null ) {
+ var selected = $textarea.textSelection( 'getSelection' );
+ assert.equal( selected, opt.after.selected, 'Checking selected text after encapsulation.' );
+ }
+
+ } );
+ }
+
+ 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: {
+ text: 'Wikilove dude! ',
+ start: 15,
+ end: 15
+ },
+ after: {
+ text: 'Wikilove dude! --~~~~',
+ selected: ''
+ },
+ replace: sig
+ });
+
+ encapsulateTest({
+ description: 'Adding bold to empty',
+ before: {
+ text: '',
+ start: 0,
+ end: 0
+ },
+ after: {
+ text: '\'\'\'Bold text\'\'\'',
+ selected: 'Bold text' // selected because it's the default
+ },
+ replace: bold
+ });
+
+ encapsulateTest({
+ description: 'Adding bold to existing text',
+ before: {
+ text: 'Now is the time for all good men to come to the aid of their country',
+ start: 20,
+ end: 32
+ },
+ after: {
+ text: 'Now is the time for \'\'\'all good men\'\'\' to come to the aid of their country',
+ selected: '' // empty because it's not the default'
+ },
+ replace: bold
+ });
+
+ encapsulateTest({
+ description: 'ownline option: adding new h2',
+ before: {
+ text:'Before\nAfter',
+ start: 7,
+ end: 7
+ },
+ after: {
+ text: 'Before\n== Heading 2 ==\nAfter',
+ selected: 'Heading 2'
+ },
+ replace: h2
+ });
+
+ encapsulateTest({
+ description: 'ownline option: turn a whole line into new h2',
+ before: {
+ text:'Before\nMy heading\nAfter',
+ start: 7,
+ end: 17
+ },
+ after: {
+ text: 'Before\n== My heading ==\nAfter',
+ selected: ''
+ },
+ replace: h2
+ });
+
+
+ encapsulateTest({
+ description: 'ownline option: turn a partial line into new h2',
+ before: {
+ text:'BeforeMy headingAfter',
+ start: 6,
+ end: 16
+ },
+ after: {
+ text: 'Before\n== My heading ==\nAfter',
+ selected: ''
+ },
+ replace: h2
+ });
+
+
+ encapsulateTest({
+ description: 'splitlines option: no selection, insert new list item',
+ before: {
+ text: 'Before\nAfter',
+ start: 7,
+ end: 7
+ },
+ after: {
+ text: 'Before\n* Bulleted list item\nAfter'
+ },
+ replace: ulist
+ });
+
+ encapsulateTest({
+ description: 'splitlines option: single partial line selection, insert new list item',
+ before: {
+ text: 'BeforeMy List ItemAfter',
+ start: 6,
+ end: 18
+ },
+ after: {
+ text: 'Before\n* My List Item\nAfter'
+ },
+ replace: ulist
+ });
+
+ encapsulateTest({
+ description: 'splitlines option: multiple lines',
+ before: {
+ text: 'Before\nFirst\nSecond\nThird\nAfter',
+ start: 7,
+ end: 25
+ },
+ after: {
+ text: 'Before\n* First\n* Second\n* Third\nAfter'
+ },
+ replace: ulist
+ });
+
+
+ function caretTest( options ) {
+ QUnit.test( options.description, 2, function ( assert ) {
+ var pos, $textarea = $( '<textarea>' ).text( options.text );
+
+ $( '#qunit-fixture' ).append( $textarea );
+
+ if ( options.mode === 'set' ) {
+ $textarea.textSelection('setSelection', {
+ start: options.start,
+ end: options.end
+ });
+ }
+
+ function among( actual, expected, message ) {
+ if ( $.isArray( expected ) ) {
+ assert.ok( $.inArray( actual, expected ) !== -1 , message + ' (got ' + actual + '; expected one of ' + expected.join(', ') + ')' );
+ } else {
+ assert.equal( actual, expected, message );
+ }
}
- }
- var pos = $textarea.textSelection('getCaretPosition', {startAndEnd: true});
- among(pos[0], options.start, 'Caret start should be where we set it.');
- among(pos[1], options.end, 'Caret end should be where we set it.');
+ pos = $textarea.textSelection( 'getCaretPosition', { startAndEnd: true });
+ among(pos[0], options.start, 'Caret start should be where we set it.');
+ among(pos[1], options.end, 'Caret end should be where we set it.');
+ });
+ }
+
+ caretSample = 'Some big text that we like to work with. Nothing fancy... you know what I mean?';
+
+ /*
+ // @broken: Disabled per bug 34820
+ caretTest({
+ description: 'getCaretPosition with original/empty selection - bug 31847 with IE 6/7/8',
+ text: caretSample,
+ start: [0, caretSample.length], // Opera and Firefox (prior to FF 6.0) default caret to the end of the box (caretSample.length)
+ end: [0, caretSample.length], // Other browsers default it to the beginning (0), so check both.
+ mode: 'get'
+ });
+ */
+
+ caretTest({
+ description: 'set/getCaretPosition with forced empty selection',
+ text: caretSample,
+ start: 7,
+ end: 7,
+ mode: 'set'
});
-}
-
-var caretSample = "Some big text that we like to work with. Nothing fancy... you know what I mean?";
-
-/*
- // @broken: Disabled per bug 34820
-caretTest({
- description: 'getCaretPosition with original/empty selection - bug 31847 with IE 6/7/8',
- text: caretSample,
- start: [0, caretSample.length], // Opera and Firefox (prior to FF 6.0) default caret to the end of the box (caretSample.length)
- end: [0, caretSample.length], // Other browsers default it to the beginning (0), so check both.
- mode: 'get'
-});
-*/
-
-caretTest({
- description: 'set/getCaretPosition with forced empty selection',
- text: caretSample,
- start: 7,
- end: 7,
- mode: 'set'
-});
-
-caretTest({
- description: 'set/getCaretPosition with small selection',
- text: caretSample,
- start: 6,
- end: 11,
- mode: 'set'
-});
+ caretTest({
+ description: 'set/getCaretPosition with small selection',
+ text: caretSample,
+ start: 6,
+ end: 11,
+ mode: 'set'
+ });
+}( jQuery ) );
-QUnit.module( 'mediawiki.api.parse', QUnit.newMwEnvironment() );
+( function ( mw, $ ) {
+ QUnit.module( 'mediawiki.api.parse', QUnit.newMwEnvironment() );
-QUnit.asyncTest( 'Hello world', function ( assert ) {
- var api;
- QUnit.expect( 6 );
+ QUnit.asyncTest( 'Hello world', function ( assert ) {
+ var api;
+ QUnit.expect( 6 );
- api = new mw.Api();
+ api = new mw.Api();
- api.parse( "'''Hello world'''" )
- .done( function ( html ) {
- // Parse into a document fragment instead of comparing HTML, due to
- // presence of Tidy influencing whitespace.
- // Html also contains "NewPP report" comment.
- var $res = $( '<div>' ).html( html ).children(),
- res = $res.get( 0 );
- assert.equal( $res.length, 1, 'Response contains 1 element' );
- assert.equal( res.nodeName.toLowerCase(), 'p', 'Response is a paragraph' );
- assert.equal( $res.children().length, 1, 'Response has 1 child element' );
- assert.equal( $res.children().get( 0 ).nodeName.toLowerCase(), 'b', 'Child element is a bold tag' );
- // Trim since Tidy may or may not mess with the spacing here
- assert.equal( $.trim( $res.text() ), 'Hello world', 'Response contains given text' );
- assert.equal( $res.find( 'b' ).text(), 'Hello world', 'Bold tag wraps the entire, same, text' );
+ api.parse( '\'\'\'Hello world\'\'\'' )
+ .done( function ( html ) {
+ // Parse into a document fragment instead of comparing HTML, due to
+ // presence of Tidy influencing whitespace.
+ // Html also contains "NewPP report" comment.
+ var $res = $( '<div>' ).html( html ).children(),
+ res = $res.get( 0 );
+ assert.equal( $res.length, 1, 'Response contains 1 element' );
+ assert.equal( res.nodeName.toLowerCase(), 'p', 'Response is a paragraph' );
+ assert.equal( $res.children().length, 1, 'Response has 1 child element' );
+ assert.equal( $res.children().get( 0 ).nodeName.toLowerCase(), 'b', 'Child element is a bold tag' );
+ // Trim since Tidy may or may not mess with the spacing here
+ assert.equal( $.trim( $res.text() ), 'Hello world', 'Response contains given text' );
+ assert.equal( $res.find( 'b' ).text(), 'Hello world', 'Bold tag wraps the entire, same, text' );
- QUnit.start();
- });
-});
+ QUnit.start();
+ });
+ });
+}( mediaWiki, jQuery ) );
-QUnit.module( 'mediawiki.api', QUnit.newMwEnvironment() );
+( function ( mw ) {
+ QUnit.module( 'mediawiki.api', QUnit.newMwEnvironment() );
+
+ QUnit.asyncTest( 'Basic functionality', function ( assert ) {
+ var api, d1, d2, d3;
+ QUnit.expect( 3 );
+
+ api = new mw.Api();
+
+ d1 = api.get( {} )
+ .done( function ( data ) {
+ assert.deepEqual( data, [], 'If request succeeds without errors, resolve deferred' );
+ });
+
+ d2 = api.get({
+ action: 'doesntexist'
+ })
+ .fail( function ( errorCode ) {
+ assert.equal( errorCode, 'unknown_action', 'API error (e.g. "unknown_action") should reject the deferred' );
+ });
+
+ d3 = api.post( {} )
+ .done( function ( data ) {
+ assert.deepEqual( data, [], 'Simple POST request' );
+ });
+
+ // After all are completed, continue the test suite.
+ QUnit.whenPromisesComplete( d1, d2, d3 ).always( function () {
+ QUnit.start();
+ });
+ });
-QUnit.asyncTest( 'Basic functionality', function ( assert ) {
- var api, d1, d2, d3;
- QUnit.expect( 3 );
+ QUnit.asyncTest( 'Deprecated callback methods', function ( assert ) {
+ var api, d1, d2, d3;
+ QUnit.expect( 3 );
- api = new mw.Api();
+ api = new mw.Api();
- d1 = api.get( {} )
- .done( function ( data ) {
- assert.deepEqual( data, [], 'If request succeeds without errors, resolve deferred' );
+ d1 = api.get( {}, function () {
+ assert.ok( true, 'Function argument treated as success callback.' );
});
- d2 = api.get({
- action: 'doesntexist'
- })
- .fail( function ( errorCode, details ) {
- assert.equal( errorCode, 'unknown_action', 'API error (e.g. "unknown_action") should reject the deferred' );
+ d2 = api.get( {}, {
+ ok: function () {
+ assert.ok( true, '"ok" property treated as success callback.' );
+ }
});
- d3 = api.post( {} )
- .done( function ( data ) {
- assert.deepEqual( data, [], 'Simple POST request' );
+ d3 = api.get({
+ action: 'doesntexist'
+ }, {
+ err: function () {
+ assert.ok( true, '"err" property treated as error callback.' );
+ }
});
- // After all are completed, continue the test suite.
- QUnit.whenPromisesComplete( d1, d2, d3 ).always( function () {
- QUnit.start();
- });
-});
-
-QUnit.asyncTest( 'Deprecated callback methods', function ( assert ) {
- var api, d1, d2, d3;
- QUnit.expect( 3 );
-
- api = new mw.Api();
-
- d1 = api.get( {}, function () {
- assert.ok( true, 'Function argument treated as success callback.' );
- });
-
- d2 = api.get( {}, {
- ok: function ( data ) {
- assert.ok( true, '"ok" property treated as success callback.' );
- }
- });
-
- d3 = api.get({
- action: 'doesntexist'
- }, {
- err: function ( data ) {
- assert.ok( true, '"err" property treated as error callback.' );
- }
- });
-
- QUnit.whenPromisesComplete( d1, d2, d3 ).always( function () {
- QUnit.start();
+ QUnit.whenPromisesComplete( d1, d2, d3 ).always( function () {
+ QUnit.start();
+ });
});
-});
+}( mediaWiki ) );
-QUnit.module( 'mediawiki.special.recentchanges', QUnit.newMwEnvironment() );
-
-// TODO: verify checkboxes == [ 'nsassociated', 'nsinvert' ]
-
-QUnit.test( '"all" namespace disable checkboxes', function ( assert ) {
-
- // from Special:Recentchanges
- var select =
- '<select id="namespace" name="namespace" class="namespaceselector">'
- + '<option value="" selected="selected">all</option>'
- + '<option value="0">(Main)</option>'
- + '<option value="1">Talk</option>'
- + '<option value="2">User</option>'
- + '<option value="3">User talk</option>'
- + '<option value="4">ProjectName</option>'
- + '<option value="5">ProjectName talk</option>'
- + '</select>'
- + '<input name="invert" type="checkbox" value="1" id="nsinvert" title="no title" />'
- + '<label for="nsinvert" title="no title">Invert selection</label>'
- + '<input name="associated" type="checkbox" value="1" id="nsassociated" title="no title" />'
- + '<label for="nsassociated" title="no title">Associated namespace</label>'
- + '<input type="submit" value="Go" />'
- + '<input type="hidden" value="Special:RecentChanges" name="title" />'
- ;
-
- var $env = $( '<div>' ).html( select ).appendTo( 'body' );
-
- // TODO abstract the double strictEquals
-
- // At first checkboxes are enabled
- assert.strictEqual( $( '#nsinvert' ).prop( 'disabled' ), false );
- assert.strictEqual( $( '#nsassociated' ).prop( 'disabled' ), false );
-
- // Initiate the recentchanges module
- mw.special.recentchanges.init();
-
- // By default
- assert.strictEqual( $( '#nsinvert' ).prop( 'disabled' ), true );
- assert.strictEqual( $( '#nsassociated' ).prop( 'disabled' ), true );
-
- // select second option...
- var $options = $( '#namespace' ).find( 'option' );
- $options.eq(0).removeProp( 'selected' );
- $options.eq(1).prop( 'selected', true );
- $( '#namespace' ).change();
-
- // ... and checkboxes should be enabled again
- assert.strictEqual( $( '#nsinvert' ).prop( 'disabled' ), false );
- assert.strictEqual( $( '#nsassociated' ).prop( 'disabled' ), false );
-
- // select first option ( 'all' namespace)...
- $options.eq(1).removeProp( 'selected' );
- $options.eq(0).prop( 'selected', true );
- $( '#namespace' ).change();
-
- // ... and checkboxes should now be disabled
- assert.strictEqual( $( '#nsinvert' ).prop( 'disabled' ), true );
- assert.strictEqual( $( '#nsassociated' ).prop( 'disabled' ), true );
-
- // DOM cleanup
- $env.remove();
-});
+( function ( mw, $ ) {
+ QUnit.module( 'mediawiki.special.recentchanges', QUnit.newMwEnvironment() );
+
+ // TODO: verify checkboxes == [ 'nsassociated', 'nsinvert' ]
+
+ QUnit.test( '"all" namespace disable checkboxes', function ( assert ) {
+ var selectHtml, $env, $options;
+
+ // from Special:Recentchanges
+ selectHtml =
+ '<select id="namespace" name="namespace" class="namespaceselector">'
+ + '<option value="" selected="selected">all</option>'
+ + '<option value="0">(Main)</option>'
+ + '<option value="1">Talk</option>'
+ + '<option value="2">User</option>'
+ + '<option value="3">User talk</option>'
+ + '<option value="4">ProjectName</option>'
+ + '<option value="5">ProjectName talk</option>'
+ + '</select>'
+ + '<input name="invert" type="checkbox" value="1" id="nsinvert" title="no title" />'
+ + '<label for="nsinvert" title="no title">Invert selection</label>'
+ + '<input name="associated" type="checkbox" value="1" id="nsassociated" title="no title" />'
+ + '<label for="nsassociated" title="no title">Associated namespace</label>'
+ + '<input type="submit" value="Go" />'
+ + '<input type="hidden" value="Special:RecentChanges" name="title" />'
+ ;
+
+ $env = $( '<div>' ).html( selectHtml ).appendTo( 'body' );
+
+ // TODO abstract the double strictEquals
+
+ // At first checkboxes are enabled
+ assert.strictEqual( $( '#nsinvert' ).prop( 'disabled' ), false );
+ assert.strictEqual( $( '#nsassociated' ).prop( 'disabled' ), false );
+
+ // Initiate the recentchanges module
+ mw.special.recentchanges.init();
+
+ // By default
+ assert.strictEqual( $( '#nsinvert' ).prop( 'disabled' ), true );
+ assert.strictEqual( $( '#nsassociated' ).prop( 'disabled' ), true );
+
+ // select second option...
+ $options = $( '#namespace' ).find( 'option' );
+ $options.eq(0).removeProp( 'selected' );
+ $options.eq(1).prop( 'selected', true );
+ $( '#namespace' ).change();
+
+ // ... and checkboxes should be enabled again
+ assert.strictEqual( $( '#nsinvert' ).prop( 'disabled' ), false );
+ assert.strictEqual( $( '#nsassociated' ).prop( 'disabled' ), false );
+
+ // select first option ( 'all' namespace)...
+ $options.eq(1).removeProp( 'selected' );
+ $options.eq(0).prop( 'selected', true );
+ $( '#namespace' ).change();
+
+ // ... and checkboxes should now be disabled
+ assert.strictEqual( $( '#nsinvert' ).prop( 'disabled' ), true );
+ assert.strictEqual( $( '#nsassociated' ).prop( 'disabled' ), true );
+
+ // DOM cleanup
+ $env.remove();
+ });
+}( mediaWiki, jQuery ) );
-( function () {
+( function ( mw ) {
// mw.Title relies on these three config vars
// Restore them after each test run
var config = {
- "wgFormattedNamespaces": {
- "-2": "Media",
- "-1": "Special",
- "0": "",
- "1": "Talk",
- "2": "User",
- "3": "User talk",
- "4": "Wikipedia",
- "5": "Wikipedia talk",
- "6": "File",
- "7": "File talk",
- "8": "MediaWiki",
- "9": "MediaWiki talk",
- "10": "Template",
- "11": "Template talk",
- "12": "Help",
- "13": "Help talk",
- "14": "Category",
- "15": "Category talk",
+ wgFormattedNamespaces: {
+ '-2': 'Media',
+ '-1': 'Special',
+ 0: '',
+ 1: 'Talk',
+ 2: 'User',
+ 3: 'User talk',
+ 4: 'Wikipedia',
+ 5: 'Wikipedia talk',
+ 6: 'File',
+ 7: 'File talk',
+ 8: 'MediaWiki',
+ 9: 'MediaWiki talk',
+ 10: 'Template',
+ 11: 'Template talk',
+ 12: 'Help',
+ 13: 'Help talk',
+ 14: 'Category',
+ 15: 'Category talk',
// testing custom / localized namespace
- "100": "Penguins"
+ 100: 'Penguins'
},
- "wgNamespaceIds": {
- "media": -2,
- "special": -1,
- "": 0,
- "talk": 1,
- "user": 2,
- "user_talk": 3,
- "wikipedia": 4,
- "wikipedia_talk": 5,
- "file": 6,
- "file_talk": 7,
- "mediawiki": 8,
- "mediawiki_talk": 9,
- "template": 10,
- "template_talk": 11,
- "help": 12,
- "help_talk": 13,
- "category": 14,
- "category_talk": 15,
- "image": 6,
- "image_talk": 7,
- "project": 4,
- "project_talk": 5,
+ wgNamespaceIds: {
+ /*jshint camelcase: false */
+ media: -2,
+ special: -1,
+ '': 0,
+ talk: 1,
+ user: 2,
+ user_talk: 3,
+ wikipedia: 4,
+ wikipedia_talk: 5,
+ file: 6,
+ file_talk: 7,
+ mediawiki: 8,
+ mediawiki_talk: 9,
+ template: 10,
+ template_talk: 11,
+ help: 12,
+ help_talk: 13,
+ category: 14,
+ category_talk: 15,
+ image: 6,
+ image_talk: 7,
+ project: 4,
+ project_talk: 5,
/* testing custom / alias */
- "penguins": 100,
- "antarctic_waterfowl": 100
+ penguins: 100,
+ antarctic_waterfowl: 100
},
- "wgCaseSensitiveNamespaces": []
+ wgCaseSensitiveNamespaces: []
};
QUnit.module( 'mediawiki.Title', QUnit.newMwEnvironment({ config: config }) );
title = new mw.Title( ' MediaWiki: Foo bar .js ' );
// Don't ask why, it's the way the backend works. One space is kept of each set
- assert.equal( title.getName(), 'Foo_bar_.js', "Merge multiple spaces to a single space." );
+ assert.equal( title.getName(), 'Foo_bar_.js', 'Merge multiple spaces to a single space.' );
});
QUnit.test( 'Main text for filename', 8, function ( assert ) {
QUnit.test( 'Throw error on invalid title', 1, function ( assert ) {
assert.throws(function () {
- var title = new mw.Title( '' );
+ return new mw.Title( '' );
}, 'Throw error on empty string' );
});
assert.equal( title.getUrl(), '/wiki/User_talk:John_Doe', 'Escaping in title and namespace for urls' );
});
-}() );
\ No newline at end of file
+}( mediaWiki ) );
\ No newline at end of file
-QUnit.module( 'mediawiki.Uri', QUnit.newMwEnvironment({
- setup: function () {
- this.mwUriOrg = mw.Uri;
- mw.Uri = mw.UriRelative( 'http://example.org/w/index.php' );
- },
- teardown: function () {
- mw.Uri = this.mwUriOrg;
- delete this.mwUriOrg;
- }
-}) );
-
-$.each( [true, false], function ( i, strictMode ) {
- QUnit.test( 'Basic mw.Uri object test in ' + ( strictMode ? '' : 'non-' ) + 'strict mode for a simple HTTP URI', 2, function ( assert ) {
- var uriString, uri;
- uriString = 'http://www.ietf.org/rfc/rfc2396.txt';
- uri = new mw.Uri( uriString, {
- strictMode: strictMode
+( function ( mw, $ ) {
+ QUnit.module( 'mediawiki.Uri', QUnit.newMwEnvironment({
+ setup: function () {
+ this.mwUriOrg = mw.Uri;
+ mw.Uri = mw.UriRelative( 'http://example.org/w/index.php' );
+ },
+ teardown: function () {
+ mw.Uri = this.mwUriOrg;
+ delete this.mwUriOrg;
+ }
+ }) );
+
+ $.each( [true, false], function ( i, strictMode ) {
+ QUnit.test( 'Basic mw.Uri object test in ' + ( strictMode ? '' : 'non-' ) + 'strict mode for a simple HTTP URI', 2, function ( assert ) {
+ var uriString, uri;
+ uriString = 'http://www.ietf.org/rfc/rfc2396.txt';
+ uri = new mw.Uri( uriString, {
+ strictMode: strictMode
+ });
+
+ assert.deepEqual(
+ {
+ protocol: uri.protocol,
+ host: uri.host,
+ port: uri.port,
+ path: uri.path,
+ query: uri.query,
+ fragment: uri.fragment
+ }, {
+ protocol: 'http',
+ host: 'www.ietf.org',
+ port: undefined,
+ path: '/rfc/rfc2396.txt',
+ query: {},
+ fragment: undefined
+ },
+ 'basic object properties'
+ );
+
+ assert.deepEqual(
+ {
+ userInfo: uri.getUserInfo(),
+ authority: uri.getAuthority(),
+ hostPort: uri.getHostPort(),
+ queryString: uri.getQueryString(),
+ relativePath: uri.getRelativePath(),
+ toString: uri.toString()
+ },
+ {
+ userInfo: '',
+ authority: 'www.ietf.org',
+ hostPort: 'www.ietf.org',
+ queryString: '',
+ relativePath: '/rfc/rfc2396.txt',
+ toString: uriString
+ },
+ 'construct composite components of URI on request'
+ );
+
});
+ });
+
+ QUnit.test( 'Parse an ftp URI correctly with user and password', 1, function ( assert ) {
+ var uri = new mw.Uri( 'ftp://usr:pwd@192.0.2.16/' );
assert.deepEqual(
{
protocol: uri.protocol,
+ user: uri.user,
+ password: uri.password,
host: uri.host,
port: uri.port,
path: uri.path,
query: uri.query,
fragment: uri.fragment
- }, {
- protocol: 'http',
- host: 'www.ietf.org',
+ },
+ {
+ protocol: 'ftp',
+ user: 'usr',
+ password: 'pwd',
+ host: '192.0.2.16',
port: undefined,
- path: '/rfc/rfc2396.txt',
+ path: '/',
query: {},
fragment: undefined
},
'basic object properties'
);
+ } );
+
+ QUnit.test( 'Parse a uri with simple querystring', 1, function ( assert ) {
+ var uri = new mw.Uri( 'http://www.google.com/?q=uri' );
assert.deepEqual(
{
- userInfo: uri.getUserInfo(),
- authority: uri.getAuthority(),
- hostPort: uri.getHostPort(),
- queryString: uri.getQueryString(),
- relativePath: uri.getRelativePath(),
- toString: uri.toString()
+ protocol: uri.protocol,
+ host: uri.host,
+ port: uri.port,
+ path: uri.path,
+ query: uri.query,
+ fragment: uri.fragment,
+ queryString: uri.getQueryString()
},
{
- userInfo: '',
- authority: 'www.ietf.org',
- hostPort: 'www.ietf.org',
- queryString: '',
- relativePath: '/rfc/rfc2396.txt',
- toString: uriString
+ protocol: 'http',
+ host: 'www.google.com',
+ port: undefined,
+ path: '/',
+ query: { q: 'uri' },
+ fragment: undefined,
+ queryString: 'q=uri'
},
- 'construct composite components of URI on request'
+ 'basic object properties'
);
+ } );
- });
-});
-
-QUnit.test( 'Parse an ftp URI correctly with user and password', 1, function ( assert ) {
- var uri = new mw.Uri( 'ftp://usr:pwd@192.0.2.16/' );
-
- assert.deepEqual(
- {
- protocol: uri.protocol,
- user: uri.user,
- password: uri.password,
- host: uri.host,
- port: uri.port,
- path: uri.path,
- query: uri.query,
- fragment: uri.fragment
- },
- {
- protocol: 'ftp',
- user: 'usr',
- password: 'pwd',
- host: '192.0.2.16',
- port: undefined,
- path: '/',
- query: {},
- fragment: undefined
- },
- 'basic object properties'
- );
-} );
-
-QUnit.test( 'Parse a uri with simple querystring', 1, function ( assert ) {
- var uri = new mw.Uri( 'http://www.google.com/?q=uri' );
-
- assert.deepEqual(
- {
- protocol: uri.protocol,
- host: uri.host,
- port: uri.port,
- path: uri.path,
- query: uri.query,
- fragment: uri.fragment,
- queryString: uri.getQueryString()
- },
- {
- protocol: 'http',
- host: 'www.google.com',
- port: undefined,
- path: '/',
- query: { q: 'uri' },
- fragment: undefined,
- queryString: 'q=uri'
- },
- 'basic object properties'
- );
-} );
+ QUnit.test( 'Handle multiple query parameter (overrideKeys on)', 5, function ( assert ) {
+ var uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
+ overrideKeys: true
+ });
-QUnit.test( 'Handle multiple query parameter (overrideKeys on)', 5, function ( assert ) {
- var uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
- overrideKeys: true
- });
+ assert.equal( uri.query.n, '1', 'multiple parameters are parsed' );
+ assert.equal( uri.query.m, 'bar', 'last key overrides earlier keys' );
- assert.equal( uri.query.n, '1', 'multiple parameters are parsed' );
- assert.equal( uri.query.m, 'bar', 'last key overrides earlier keys' );
+ uri.query.n = [ 'x', 'y', 'z' ];
- uri.query.n = [ 'x', 'y', 'z' ];
+ // Verify parts and total length instead of entire string because order
+ // of iteration can vary.
+ assert.ok( uri.toString().indexOf( 'm=bar' ), 'toString preserves other values' );
+ assert.ok( uri.toString().indexOf( 'n=x&n=y&n=z' ), 'toString parameter includes all values of an array query parameter' );
+ assert.equal( uri.toString().length, 'http://www.example.com/dir/?m=bar&n=x&n=y&n=z'.length, 'toString matches expected string' );
+ } );
- // Verify parts and total length instead of entire string because order
- // of iteration can vary.
- assert.ok( uri.toString().indexOf( 'm=bar' ), 'toString preserves other values' );
- assert.ok( uri.toString().indexOf( 'n=x&n=y&n=z' ), 'toString parameter includes all values of an array query parameter' );
- assert.equal( uri.toString().length, 'http://www.example.com/dir/?m=bar&n=x&n=y&n=z'.length, 'toString matches expected string' );
-} );
+ QUnit.test( 'Handle multiple query parameter (overrideKeys off)', 9, function ( assert ) {
+ var uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
+ overrideKeys: false
+ });
-QUnit.test( 'Handle multiple query parameter (overrideKeys off)', 9, function ( assert ) {
- var uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
- overrideKeys: false
- });
+ // Strict comparison so that types are also verified (n should be string '1')
+ assert.strictEqual( uri.query.m.length, 2, 'multi-value query should be an array with 2 items' );
+ assert.strictEqual( uri.query.m[0], 'foo', 'order and value is correct' );
+ assert.strictEqual( uri.query.m[1], 'bar', 'order and value is correct' );
+ assert.strictEqual( uri.query.n, '1', 'n=1 is parsed with the correct value of the expected type' );
- // Strict comparison so that types are also verified (n should be string '1')
- assert.strictEqual( uri.query.m.length, 2, 'multi-value query should be an array with 2 items' );
- assert.strictEqual( uri.query.m[0], 'foo', 'order and value is correct' );
- assert.strictEqual( uri.query.m[1], 'bar', 'order and value is correct' );
- assert.strictEqual( uri.query.n, '1', 'n=1 is parsed with the correct value of the expected type' );
-
- // Change query values
- uri.query.n = [ 'x', 'y', 'z' ];
-
- // Verify parts and total length instead of entire string because order
- // of iteration can vary.
- assert.ok( uri.toString().indexOf( 'm=foo&m=bar' ) >= 0, 'toString preserves other values' );
- assert.ok( uri.toString().indexOf( 'n=x&n=y&n=z' ) >= 0, 'toString parameter includes all values of an array query parameter' );
- assert.equal( uri.toString().length, 'http://www.example.com/dir/?m=foo&m=bar&n=x&n=y&n=z'.length, 'toString matches expected string' );
-
- // Remove query values
- uri.query.m.splice( 0, 1 );
- delete uri.query.n;
-
- assert.equal( uri.toString(), 'http://www.example.com/dir/?m=bar', 'deletion properties' );
-
- // Remove more query values, leaving an empty array
- uri.query.m.splice( 0, 1 );
- assert.equal( uri.toString(), 'http://www.example.com/dir/', 'empty array value is ommitted' );
-} );
-
-QUnit.test( 'All-dressed URI with everything', 11, function ( assert ) {
- var uri, queryString, relativePath;
-
- uri = new mw.Uri( 'http://auth@www.example.com:81/dir/dir.2/index.htm?q1=0&&test1&test2=value+%28escaped%29#top' );
-
- assert.deepEqual(
- {
- protocol: uri.protocol,
- user: uri.user,
- password: uri.password,
- host: uri.host,
- port: uri.port,
- path: uri.path,
- query: uri.query,
- fragment: uri.fragment
- },
- {
- protocol: 'http',
- user: 'auth',
- password: undefined,
- host: 'www.example.com',
- port: '81',
- path: '/dir/dir.2/index.htm',
- query: { q1: '0', test1: null, test2: 'value (escaped)' },
- fragment: 'top'
- },
- 'basic object properties'
- );
+ // Change query values
+ uri.query.n = [ 'x', 'y', 'z' ];
- assert.equal( uri.getUserInfo(), 'auth', 'user info' );
+ // Verify parts and total length instead of entire string because order
+ // of iteration can vary.
+ assert.ok( uri.toString().indexOf( 'm=foo&m=bar' ) >= 0, 'toString preserves other values' );
+ assert.ok( uri.toString().indexOf( 'n=x&n=y&n=z' ) >= 0, 'toString parameter includes all values of an array query parameter' );
+ assert.equal( uri.toString().length, 'http://www.example.com/dir/?m=foo&m=bar&n=x&n=y&n=z'.length, 'toString matches expected string' );
- assert.equal( uri.getAuthority(), 'auth@www.example.com:81', 'authority equal to auth@hostport' );
+ // Remove query values
+ uri.query.m.splice( 0, 1 );
+ delete uri.query.n;
- assert.equal( uri.getHostPort(), 'www.example.com:81', 'hostport equal to host:port' );
+ assert.equal( uri.toString(), 'http://www.example.com/dir/?m=bar', 'deletion properties' );
- queryString = uri.getQueryString();
- assert.ok( queryString.indexOf( 'q1=0' ) >= 0, 'query param with numbers' );
- assert.ok( queryString.indexOf( 'test1' ) >= 0, 'query param with null value is included' );
- assert.ok( queryString.indexOf( 'test1=' ) === -1, 'query param with null value does not generate equals sign' );
- assert.ok( queryString.indexOf( 'test2=value+%28escaped%29' ) >= 0, 'query param is url escaped' );
+ // Remove more query values, leaving an empty array
+ uri.query.m.splice( 0, 1 );
+ assert.equal( uri.toString(), 'http://www.example.com/dir/', 'empty array value is ommitted' );
+ } );
- relativePath = uri.getRelativePath();
- assert.ok( relativePath.indexOf( uri.path ) >= 0, 'path in relative path' );
- assert.ok( relativePath.indexOf( uri.getQueryString() ) >= 0, 'query string in relative path' );
- assert.ok( relativePath.indexOf( uri.fragment ) >= 0, 'fragement in relative path' );
-} );
+ QUnit.test( 'All-dressed URI with everything', 11, function ( assert ) {
+ var uri, queryString, relativePath;
-QUnit.test( 'Cloning', 6, function ( assert ) {
- var original, clone;
+ uri = new mw.Uri( 'http://auth@www.example.com:81/dir/dir.2/index.htm?q1=0&&test1&test2=value+%28escaped%29#top' );
- original = new mw.Uri( 'http://foo.example.org/index.php?one=1&two=2' );
- clone = original.clone();
+ assert.deepEqual(
+ {
+ protocol: uri.protocol,
+ user: uri.user,
+ password: uri.password,
+ host: uri.host,
+ port: uri.port,
+ path: uri.path,
+ query: uri.query,
+ fragment: uri.fragment
+ },
+ {
+ protocol: 'http',
+ user: 'auth',
+ password: undefined,
+ host: 'www.example.com',
+ port: '81',
+ path: '/dir/dir.2/index.htm',
+ query: { q1: '0', test1: null, test2: 'value (escaped)' },
+ fragment: 'top'
+ },
+ 'basic object properties'
+ );
- assert.deepEqual( clone, original, 'clone has equivalent properties' );
- assert.equal( original.toString(), clone.toString(), 'toString matches original' );
+ assert.equal( uri.getUserInfo(), 'auth', 'user info' );
- assert.notStrictEqual( clone, original, 'clone is a different object when compared by reference' );
+ assert.equal( uri.getAuthority(), 'auth@www.example.com:81', 'authority equal to auth@hostport' );
- clone.host = 'bar.example.org';
- assert.notEqual( original.host, clone.host, 'manipulating clone did not effect original' );
- assert.notEqual( original.toString(), clone.toString(), 'Stringified url no longer matches original' );
+ assert.equal( uri.getHostPort(), 'www.example.com:81', 'hostport equal to host:port' );
- clone.query.three = 3;
+ queryString = uri.getQueryString();
+ assert.ok( queryString.indexOf( 'q1=0' ) >= 0, 'query param with numbers' );
+ assert.ok( queryString.indexOf( 'test1' ) >= 0, 'query param with null value is included' );
+ assert.ok( queryString.indexOf( 'test1=' ) === -1, 'query param with null value does not generate equals sign' );
+ assert.ok( queryString.indexOf( 'test2=value+%28escaped%29' ) >= 0, 'query param is url escaped' );
- assert.deepEqual(
- original.query,
- { 'one': '1', 'two': '2' },
- 'Properties is deep cloned (bug 37708)'
- );
-} );
+ relativePath = uri.getRelativePath();
+ assert.ok( relativePath.indexOf( uri.path ) >= 0, 'path in relative path' );
+ assert.ok( relativePath.indexOf( uri.getQueryString() ) >= 0, 'query string in relative path' );
+ assert.ok( relativePath.indexOf( uri.fragment ) >= 0, 'fragement in relative path' );
+ } );
-QUnit.test( 'Constructing mw.Uri from plain object', 3, function ( assert ) {
- var uri = new mw.Uri({
- protocol: 'http',
- host: 'www.foo.local',
- path: '/this'
- });
- assert.equal( uri.toString(), 'http://www.foo.local/this', 'Basic properties' );
-
- uri = new mw.Uri({
- protocol: 'http',
- host: 'www.foo.local',
- path: '/this',
- query: { hi: 'there' },
- fragment: 'blah'
- });
- assert.equal( uri.toString(), 'http://www.foo.local/this?hi=there#blah', 'More complex properties' );
+ QUnit.test( 'Cloning', 6, function ( assert ) {
+ var original, clone;
- assert.throws(
- function () {
- var uri = new mw.Uri({
- protocol: 'http',
- host: 'www.foo.local'
- });
- },
- function ( e ) {
- return e.message === 'Bad constructor arguments';
- },
- 'Construction failed when missing required properties'
- );
-} );
+ original = new mw.Uri( 'http://foo.example.org/index.php?one=1&two=2' );
+ clone = original.clone();
-QUnit.test( 'Manipulate properties', 8, function ( assert ) {
- var uriBase, uri;
+ assert.deepEqual( clone, original, 'clone has equivalent properties' );
+ assert.equal( original.toString(), clone.toString(), 'toString matches original' );
- uriBase = new mw.Uri( 'http://en.wiki.local/w/api.php' );
+ assert.notStrictEqual( clone, original, 'clone is a different object when compared by reference' );
- uri = uriBase.clone();
- uri.fragment = 'frag';
- assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php#frag', 'add a fragment' );
+ clone.host = 'bar.example.org';
+ assert.notEqual( original.host, clone.host, 'manipulating clone did not effect original' );
+ assert.notEqual( original.toString(), clone.toString(), 'Stringified url no longer matches original' );
- uri = uriBase.clone();
- uri.host = 'fr.wiki.local';
- uri.port = '8080';
- assert.equal( uri.toString(), 'http://fr.wiki.local:8080/w/api.php', 'change host and port' );
+ clone.query.three = 3;
- uri = uriBase.clone();
- uri.query.foo = 'bar';
- assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php?foo=bar', 'add query arguments' );
+ assert.deepEqual(
+ original.query,
+ { 'one': '1', 'two': '2' },
+ 'Properties is deep cloned (bug 37708)'
+ );
+ } );
- delete uri.query.foo;
- assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php', 'delete query arguments' );
+ QUnit.test( 'Constructing mw.Uri from plain object', 3, function ( assert ) {
+ var uri = new mw.Uri({
+ protocol: 'http',
+ host: 'www.foo.local',
+ path: '/this'
+ });
+ assert.equal( uri.toString(), 'http://www.foo.local/this', 'Basic properties' );
- uri = uriBase.clone();
- uri.query.foo = 'bar';
- assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php?foo=bar', 'extend query arguments' );
- uri.extend({
- foo: 'quux',
- pif: 'paf'
- });
- assert.ok( uri.toString().indexOf( 'foo=quux' ) >= 0, 'extend query arguments' );
- assert.ok( uri.toString().indexOf( 'foo=bar' ) === -1, 'extend query arguments' );
- assert.ok( uri.toString().indexOf( 'pif=paf' ) >= 0 , 'extend query arguments' );
-} );
+ uri = new mw.Uri({
+ protocol: 'http',
+ host: 'www.foo.local',
+ path: '/this',
+ query: { hi: 'there' },
+ fragment: 'blah'
+ });
+ assert.equal( uri.toString(), 'http://www.foo.local/this?hi=there#blah', 'More complex properties' );
+
+ assert.throws(
+ function () {
+ return new mw.Uri({
+ protocol: 'http',
+ host: 'www.foo.local'
+ });
+ },
+ function ( e ) {
+ return e.message === 'Bad constructor arguments';
+ },
+ 'Construction failed when missing required properties'
+ );
+ } );
-QUnit.test( 'Handle protocol-relative URLs', 5, function ( assert ) {
- var UriRel, uri;
+ QUnit.test( 'Manipulate properties', 8, function ( assert ) {
+ var uriBase, uri;
- UriRel = mw.UriRelative( 'glork://en.wiki.local/foo.php' );
+ uriBase = new mw.Uri( 'http://en.wiki.local/w/api.php' );
- uri = new UriRel( '//en.wiki.local/w/api.php' );
- assert.equal( uri.protocol, 'glork', 'create protocol-relative URLs with same protocol as document' );
+ uri = uriBase.clone();
+ uri.fragment = 'frag';
+ assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php#frag', 'add a fragment' );
- uri = new UriRel( '/foo.com' );
- assert.equal( uri.toString(), 'glork://en.wiki.local/foo.com', 'handle absolute paths by supplying protocol and host from document in loose mode' );
+ uri = uriBase.clone();
+ uri.host = 'fr.wiki.local';
+ uri.port = '8080';
+ assert.equal( uri.toString(), 'http://fr.wiki.local:8080/w/api.php', 'change host and port' );
- uri = new UriRel( 'http:/foo.com' );
- assert.equal( uri.toString(), 'http://en.wiki.local/foo.com', 'handle absolute paths by supplying host from document in loose mode' );
+ uri = uriBase.clone();
+ uri.query.foo = 'bar';
+ assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php?foo=bar', 'add query arguments' );
- uri = new UriRel( '/foo.com', true );
- assert.equal( uri.toString(), 'glork://en.wiki.local/foo.com', 'handle absolute paths by supplying protocol and host from document in strict mode' );
+ delete uri.query.foo;
+ assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php', 'delete query arguments' );
- uri = new UriRel( 'http:/foo.com', true );
- assert.equal( uri.toString(), 'http://en.wiki.local/foo.com', 'handle absolute paths by supplying host from document in strict mode' );
-} );
+ uri = uriBase.clone();
+ uri.query.foo = 'bar';
+ assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php?foo=bar', 'extend query arguments' );
+ uri.extend({
+ foo: 'quux',
+ pif: 'paf'
+ });
+ assert.ok( uri.toString().indexOf( 'foo=quux' ) >= 0, 'extend query arguments' );
+ assert.ok( uri.toString().indexOf( 'foo=bar' ) === -1, 'extend query arguments' );
+ assert.ok( uri.toString().indexOf( 'pif=paf' ) >= 0 , 'extend query arguments' );
+ } );
-QUnit.test( 'Bad calls', 3, function ( assert ) {
- var uri;
+ QUnit.test( 'Handle protocol-relative URLs', 5, function ( assert ) {
+ var UriRel, uri;
- assert.throws(
- function () {
- new mw.Uri( 'glaswegian penguins' );
- },
- function ( e ) {
- return e.message === 'Bad constructor arguments';
- },
- 'throw error on non-URI as argument to constructor'
- );
+ UriRel = mw.UriRelative( 'glork://en.wiki.local/foo.php' );
- assert.throws(
- function () {
- new mw.Uri( 'foo.com/bar/baz', {
- strictMode: true
- });
- },
- function ( e ) {
- return e.message === 'Bad constructor arguments';
- },
- 'throw error on URI without protocol or // or leading / in strict mode'
- );
+ uri = new UriRel( '//en.wiki.local/w/api.php' );
+ assert.equal( uri.protocol, 'glork', 'create protocol-relative URLs with same protocol as document' );
+
+ uri = new UriRel( '/foo.com' );
+ assert.equal( uri.toString(), 'glork://en.wiki.local/foo.com', 'handle absolute paths by supplying protocol and host from document in loose mode' );
+
+ uri = new UriRel( 'http:/foo.com' );
+ assert.equal( uri.toString(), 'http://en.wiki.local/foo.com', 'handle absolute paths by supplying host from document in loose mode' );
+
+ uri = new UriRel( '/foo.com', true );
+ assert.equal( uri.toString(), 'glork://en.wiki.local/foo.com', 'handle absolute paths by supplying protocol and host from document in strict mode' );
+
+ uri = new UriRel( 'http:/foo.com', true );
+ assert.equal( uri.toString(), 'http://en.wiki.local/foo.com', 'handle absolute paths by supplying host from document in strict mode' );
+ } );
- uri = new mw.Uri( 'foo.com/bar/baz', {
- strictMode: false
+ QUnit.test( 'Bad calls', 3, function ( assert ) {
+ var uri;
+
+ assert.throws(
+ function () {
+ return new mw.Uri( 'glaswegian penguins' );
+ },
+ function ( e ) {
+ return e.message === 'Bad constructor arguments';
+ },
+ 'throw error on non-URI as argument to constructor'
+ );
+
+ assert.throws(
+ function () {
+ return new mw.Uri( 'foo.com/bar/baz', {
+ strictMode: true
+ });
+ },
+ function ( e ) {
+ return e.message === 'Bad constructor arguments';
+ },
+ 'throw error on URI without protocol or // or leading / in strict mode'
+ );
+
+ uri = new mw.Uri( 'foo.com/bar/baz', {
+ strictMode: false
+ });
+ assert.equal( uri.toString(), 'http://foo.com/bar/baz', 'normalize URI without protocol or // in loose mode' );
});
- assert.equal( uri.toString(), 'http://foo.com/bar/baz', 'normalize URI without protocol or // in loose mode' );
-});
-QUnit.test( 'bug 35658', 2, function ( assert ) {
- var testProtocol, testServer, testPort, testPath, UriClass, uri, href;
+ QUnit.test( 'bug 35658', 2, function ( assert ) {
+ var testProtocol, testServer, testPort, testPath, UriClass, uri, href;
- testProtocol = 'https://';
- testServer = 'foo.example.org';
- testPort = '3004';
- testPath = '/!1qy';
+ testProtocol = 'https://';
+ testServer = 'foo.example.org';
+ testPort = '3004';
+ testPath = '/!1qy';
- UriClass = mw.UriRelative( testProtocol + testServer + '/some/path/index.html' );
- uri = new UriClass( testPath );
- href = uri.toString();
- assert.equal( href, testProtocol + testServer + testPath, 'Root-relative URL gets host & protocol supplied' );
+ UriClass = mw.UriRelative( testProtocol + testServer + '/some/path/index.html' );
+ uri = new UriClass( testPath );
+ href = uri.toString();
+ assert.equal( href, testProtocol + testServer + testPath, 'Root-relative URL gets host & protocol supplied' );
- UriClass = mw.UriRelative( testProtocol + testServer + ':' + testPort + '/some/path.php' );
- uri = new UriClass( testPath );
- href = uri.toString();
- assert.equal( href, testProtocol + testServer + ':' + testPort + testPath, 'Root-relative URL gets host, protocol, and port supplied' );
+ UriClass = mw.UriRelative( testProtocol + testServer + ':' + testPort + '/some/path.php' );
+ uri = new UriClass( testPath );
+ href = uri.toString();
+ assert.equal( href, testProtocol + testServer + ':' + testPort + testPath, 'Root-relative URL gets host, protocol, and port supplied' );
-} );
+ } );
-QUnit.test( 'Constructor falls back to default location', 4, function ( assert ) {
- var testuri, MyUri, uri;
+ QUnit.test( 'Constructor falls back to default location', 4, function ( assert ) {
+ var testuri, MyUri, uri;
- testuri = 'http://example.org/w/index.php';
- MyUri = mw.UriRelative( testuri );
+ testuri = 'http://example.org/w/index.php';
+ MyUri = mw.UriRelative( testuri );
- uri = new MyUri();
- assert.equal( uri.toString(), testuri, 'no arguments' );
+ uri = new MyUri();
+ assert.equal( uri.toString(), testuri, 'no arguments' );
- uri = new MyUri( undefined );
- assert.equal( uri.toString(), testuri, 'undefined' );
+ uri = new MyUri( undefined );
+ assert.equal( uri.toString(), testuri, 'undefined' );
- uri = new MyUri( null );
- assert.equal( uri.toString(), testuri, 'null' );
+ uri = new MyUri( null );
+ assert.equal( uri.toString(), testuri, 'null' );
- uri = new MyUri( '' );
- assert.equal( uri.toString(), testuri, 'empty string' );
-} );
+ uri = new MyUri( '' );
+ assert.equal( uri.toString(), testuri, 'empty string' );
+ } );
+}( mediaWiki, jQuery ) );
-QUnit.module( 'mediawiki.cldr', QUnit.newMwEnvironment() );
+( function ( mw, $ ) {
+ QUnit.module( 'mediawiki.cldr', QUnit.newMwEnvironment() );
-var pluralTestcases = {
- /*
- * Sample:
- * "languagecode" : [
- * [ number, [ "form1", "form2", ... ], "expected", "description" ]
- * ];
- */
- "en": [
- [ 0, [ "one", "other" ], "other", "English plural test- 0 is other" ],
- [ 1, [ "one", "other" ], "one", "English plural test- 1 is one" ]
- ],
- "fa": [
- [ 0, [ "one", "other" ], "other", "Persian plural test- 0 is other" ],
- [ 1, [ "one", "other" ], "one", "Persian plural test- 1 is one" ],
- [ 2, [ "one", "other" ], "other", "Persian plural test- 2 is other" ]
- ],
- "fr": [
- [ 0, [ "one", "other" ], "other", "French plural test- 0 is other" ],
- [ 1, [ "one", "other" ], "one", "French plural test- 1 is one" ]
- ],
- "hi": [
- [ 0, [ "one", "other" ], "one", "Hindi plural test- 0 is one" ],
- [ 1, [ "one", "other" ], "one", "Hindi plural test- 1 is one" ],
- [ 2, [ "one", "other" ], "other", "Hindi plural test- 2 is other" ]
- ],
- "he": [
- [ 0, [ "one", "other" ], "other", "Hebrew plural test- 0 is other" ],
- [ 1, [ "one", "other" ], "one", "Hebrew plural test- 1 is one" ],
- [ 2, [ "one", "other" ], "other", "Hebrew plural test- 2 is other with 2 forms" ],
- [ 2, [ "one", "dual", "other" ], "dual", "Hebrew plural test- 2 is dual with 3 forms" ]
- ],
- "hu": [
- [ 0, [ "one", "other" ], "other", "Hungarian plural test- 0 is other" ],
- [ 1, [ "one", "other" ], "one", "Hungarian plural test- 1 is one" ],
- [ 2, [ "one", "other" ], "other", "Hungarian plural test- 2 is other" ]
- ],
- "ar": [
- [ 0, [ "zero", "one", "two", "few", "many", "other" ], "zero", "Arabic plural test - 0 is zero" ],
- [ 1, [ "zero", "one", "two", "few", "many", "other" ], "one", "Arabic plural test - 1 is one" ],
- [ 2, [ "zero", "one", "two", "few", "many", "other" ], "two", "Arabic plural test - 2 is two" ],
- [ 3, [ "zero", "one", "two", "few", "many", "other" ], "few", "Arabic plural test - 3 is few" ],
- [ 9, [ "zero", "one", "two", "few", "many", "other" ], "few", "Arabic plural test - 9 is few" ],
- [ "9", [ "zero", "one", "two", "few", "many", "other" ], "few", "Arabic plural test - 9 is few" ],
- [ 110, [ "zero", "one", "two", "few", "many", "other" ], "few", "Arabic plural test - 110 is few" ],
- [ 11, [ "zero", "one", "two", "few", "many", "other" ], "many", "Arabic plural test - 11 is many" ],
- [ 15, [ "zero", "one", "two", "few", "many", "other" ], "many", "Arabic plural test - 15 is many" ],
- [ 99, [ "zero", "one", "two", "few", "many", "other" ], "many", "Arabic plural test - 99 is many" ],
- [ 9999, [ "zero", "one", "two", "few", "many", "other" ], "many", "Arabic plural test - 9999 is many" ],
- [ 100, [ "zero", "one", "two", "few", "many", "other" ], "other", "Arabic plural test - 100 is other" ],
- [ 102, [ "zero", "one", "two", "few", "many", "other" ], "other", "Arabic plural test - 102 is other" ],
- [ 1000, [ "zero", "one", "two", "few", "many", "other" ], "other", "Arabic plural test - 1000 is other" ],
- [ 1.7, [ "zero", "one", "two", "few", "many", "other" ], "other", "Arabic plural test - 1.7 is other" ]
- ]
-};
+ var pluralTestcases = {
+ /*
+ * Sample:
+ * languagecode : [
+ * [ number, [ 'form1', 'form2', ... ], 'expected', 'description' ]
+ * ];
+ */
+ en: [
+ [ 0, [ 'one', 'other' ], 'other', 'English plural test- 0 is other' ],
+ [ 1, [ 'one', 'other' ], 'one', 'English plural test- 1 is one' ]
+ ],
+ fa: [
+ [ 0, [ 'one', 'other' ], 'other', 'Persian plural test- 0 is other' ],
+ [ 1, [ 'one', 'other' ], 'one', 'Persian plural test- 1 is one' ],
+ [ 2, [ 'one', 'other' ], 'other', 'Persian plural test- 2 is other' ]
+ ],
+ fr: [
+ [ 0, [ 'one', 'other' ], 'other', 'French plural test- 0 is other' ],
+ [ 1, [ 'one', 'other' ], 'one', 'French plural test- 1 is one' ]
+ ],
+ hi: [
+ [ 0, [ 'one', 'other' ], 'one', 'Hindi plural test- 0 is one' ],
+ [ 1, [ 'one', 'other' ], 'one', 'Hindi plural test- 1 is one' ],
+ [ 2, [ 'one', 'other' ], 'other', 'Hindi plural test- 2 is other' ]
+ ],
+ he: [
+ [ 0, [ 'one', 'other' ], 'other', 'Hebrew plural test- 0 is other' ],
+ [ 1, [ 'one', 'other' ], 'one', 'Hebrew plural test- 1 is one' ],
+ [ 2, [ 'one', 'other' ], 'other', 'Hebrew plural test- 2 is other with 2 forms' ],
+ [ 2, [ 'one', 'dual', 'other' ], 'dual', 'Hebrew plural test- 2 is dual with 3 forms' ]
+ ],
+ hu: [
+ [ 0, [ 'one', 'other' ], 'other', 'Hungarian plural test- 0 is other' ],
+ [ 1, [ 'one', 'other' ], 'one', 'Hungarian plural test- 1 is one' ],
+ [ 2, [ 'one', 'other' ], 'other', 'Hungarian plural test- 2 is other' ]
+ ],
+ ar: [
+ [ 0, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'zero', 'Arabic plural test - 0 is zero' ],
+ [ 1, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'one', 'Arabic plural test - 1 is one' ],
+ [ 2, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'two', 'Arabic plural test - 2 is two' ],
+ [ 3, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'few', 'Arabic plural test - 3 is few' ],
+ [ 9, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'few', 'Arabic plural test - 9 is few' ],
+ [ '9', [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'few', 'Arabic plural test - 9 is few' ],
+ [ 110, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'few', 'Arabic plural test - 110 is few' ],
+ [ 11, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'many', 'Arabic plural test - 11 is many' ],
+ [ 15, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'many', 'Arabic plural test - 15 is many' ],
+ [ 99, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'many', 'Arabic plural test - 99 is many' ],
+ [ 9999, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'many', 'Arabic plural test - 9999 is many' ],
+ [ 100, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'other', 'Arabic plural test - 100 is other' ],
+ [ 102, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'other', 'Arabic plural test - 102 is other' ],
+ [ 1000, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'other', 'Arabic plural test - 1000 is other' ],
+ [ 1.7, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'other', 'Arabic plural test - 1.7 is other' ]
+ ]
+ };
-function pluralTest( langCode, tests ) {
- QUnit.test( 'Plural Test for ' + langCode, tests.length, function ( assert ) {
- for ( var i = 0; i < tests.length; i++ ) {
- assert.equal(
- mw.language.convertPlural( tests[i][0], tests[i][1] ),
- tests[i][2],
- tests[i][3]
- );
+ function pluralTest( langCode, tests ) {
+ QUnit.test( 'Plural Test for ' + langCode, tests.length, function ( assert ) {
+ for ( var i = 0; i < tests.length; i++ ) {
+ assert.equal(
+ mw.language.convertPlural( tests[i][0], tests[i][1] ),
+ tests[i][2],
+ tests[i][3]
+ );
+ }
+ } );
+ }
+
+ $.each( pluralTestcases, function ( langCode, tests ) {
+ if ( langCode === mw.config.get( 'wgUserLanguage' ) ) {
+ pluralTest( langCode, tests );
}
} );
-}
-
-$.each( pluralTestcases, function ( langCode, tests ) {
- if ( langCode === mw.config.get( 'wgUserLanguage' ) ) {
- pluralTest( langCode, tests );
- }
-} );
+}( mediaWiki, jQuery ) );
-/* Some misc JavaScript compatibility tests, just to make sure the environments we run in are consistent */
-
-QUnit.module( 'mediawiki.jscompat', QUnit.newMwEnvironment() );
-
-QUnit.test( 'Variable with Unicode letter in name', 3, function ( assert ) {
- var orig = "some token";
- var ŝablono = orig;
-
- assert.deepEqual( ŝablono, orig, 'ŝablono' );
- assert.deepEqual( \u015dablono, orig, '\\u015dablono' );
- assert.deepEqual( \u015Dablono, orig, '\\u015Dablono' );
-});
-
-/*
-// Not that we need this. ;)
-// This fails on IE 6-8
-// Works on IE 9, Firefox 6, Chrome 14
-QUnit.test( 'Keyword workaround: "if" as variable name using Unicode escapes', function ( assert ) {
- var orig = "another token";
- \u0069\u0066 = orig;
- assert.deepEqual( \u0069\u0066, orig, '\\u0069\\u0066' );
-});
-*/
-
-/*
-// Not that we need this. ;)
-// This fails on IE 6-9
-// Works on Firefox 6, Chrome 14
-QUnit.test( 'Keyword workaround: "if" as member variable name using Unicode escapes', function ( assert ) {
- var orig = "another token";
- var foo = {};
- foo.\u0069\u0066 = orig;
- assert.deepEqual( foo.\u0069\u0066, orig, 'foo.\\u0069\\u0066' );
-});
-*/
-
-QUnit.test( 'Stripping of single initial newline from textarea\'s literal contents (bug 12130)', function ( assert ) {
- var maxn = 4;
- QUnit.expect( maxn * 2 );
-
- function repeat( str, n ) {
- if ( n <= 0 ) {
- return '';
- } else {
- var out = new Array(n);
- for ( var i = 0; i < n; i++ ) {
- out[i] = str;
+/**
+ * Some misc JavaScript compatibility tests,
+ * just to make sure the environments we run in are consistent.
+ */
+( function ( $ ) {
+ QUnit.module( 'mediawiki.jscompat', QUnit.newMwEnvironment() );
+
+ QUnit.test( 'Variable with Unicode letter in name', 3, function ( assert ) {
+ var orig, ŝablono;
+
+ orig = 'some token';
+ ŝablono = orig;
+
+ assert.deepEqual( ŝablono, orig, 'ŝablono' );
+ assert.deepEqual( \u015dablono, orig, '\\u015dablono' );
+ assert.deepEqual( \u015Dablono, orig, '\\u015Dablono' );
+ });
+
+ /*
+ // Not that we need this. ;)
+ // This fails on IE 6-8
+ // Works on IE 9, Firefox 6, Chrome 14
+ QUnit.test( 'Keyword workaround: "if" as variable name using Unicode escapes', function ( assert ) {
+ var orig = "another token";
+ \u0069\u0066 = orig;
+ assert.deepEqual( \u0069\u0066, orig, '\\u0069\\u0066' );
+ });
+ */
+
+ /*
+ // Not that we need this. ;)
+ // This fails on IE 6-9
+ // Works on Firefox 6, Chrome 14
+ QUnit.test( 'Keyword workaround: "if" as member variable name using Unicode escapes', function ( assert ) {
+ var orig = "another token";
+ var foo = {};
+ foo.\u0069\u0066 = orig;
+ assert.deepEqual( foo.\u0069\u0066, orig, 'foo.\\u0069\\u0066' );
+ });
+ */
+
+ QUnit.test( 'Stripping of single initial newline from textarea\'s literal contents (bug 12130)', function ( assert ) {
+ var maxn, n,
+ expected, $textarea;
+
+ maxn = 4;
+ QUnit.expect( maxn * 2 );
+
+ function repeat( str, n ) {
+ var out;
+ if ( n <= 0 ) {
+ return '';
+ } else {
+ out = [];
+ out.length = n + 1;
+ return out.join( str );
}
- return out.join('');
}
- }
- for ( var n = 0; n < maxn; n++ ) {
- var expected = repeat('\n', n) + 'some text';
+ for ( n = 0; n < maxn; n++ ) {
+ expected = repeat('\n', n) + 'some text';
- var $textarea = $('<textarea>\n' + expected + '</textarea>');
- assert.equal( $textarea.val(), expected, 'Expecting ' + n + ' newlines (HTML contained ' + (n + 1) + ')' );
+ $textarea = $('<textarea>\n' + expected + '</textarea>');
+ assert.equal( $textarea.val(), expected, 'Expecting ' + n + ' newlines (HTML contained ' + (n + 1) + ')' );
- var $textarea2 = $('<textarea>').val(expected);
- assert.equal( $textarea2.val(), expected, 'Expecting ' + n + ' newlines (from DOM set with ' + n + ')' );
- }
-});
+ $textarea = $('<textarea>').val( expected );
+ assert.equal( $textarea.val(), expected, 'Expecting ' + n + ' newlines (from DOM set with ' + n + ')' );
+ }
+ });
+}( jQuery ) );
-QUnit.module( 'mediawiki.language', QUnit.newMwEnvironment({
- setup: function () {
- this.liveLangData = mw.language.data.values;
- mw.language.data.values = $.extend( true, {}, this.liveLangData );
- },
- teardown: function () {
- // Restore
- mw.language.data.values = this.liveLangData;
- }
-}) );
+( function ( mw, $ ) {
-QUnit.test( 'mw.language getData and setData', function ( assert ) {
- QUnit.expect( 2 );
+ QUnit.module( 'mediawiki.language', QUnit.newMwEnvironment({
+ setup: function () {
+ this.liveLangData = mw.language.data.values;
+ mw.language.data.values = $.extend( true, {}, this.liveLangData );
+ },
+ teardown: function () {
+ mw.language.data.values = this.liveLangData;
+ }
+ }) );
- mw.language.setData( 'en', 'testkey', 'testvalue' );
- assert.equal( mw.language.getData( 'en', 'testkey' ), 'testvalue', 'Getter setter test for mw.language' );
- assert.equal( mw.language.getData( 'en', 'invalidkey' ), undefined, 'Getter setter test for mw.language with invalid key' );
-} );
+ QUnit.test( 'mw.language getData and setData', 2, function ( assert ) {
+ mw.language.setData( 'en', 'testkey', 'testvalue' );
+ assert.equal( mw.language.getData( 'en', 'testkey' ), 'testvalue', 'Getter setter test for mw.language' );
+ assert.equal( mw.language.getData( 'en', 'invalidkey' ), undefined, 'Getter setter test for mw.language with invalid key' );
+ } );
-function grammarTest( langCode, test ) {
- // 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 ) {
- QUnit.expect( test.length );
+ function grammarTest( langCode, test ) {
+ // 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 ) {
+ QUnit.expect( test.length );
- for ( var i = 0 ; i < test.length; i++ ) {
- assert.equal(
- mw.language.convertGrammar( test[i].word, test[i].grammarForm ),
- test[i].expected,
- test[i].description
- );
- }
- });
-}
+ for ( var i = 0 ; i < test.length; i++ ) {
+ assert.equal(
+ mw.language.convertGrammar( test[i].word, test[i].grammarForm ),
+ test[i].expected,
+ test[i].description
+ );
+ }
+ });
+ }
-var grammarTests = {
- bs: [
- {
- word: 'word',
- grammarForm: 'instrumental',
- expected: 's word',
- description: 'Grammar test for instrumental case'
- },
- {
- word: 'word',
- grammarForm: 'lokativ',
- expected: 'o word',
- description: 'Grammar test for lokativ case'
- }
- ],
+ var grammarTests = {
+ bs: [
+ {
+ word: 'word',
+ grammarForm: 'instrumental',
+ expected: 's word',
+ description: 'Grammar test for instrumental case'
+ },
+ {
+ word: 'word',
+ grammarForm: 'lokativ',
+ expected: 'o word',
+ description: 'Grammar test for lokativ case'
+ }
+ ],
- he: [
- {
- word: "ויקיפדיה",
- grammarForm: 'prefixed',
- expected: "וויקיפדיה",
- description: 'Duplicate the "Waw" if prefixed'
- },
- {
- word: "וולפגנג",
- grammarForm: 'prefixed',
- expected: "וולפגנג",
- description: 'Duplicate the "Waw" if prefixed, but not if it is already duplicated.'
- },
- {
- word: "הקובץ",
- grammarForm: 'prefixed',
- expected: "קובץ",
- description: 'Remove the "He" if prefixed'
- },
- {
- word: 'Wikipedia',
- grammarForm: 'תחילית',
- expected: '־Wikipedia',
- description: 'GAdd a hyphen (maqaf) before non-Hebrew letters'
- },
- {
- word: '1995',
- grammarForm: 'תחילית',
- expected: '־1995',
- description: 'Add a hyphen (maqaf) before numbers'
- }
- ],
+ he: [
+ {
+ word: 'ויקיפדיה',
+ grammarForm: 'prefixed',
+ expected: 'וויקיפדיה',
+ description: 'Duplicate the "Waw" if prefixed'
+ },
+ {
+ word: 'וולפגנג',
+ grammarForm: 'prefixed',
+ expected: 'וולפגנג',
+ description: 'Duplicate the "Waw" if prefixed, but not if it is already duplicated.'
+ },
+ {
+ word: 'הקובץ',
+ grammarForm: 'prefixed',
+ expected: 'קובץ',
+ description: 'Remove the "He" if prefixed'
+ },
+ {
+ word: 'Wikipedia',
+ grammarForm: 'תחילית',
+ expected: '־Wikipedia',
+ description: 'GAdd a hyphen (maqaf) before non-Hebrew letters'
+ },
+ {
+ word: '1995',
+ grammarForm: 'תחילית',
+ expected: '־1995',
+ description: 'Add a hyphen (maqaf) before numbers'
+ }
+ ],
- hsb: [
- {
- word: 'word',
- grammarForm: 'instrumental',
- expected: 'z word',
- description: 'Grammar test for instrumental case'
- },
- {
- word: 'word',
- grammarForm: 'lokatiw',
- expected: 'wo word',
- description: 'Grammar test for lokatiw case'
- }
- ],
+ hsb: [
+ {
+ word: 'word',
+ grammarForm: 'instrumental',
+ expected: 'z word',
+ description: 'Grammar test for instrumental case'
+ },
+ {
+ word: 'word',
+ grammarForm: 'lokatiw',
+ expected: 'wo word',
+ description: 'Grammar test for lokatiw case'
+ }
+ ],
- dsb: [
- {
- word: 'word',
- grammarForm: 'instrumental',
- expected: 'z word',
- description: 'Grammar test for instrumental case'
- },
- {
- word: 'word',
- grammarForm: 'lokatiw',
- expected: 'wo word',
- description: 'Grammar test for lokatiw case'
- }
- ],
+ dsb: [
+ {
+ word: 'word',
+ grammarForm: 'instrumental',
+ expected: 'z word',
+ description: 'Grammar test for instrumental case'
+ },
+ {
+ word: 'word',
+ grammarForm: 'lokatiw',
+ expected: 'wo word',
+ description: 'Grammar test for lokatiw case'
+ }
+ ],
- hy: [
- {
- word: 'Մաունա',
- grammarForm: 'genitive',
- expected: 'Մաունայի',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'հետո',
- grammarForm: 'genitive',
- expected: 'հետոյի',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'գիրք',
- grammarForm: 'genitive',
- expected: 'գրքի',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'ժամանակի',
- grammarForm: 'genitive',
- expected: 'ժամանակիի',
- description: 'Grammar test for genitive case'
- }
- ],
+ hy: [
+ {
+ word: 'Մաունա',
+ grammarForm: 'genitive',
+ expected: 'Մաունայի',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'հետո',
+ grammarForm: 'genitive',
+ expected: 'հետոյի',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'գիրք',
+ grammarForm: 'genitive',
+ expected: 'գրքի',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'ժամանակի',
+ grammarForm: 'genitive',
+ expected: 'ժամանակիի',
+ description: 'Grammar test for genitive case'
+ }
+ ],
- fi: [
- {
- word: 'talo',
- grammarForm: 'genitive',
- expected: 'talon',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'linux',
- grammarForm: 'genitive',
- expected: 'linuxin',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'talo',
- grammarForm: 'elative',
- expected: 'talosta',
- description: 'Grammar test for elative case'
- },
- {
- word: 'pastöroitu',
- grammarForm: 'partitive',
- expected: 'pastöroitua',
- description: 'Grammar test for partitive case'
- },
- {
- word: 'talo',
- grammarForm: 'partitive',
- expected: 'taloa',
- description: 'Grammar test for partitive case'
- },
- {
- word: 'talo',
- grammarForm: 'illative',
- expected: 'taloon',
- description: 'Grammar test for illative case'
- },
- {
- word: 'linux',
- grammarForm: 'inessive',
- expected: 'linuxissa',
- description: 'Grammar test for inessive case'
- }
- ],
+ fi: [
+ {
+ word: 'talo',
+ grammarForm: 'genitive',
+ expected: 'talon',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'linux',
+ grammarForm: 'genitive',
+ expected: 'linuxin',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'talo',
+ grammarForm: 'elative',
+ expected: 'talosta',
+ description: 'Grammar test for elative case'
+ },
+ {
+ word: 'pastöroitu',
+ grammarForm: 'partitive',
+ expected: 'pastöroitua',
+ description: 'Grammar test for partitive case'
+ },
+ {
+ word: 'talo',
+ grammarForm: 'partitive',
+ expected: 'taloa',
+ description: 'Grammar test for partitive case'
+ },
+ {
+ word: 'talo',
+ grammarForm: 'illative',
+ expected: 'taloon',
+ description: 'Grammar test for illative case'
+ },
+ {
+ word: 'linux',
+ grammarForm: 'inessive',
+ expected: 'linuxissa',
+ description: 'Grammar test for inessive case'
+ }
+ ],
- ru: [
- {
- word: 'тесть',
- grammarForm: 'genitive',
- expected: 'тестя',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'привилегия',
- grammarForm: 'genitive',
- expected: 'привилегии',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'установка',
- grammarForm: 'genitive',
- expected: 'установки',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'похоти',
- grammarForm: 'genitive',
- expected: 'похотей',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'доводы',
- grammarForm: 'genitive',
- expected: 'доводов',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'песчаник',
- grammarForm: 'genitive',
- expected: 'песчаника',
- description: 'Grammar test for genitive case'
- }
- ],
+ ru: [
+ {
+ word: 'тесть',
+ grammarForm: 'genitive',
+ expected: 'тестя',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'привилегия',
+ grammarForm: 'genitive',
+ expected: 'привилегии',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'установка',
+ grammarForm: 'genitive',
+ expected: 'установки',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'похоти',
+ grammarForm: 'genitive',
+ expected: 'похотей',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'доводы',
+ grammarForm: 'genitive',
+ expected: 'доводов',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'песчаник',
+ grammarForm: 'genitive',
+ expected: 'песчаника',
+ description: 'Grammar test for genitive case'
+ }
+ ],
- hu: [
- {
- word: 'Wikipédiá',
- grammarForm: 'rol',
- expected: 'Wikipédiáról',
- description: 'Grammar test for rol case'
- },
- {
- word: 'Wikipédiá',
- grammarForm: 'ba',
- expected: 'Wikipédiába',
- description: 'Grammar test for ba case'
- },
- {
- word: 'Wikipédiá',
- grammarForm: 'k',
- expected: 'Wikipédiák',
- description: 'Grammar test for k case'
- }
- ],
+ hu: [
+ {
+ word: 'Wikipédiá',
+ grammarForm: 'rol',
+ expected: 'Wikipédiáról',
+ description: 'Grammar test for rol case'
+ },
+ {
+ word: 'Wikipédiá',
+ grammarForm: 'ba',
+ expected: 'Wikipédiába',
+ description: 'Grammar test for ba case'
+ },
+ {
+ word: 'Wikipédiá',
+ grammarForm: 'k',
+ expected: 'Wikipédiák',
+ description: 'Grammar test for k case'
+ }
+ ],
- ga: [
- {
- word: 'an Domhnach',
- grammarForm: 'ainmlae',
- expected: 'Dé Domhnaigh',
- description: 'Grammar test for ainmlae case'
- },
- {
- word: 'an Luan',
- grammarForm: 'ainmlae',
- expected: 'Dé Luain',
- description: 'Grammar test for ainmlae case'
- },
- {
- word: 'an Satharn',
- grammarForm: 'ainmlae',
- expected: 'Dé Sathairn',
- description: 'Grammar test for ainmlae case'
- }
- ],
+ ga: [
+ {
+ word: 'an Domhnach',
+ grammarForm: 'ainmlae',
+ expected: 'Dé Domhnaigh',
+ description: 'Grammar test for ainmlae case'
+ },
+ {
+ word: 'an Luan',
+ grammarForm: 'ainmlae',
+ expected: 'Dé Luain',
+ description: 'Grammar test for ainmlae case'
+ },
+ {
+ word: 'an Satharn',
+ grammarForm: 'ainmlae',
+ expected: 'Dé Sathairn',
+ description: 'Grammar test for ainmlae case'
+ }
+ ],
- uk: [
- {
- word: 'тесть',
- grammarForm: 'genitive',
- expected: 'тестя',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'Вікіпедія',
- grammarForm: 'genitive',
- expected: 'Вікіпедії',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'установка',
- grammarForm: 'genitive',
- expected: 'установки',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'похоти',
- grammarForm: 'genitive',
- expected: 'похотей',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'доводы',
- grammarForm: 'genitive',
- expected: 'доводов',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'песчаник',
- grammarForm: 'genitive',
- expected: 'песчаника',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'Вікіпедія',
- grammarForm: 'accusative',
- expected: 'Вікіпедію',
- description: 'Grammar test for accusative case'
- }
- ],
+ uk: [
+ {
+ word: 'тесть',
+ grammarForm: 'genitive',
+ expected: 'тестя',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'Вікіпедія',
+ grammarForm: 'genitive',
+ expected: 'Вікіпедії',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'установка',
+ grammarForm: 'genitive',
+ expected: 'установки',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'похоти',
+ grammarForm: 'genitive',
+ expected: 'похотей',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'доводы',
+ grammarForm: 'genitive',
+ expected: 'доводов',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'песчаник',
+ grammarForm: 'genitive',
+ expected: 'песчаника',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'Вікіпедія',
+ grammarForm: 'accusative',
+ expected: 'Вікіпедію',
+ description: 'Grammar test for accusative case'
+ }
+ ],
- sl: [
- {
- word: 'word',
- grammarForm: 'orodnik',
- expected: 'z word',
- description: 'Grammar test for orodnik case'
- },
- {
- word: 'word',
- grammarForm: 'mestnik',
- expected: 'o word',
- description: 'Grammar test for mestnik case'
- }
- ],
+ sl: [
+ {
+ word: 'word',
+ grammarForm: 'orodnik',
+ expected: 'z word',
+ description: 'Grammar test for orodnik case'
+ },
+ {
+ word: 'word',
+ grammarForm: 'mestnik',
+ expected: 'o word',
+ description: 'Grammar test for mestnik case'
+ }
+ ],
- os: [
- {
- word: 'бæстæ',
- grammarForm: 'genitive',
- expected: 'бæсты',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'бæстæ',
- grammarForm: 'allative',
- expected: 'бæстæм',
- description: 'Grammar test for allative case'
- },
- {
- word: 'Тигр',
- grammarForm: 'dative',
- expected: 'Тигрæн',
- description: 'Grammar test for dative case'
- },
- {
- word: 'цъити',
- grammarForm: 'dative',
- expected: 'цъитийæн',
- description: 'Grammar test for dative case'
- },
- {
- word: 'лæппу',
- grammarForm: 'genitive',
- expected: 'лæппуйы',
- description: 'Grammar test for genitive case'
- },
- {
- word: '2011',
- grammarForm: 'equative',
- expected: '2011-ау',
- description: 'Grammar test for equative case'
- }
- ],
+ os: [
+ {
+ word: 'бæстæ',
+ grammarForm: 'genitive',
+ expected: 'бæсты',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'бæстæ',
+ grammarForm: 'allative',
+ expected: 'бæстæм',
+ description: 'Grammar test for allative case'
+ },
+ {
+ word: 'Тигр',
+ grammarForm: 'dative',
+ expected: 'Тигрæн',
+ description: 'Grammar test for dative case'
+ },
+ {
+ word: 'цъити',
+ grammarForm: 'dative',
+ expected: 'цъитийæн',
+ description: 'Grammar test for dative case'
+ },
+ {
+ word: 'лæппу',
+ grammarForm: 'genitive',
+ expected: 'лæппуйы',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: '2011',
+ grammarForm: 'equative',
+ expected: '2011-ау',
+ description: 'Grammar test for equative case'
+ }
+ ],
- la: [
- {
- word: 'Translatio',
- grammarForm: 'genitive',
- expected: 'Translationis',
- description: 'Grammar test for genitive case'
- },
- {
- word: 'Translatio',
- grammarForm: 'accusative',
- expected: 'Translationem',
- description: 'Grammar test for accusative case'
- },
- {
- word: 'Translatio',
- grammarForm: 'ablative',
- expected: 'Translatione',
- description: 'Grammar test for ablative case'
- }
- ]
-};
+ la: [
+ {
+ word: 'Translatio',
+ grammarForm: 'genitive',
+ expected: 'Translationis',
+ description: 'Grammar test for genitive case'
+ },
+ {
+ word: 'Translatio',
+ grammarForm: 'accusative',
+ expected: 'Translationem',
+ description: 'Grammar test for accusative case'
+ },
+ {
+ word: 'Translatio',
+ grammarForm: 'ablative',
+ expected: 'Translatione',
+ description: 'Grammar test for ablative case'
+ }
+ ]
+ };
-$.each( grammarTests, function ( langCode, test ) {
- if ( langCode === mw.config.get( 'wgUserLanguage' ) ) {
- grammarTest( langCode, test );
- }
-});
+ $.each( grammarTests, function ( langCode, test ) {
+ if ( langCode === mw.config.get( 'wgUserLanguage' ) ) {
+ grammarTest( langCode, test );
+ }
+ });
+}( mediaWiki, jQuery ) );
-( function ( mw ) {
+( function ( mw, $ ) {
QUnit.module( 'mediawiki', QUnit.newMwEnvironment() );
// /sample/awesome.js declares the "mw.loader.testCallback" function
// which contains a call to start() and ok()
- assert.strictEqual( isAwesomeDone, true, "test.callback module should've caused isAwesomeDone to be true" );
+ assert.strictEqual( isAwesomeDone, true, 'test.callback module should\'ve caused isAwesomeDone to be true' );
delete mw.loader.testCallback;
}, function () {
mw.loader.using(
['test.module7'],
function () {
- assert.ok( false, "Success fired despite missing dependency" );
- assert.ok( true , "QUnit expected() count dummy" );
+ assert.ok( false, 'Success fired despite missing dependency' );
+ assert.ok( true , 'QUnit expected() count dummy' );
},
function ( e, dependencies ) {
assert.strictEqual( $.isArray( dependencies ), true, 'Expected array of dependencies' );
mw.loader.using(
['test.module9'],
function () {
- assert.ok( false, "Success fired despite missing dependency" );
- assert.ok( true , "QUnit expected() count dummy" );
+ assert.ok( false, 'Success fired despite missing dependency' );
+ assert.ok( true , 'QUnit expected() count dummy' );
},
function ( e, dependencies ) {
assert.strictEqual( $.isArray( dependencies ), true, 'Expected array of dependencies' );
});
-}( mediaWiki ) );
+}( mediaWiki, jQuery ) );
-( function ( mw ) {
+( function ( mw, $ ) {
QUnit.module( 'mediawiki.user', QUnit.newMwEnvironment() );
QUnit.asyncTest( 'getRights', 1, function ( assert ) {
mw.user.getRights( function ( rights ) {
- // First group should always be '*'
assert.equal( $.type( rights ), 'array', 'Callback gets an array' );
QUnit.start();
});
});
-}( mediaWiki ) );
+}( mediaWiki, jQuery ) );
-QUnit.module( 'mediawiki.util', QUnit.newMwEnvironment() );
-
-QUnit.test( 'rawurlencode', 1, function ( assert ) {
- assert.equal( mw.util.rawurlencode( 'Test:A & B/Here' ), 'Test%3AA%20%26%20B%2FHere' );
-});
-
-QUnit.test( 'wikiUrlencode', 1, function ( assert ) {
- assert.equal( mw.util.wikiUrlencode( 'Test:A & B/Here' ), 'Test:A_%26_B/Here' );
-});
-
-QUnit.test( 'wikiGetlink', 3, function ( assert ) {
- // Not part of startUp module
- mw.config.set( 'wgArticlePath', '/wiki/$1' );
- mw.config.set( 'wgPageName', 'Foobar' );
-
- var hrefA = mw.util.wikiGetlink( 'Sandbox' );
- assert.equal( hrefA, '/wiki/Sandbox', 'Simple title; Get link for "Sandbox"' );
-
- var hrefB = mw.util.wikiGetlink( 'Foo:Sandbox ? 5+5=10 ! (test)/subpage' );
- assert.equal( hrefB, '/wiki/Foo:Sandbox_%3F_5%2B5%3D10_%21_%28test%29/subpage',
- 'Advanced title; Get link for "Foo:Sandbox ? 5+5=10 ! (test)/subpage"' );
-
- var hrefC = mw.util.wikiGetlink();
- assert.equal( hrefC, '/wiki/Foobar', 'Default title; Get link for current page ("Foobar")' );
-});
-
-QUnit.test( 'wikiScript', 4, function ( assert ) {
- mw.config.set({
- 'wgScript': '/w/i.php', // customized wgScript for bug 39103
- 'wgLoadScript': '/w/l.php', // customized wgLoadScript for bug 39103
- 'wgScriptPath': '/w',
- 'wgScriptExtension': '.php'
+( function ( mw, $ ) {
+ QUnit.module( 'mediawiki.util', QUnit.newMwEnvironment() );
+
+ QUnit.test( 'rawurlencode', 1, function ( assert ) {
+ assert.equal( mw.util.rawurlencode( 'Test:A & B/Here' ), 'Test%3AA%20%26%20B%2FHere' );
+ });
+
+ QUnit.test( 'wikiUrlencode', 1, function ( assert ) {
+ assert.equal( mw.util.wikiUrlencode( 'Test:A & B/Here' ), 'Test:A_%26_B/Here' );
});
- assert.equal( mw.util.wikiScript(), mw.config.get( 'wgScript' ), 'wikiScript() returns wgScript' );
- assert.equal( mw.util.wikiScript( 'index' ), mw.config.get( 'wgScript' ), "wikiScript( 'index' ) returns wgScript" );
- assert.equal( mw.util.wikiScript( 'load' ), mw.config.get( 'wgLoadScript' ), "wikiScript( 'load' ) returns wgLoadScript" );
- assert.equal( mw.util.wikiScript( 'api' ), '/w/api.php', 'API path' );
-});
-
-QUnit.test( 'addCSS', 3, function ( assert ) {
- var $testEl = $( '<div>' ).attr( 'id', 'mw-addcsstest' ).appendTo( '#qunit-fixture' );
-
- var style = mw.util.addCSS( '#mw-addcsstest { visibility: hidden; }' );
- assert.equal( typeof style, 'object', 'addCSS returned an object' );
- assert.strictEqual( style.disabled, false, 'property "disabled" is available and set to false' );
-
- assert.equal( $testEl.css( 'visibility' ), 'hidden', 'Added style properties are in effect' );
-
- // Clean up
- $( style.ownerNode ).remove();
-});
-
-QUnit.asyncTest( 'toggleToc', 4, function ( assert ) {
- assert.strictEqual( mw.util.toggleToc(), null, 'Return null if there is no table of contents on the page.' );
-
- var tocHtml =
- '<table id="toc" class="toc"><tr><td>' +
- '<div id="toctitle">' +
- '<h2>Contents</h2>' +
- '<span class="toctoggle"> [<a href="#" class="internal" id="togglelink">Hide</a> ]</span>' +
- '</div>' +
- '<ul><li></li></ul>' +
- '</td></tr></table>',
- $toc = $(tocHtml).appendTo( '#qunit-fixture' ),
+ QUnit.test( 'wikiGetlink', 3, function ( assert ) {
+ // Not part of startUp module
+ mw.config.set( 'wgArticlePath', '/wiki/$1' );
+ mw.config.set( 'wgPageName', 'Foobar' );
+
+ var href = mw.util.wikiGetlink( 'Sandbox' );
+ assert.equal( href, '/wiki/Sandbox', 'Simple title; Get link for "Sandbox"' );
+
+ href = mw.util.wikiGetlink( 'Foo:Sandbox ? 5+5=10 ! (test)/subpage' );
+ assert.equal( href, '/wiki/Foo:Sandbox_%3F_5%2B5%3D10_%21_%28test%29/subpage',
+ 'Advanced title; Get link for "Foo:Sandbox ? 5+5=10 ! (test)/subpage"' );
+
+ href = mw.util.wikiGetlink();
+ assert.equal( href, '/wiki/Foobar', 'Default title; Get link for current page ("Foobar")' );
+ });
+
+ QUnit.test( 'wikiScript', 4, function ( assert ) {
+ mw.config.set({
+ 'wgScript': '/w/i.php', // customized wgScript for bug 39103
+ 'wgLoadScript': '/w/l.php', // customized wgLoadScript for bug 39103
+ 'wgScriptPath': '/w',
+ 'wgScriptExtension': '.php'
+ });
+
+ assert.equal( mw.util.wikiScript(), mw.config.get( 'wgScript' ),
+ 'wikiScript() returns wgScript'
+ );
+ assert.equal( mw.util.wikiScript( 'index' ), mw.config.get( 'wgScript' ),
+ 'wikiScript( index ) returns wgScript'
+ );
+ assert.equal( mw.util.wikiScript( 'load' ), mw.config.get( 'wgLoadScript' ),
+ 'wikiScript( load ) returns wgLoadScript'
+ );
+ assert.equal( mw.util.wikiScript( 'api' ), '/w/api.php', 'API path' );
+ });
+
+ QUnit.test( 'addCSS', 3, function ( assert ) {
+ var $el, style;
+ $el = $( '<div>' ).attr( 'id', 'mw-addcsstest' ).appendTo( '#qunit-fixture' );
+
+ style = mw.util.addCSS( '#mw-addcsstest { visibility: hidden; }' );
+ assert.equal( typeof style, 'object', 'addCSS returned an object' );
+ assert.strictEqual( style.disabled, false, 'property "disabled" is available and set to false' );
+
+ assert.equal( $el.css( 'visibility' ), 'hidden', 'Added style properties are in effect' );
+
+ // Clean up
+ $( style.ownerNode ).remove();
+ });
+
+ QUnit.asyncTest( 'toggleToc', 4, function ( assert ) {
+ var tocHtml, $toggleLink;
+
+ function actionC() {
+ QUnit.start();
+ }
+
+ function actionB() {
+ assert.strictEqual( mw.util.toggleToc( $toggleLink, actionC ), true, 'Return boolean true if the TOC is now visible.' );
+ }
+
+ function actionA() {
+ assert.strictEqual( mw.util.toggleToc( $toggleLink, actionB ), false, 'Return boolean false if the TOC is now hidden.' );
+ }
+
+ assert.strictEqual( mw.util.toggleToc(), null, 'Return null if there is no table of contents on the page.' );
+
+ tocHtml =
+ '<table id="toc" class="toc"><tr><td>' +
+ '<div id="toctitle">' +
+ '<h2>Contents</h2>' +
+ '<span class="toctoggle"> [<a href="#" class="internal" id="togglelink">Hide</a> ]</span>' +
+ '</div>' +
+ '<ul><li></li></ul>' +
+ '</td></tr></table>';
+ $(tocHtml).appendTo( '#qunit-fixture' ),
$toggleLink = $( '#togglelink' );
- assert.strictEqual( $toggleLink.length, 1, 'Toggle link is appended to the page.' );
-
- var actionC = function() {
- QUnit.start();
- };
- var actionB = function() {
- assert.strictEqual( mw.util.toggleToc( $toggleLink, actionC ), true, 'Return boolean true if the TOC is now visible.' );
- };
- var actionA = function() {
- assert.strictEqual( mw.util.toggleToc( $toggleLink, actionB ), false, 'Return boolean false if the TOC is now hidden.' );
- };
-
- actionA();
-});
-
-QUnit.test( 'getParamValue', 5, function ( assert ) {
- var url1 = 'http://example.org/?foo=wrong&foo=right#&foo=bad';
-
- assert.equal( mw.util.getParamValue( 'foo', url1 ), 'right', 'Use latest one, ignore hash' );
- assert.strictEqual( mw.util.getParamValue( 'bar', url1 ), null, 'Return null when not found' );
-
- var url2 = 'http://example.org/#&foo=bad';
- assert.strictEqual( mw.util.getParamValue( 'foo', url2 ), null, 'Ignore hash if param is not in querystring but in hash (bug 27427)' );
-
- var url3 = 'example.org?' + $.param({ 'TEST': 'a b+c' });
- assert.strictEqual( mw.util.getParamValue( 'TEST', url3 ), 'a b+c', 'Bug 30441: getParamValue must understand "+" encoding of space' );
-
- var url4 = 'example.org?' + $.param({ 'TEST': 'a b+c d' }); // check for sloppy code from r95332 :)
- assert.strictEqual( mw.util.getParamValue( 'TEST', url4 ), 'a b+c d', 'Bug 30441: getParamValue must understand "+" encoding of space (multiple spaces)' );
-});
-
-QUnit.test( 'tooltipAccessKey', 3, function ( assert ) {
- assert.equal( typeof mw.util.tooltipAccessKeyPrefix, 'string', 'mw.util.tooltipAccessKeyPrefix must be a string' );
- assert.ok( mw.util.tooltipAccessKeyRegexp instanceof RegExp, 'mw.util.tooltipAccessKeyRegexp instance of RegExp' );
- assert.ok( mw.util.updateTooltipAccessKeys, 'mw.util.updateTooltipAccessKeys' );
-});
-
-QUnit.test( '$content', 2, function ( assert ) {
- assert.ok( mw.util.$content instanceof jQuery, 'mw.util.$content instance of jQuery' );
- assert.strictEqual( mw.util.$content.length, 1, 'mw.util.$content must have length of 1' );
-});
-
-
-/**
- * Portlet names are prefixed with 'p-test' to avoid conflict with core
- * when running the test suite under a wiki page.
- * Previously, test elements where invisible to the selector since only
- * one element can have a given id.
- */
-QUnit.test( 'addPortletLink', 8, function ( assert ) {
- var pTestTb, pCustom, vectorTabs, tbRL, cuQuux, $cuQuux, tbMW, $tbMW, tbRLDM, caFoo;
- pTestTb = '\
- <div class="portlet" id="p-test-tb">\
- <h5>Toolbox</h5>\
- <ul class="body"></ul>\
- </div>';
- pCustom = '\
- <div class="portlet" id="p-test-custom">\
- <h5>Views</h5>\
- <ul class="body">\
- <li id="c-foo"><a href="#">Foo</a></li>\
- <li id="c-barmenu">\
- <ul>\
- <li id="c-bar-baz"><a href="#">Baz</a></a>\
- </ul>\
- </li>\
- </ul>\
- </div>';
- vectorTabs = '\
- <div id="p-test-views" class="vectorTabs">\
- <h5>Views</h5>\
- <ul></ul>\
- </div>';
-
- $( '#qunit-fixture' ).append( pTestTb, pCustom, vectorTabs );
-
- tbRL = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/ResourceLoader',
- 'ResourceLoader', 't-rl', 'More info about ResourceLoader on MediaWiki.org ', 'l' );
-
- assert.ok( $.isDomElement( tbRL ), 'addPortletLink returns a valid DOM Element according to $.isDomElement' );
-
- tbMW = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/',
- 'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org ', 'm', tbRL );
- $tbMW = $( tbMW );
-
-
- assert.equal( $tbMW.attr( 'id' ), 't-mworg', 'Link has correct ID set' );
- assert.equal( $tbMW.closest( '.portlet' ).attr( 'id' ), 'p-test-tb', 'Link was inserted within correct portlet' );
- assert.equal( $tbMW.next().attr( 'id' ), 't-rl', 'Link is in the correct position (by passing nextnode)' );
-
- cuQuux = mw.util.addPortletLink( 'p-test-custom', '#', 'Quux' );
- $cuQuux = $(cuQuux);
-
- assert.equal(
- $( '#p-test-custom #c-barmenu ul li' ).length,
- 1,
- 'addPortletLink did not add the item to all <ul> elements in the portlet (bug 35082)'
- );
-
- tbRLDM = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
- 'Default modules', 't-rldm', 'List of all default modules ', 'd', '#t-rl' );
-
- assert.equal( $( tbRLDM ).next().attr( 'id' ), 't-rl', 'Link is in the correct position (by passing CSS selector)' );
-
- caFoo = mw.util.addPortletLink( 'p-test-views', '#', 'Foo' );
-
- assert.strictEqual( $tbMW.find( 'span').length, 0, 'No <span> element should be added for porlets without vectorTabs class.' );
- assert.strictEqual( $( caFoo ).find( 'span').length, 1, 'A <span> element should be added for porlets with vectorTabs class.' );
-});
-
-QUnit.test( 'jsMessage', 1, function ( assert ) {
- var a = mw.util.jsMessage( "MediaWiki is <b>Awesome</b>." );
- assert.ok( a, 'Basic checking of return value' );
-
- // Clean up
- $( '#mw-js-message' ).remove();
-});
-
-QUnit.test( 'validateEmail', 6, function ( assert ) {
- assert.strictEqual( mw.util.validateEmail( "" ), null, 'Should return null for empty string ' );
- assert.strictEqual( mw.util.validateEmail( "user@localhost" ), true, 'Return true for a valid e-mail address' );
-
- // testEmailWithCommasAreInvalids
- assert.strictEqual( mw.util.validateEmail( "user,foo@example.org" ), false, 'Emails with commas are invalid' );
- assert.strictEqual( mw.util.validateEmail( "userfoo@ex,ample.org" ), false, 'Emails with commas are invalid' );
-
- // testEmailWithHyphens
- assert.strictEqual( mw.util.validateEmail( "user-foo@example.org" ), true, 'Emails may contain a hyphen' );
- assert.strictEqual( mw.util.validateEmail( "userfoo@ex-ample.org" ), true, 'Emails may contain a hyphen' );
-});
-
-QUnit.test( 'isIPv6Address', 40, function ( assert ) {
- // Shortcuts
- function assertFalseIPv6( addy, summary ) {
- return assert.strictEqual( mw.util.isIPv6Address( addy ), false, summary );
- }
- function assertTrueIPv6( addy, summary ) {
- return assert.strictEqual( mw.util.isIPv6Address( addy ), true, summary );
- }
-
- // Based on IPTest.php > testisIPv6
- assertFalseIPv6( ':fc:100::', 'IPv6 starting with lone ":"' );
- assertFalseIPv6( 'fc:100:::', 'IPv6 ending with a ":::"' );
- assertFalseIPv6( 'fc:300', 'IPv6 with only 2 words' );
- assertFalseIPv6( 'fc:100:300', 'IPv6 with only 3 words' );
-
- $.each(
- ['fc:100::',
- 'fc:100:a::',
- 'fc:100:a:d::',
- 'fc:100:a:d:1::',
- 'fc:100:a:d:1:e::',
- 'fc:100:a:d:1:e:ac::'], function ( i, addy ){
- assertTrueIPv6( addy, addy + ' is a valid IP' );
+ assert.strictEqual( $toggleLink.length, 1, 'Toggle link is appended to the page.' );
+
+ actionA();
});
- assertFalseIPv6( 'fc:100:a:d:1:e:ac:0::', 'IPv6 with 8 words ending with "::"' );
- assertFalseIPv6( 'fc:100:a:d:1:e:ac:0:1::', 'IPv6 with 9 words ending with "::"' );
-
- assertFalseIPv6( ':::' );
- assertFalseIPv6( '::0:', 'IPv6 ending in a lone ":"' );
-
- assertTrueIPv6( '::', 'IPv6 zero address' );
- $.each(
- ['::0',
- '::fc',
- '::fc:100',
- '::fc:100:a',
- '::fc:100:a:d',
- '::fc:100:a:d:1',
- '::fc:100:a:d:1:e',
- '::fc:100:a:d:1:e:ac',
-
- 'fc:100:a:d:1:e:ac:0'], function ( i, addy ){
- assertTrueIPv6( addy, addy + ' is a valid IP' );
+ QUnit.test( 'getParamValue', 5, function ( assert ) {
+ var url;
+
+ url = 'http://example.org/?foo=wrong&foo=right#&foo=bad';
+ assert.equal( mw.util.getParamValue( 'foo', url ), 'right', 'Use latest one, ignore hash' );
+ assert.strictEqual( mw.util.getParamValue( 'bar', url ), null, 'Return null when not found' );
+
+ url = 'http://example.org/#&foo=bad';
+ assert.strictEqual( mw.util.getParamValue( 'foo', url ), null, 'Ignore hash if param is not in querystring but in hash (bug 27427)' );
+
+ url = 'example.org?' + $.param({ 'TEST': 'a b+c' });
+ assert.strictEqual( mw.util.getParamValue( 'TEST', url ), 'a b+c', 'Bug 30441: getParamValue must understand "+" encoding of space' );
+
+ url = 'example.org?' + $.param({ 'TEST': 'a b+c d' }); // check for sloppy code from r95332 :)
+ assert.strictEqual( mw.util.getParamValue( 'TEST', url ), 'a b+c d', 'Bug 30441: getParamValue must understand "+" encoding of space (multiple spaces)' );
+ });
+
+ QUnit.test( 'tooltipAccessKey', 3, function ( assert ) {
+ assert.equal( typeof mw.util.tooltipAccessKeyPrefix, 'string', 'mw.util.tooltipAccessKeyPrefix must be a string' );
+ assert.ok( mw.util.tooltipAccessKeyRegexp instanceof RegExp, 'mw.util.tooltipAccessKeyRegexp instance of RegExp' );
+ assert.ok( mw.util.updateTooltipAccessKeys, 'mw.util.updateTooltipAccessKeys' );
+ });
+
+ QUnit.test( '$content', 2, function ( assert ) {
+ assert.ok( mw.util.$content instanceof jQuery, 'mw.util.$content instance of jQuery' );
+ assert.strictEqual( mw.util.$content.length, 1, 'mw.util.$content must have length of 1' );
+ });
+
+
+ /**
+ * Portlet names are prefixed with 'p-test' to avoid conflict with core
+ * when running the test suite under a wiki page.
+ * Previously, test elements where invisible to the selector since only
+ * one element can have a given id.
+ */
+ QUnit.test( 'addPortletLink', 8, function ( assert ) {
+ var pTestTb, pCustom, vectorTabs, tbRL, cuQuux, $cuQuux, tbMW, $tbMW, tbRLDM, caFoo;
+
+ pTestTb = '\
+ <div class="portlet" id="p-test-tb">\
+ <h5>Toolbox</h5>\
+ <ul class="body"></ul>\
+ </div>';
+ pCustom = '\
+ <div class="portlet" id="p-test-custom">\
+ <h5>Views</h5>\
+ <ul class="body">\
+ <li id="c-foo"><a href="#">Foo</a></li>\
+ <li id="c-barmenu">\
+ <ul>\
+ <li id="c-bar-baz"><a href="#">Baz</a></a>\
+ </ul>\
+ </li>\
+ </ul>\
+ </div>';
+ vectorTabs = '\
+ <div id="p-test-views" class="vectorTabs">\
+ <h5>Views</h5>\
+ <ul></ul>\
+ </div>';
+
+ $( '#qunit-fixture' ).append( pTestTb, pCustom, vectorTabs );
+
+ tbRL = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/ResourceLoader',
+ 'ResourceLoader', 't-rl', 'More info about ResourceLoader on MediaWiki.org ', 'l' );
+
+ assert.ok( $.isDomElement( tbRL ), 'addPortletLink returns a valid DOM Element according to $.isDomElement' );
+
+ tbMW = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/',
+ 'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org ', 'm', tbRL );
+ $tbMW = $( tbMW );
+
+
+ assert.equal( $tbMW.attr( 'id' ), 't-mworg', 'Link has correct ID set' );
+ assert.equal( $tbMW.closest( '.portlet' ).attr( 'id' ), 'p-test-tb', 'Link was inserted within correct portlet' );
+ assert.equal( $tbMW.next().attr( 'id' ), 't-rl', 'Link is in the correct position (by passing nextnode)' );
+
+ cuQuux = mw.util.addPortletLink( 'p-test-custom', '#', 'Quux' );
+ $cuQuux = $(cuQuux);
+
+ assert.equal(
+ $( '#p-test-custom #c-barmenu ul li' ).length,
+ 1,
+ 'addPortletLink did not add the item to all <ul> elements in the portlet (bug 35082)'
+ );
+
+ tbRLDM = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
+ 'Default modules', 't-rldm', 'List of all default modules ', 'd', '#t-rl' );
+
+ assert.equal( $( tbRLDM ).next().attr( 'id' ), 't-rl', 'Link is in the correct position (by passing CSS selector)' );
+
+ caFoo = mw.util.addPortletLink( 'p-test-views', '#', 'Foo' );
+
+ assert.strictEqual( $tbMW.find( 'span').length, 0, 'No <span> element should be added for porlets without vectorTabs class.' );
+ assert.strictEqual( $( caFoo ).find( 'span').length, 1, 'A <span> element should be added for porlets with vectorTabs class.' );
});
- assertFalseIPv6( '::fc:100:a:d:1:e:ac:0', 'IPv6 with "::" and 8 words' );
- assertFalseIPv6( '::fc:100:a:d:1:e:ac:0:1', 'IPv6 with 9 words' );
-
- assertFalseIPv6( ':fc::100', 'IPv6 starting with lone ":"' );
- assertFalseIPv6( 'fc::100:', 'IPv6 ending with lone ":"' );
- assertFalseIPv6( 'fc:::100', 'IPv6 with ":::" in the middle' );
-
- assertTrueIPv6( 'fc::100', 'IPv6 with "::" and 2 words' );
- assertTrueIPv6( 'fc::100:a', 'IPv6 with "::" and 3 words' );
- assertTrueIPv6( 'fc::100:a:d', 'IPv6 with "::" and 4 words' );
- assertTrueIPv6( 'fc::100:a:d:1', 'IPv6 with "::" and 5 words' );
- assertTrueIPv6( 'fc::100:a:d:1:e', 'IPv6 with "::" and 6 words' );
- assertTrueIPv6( 'fc::100:a:d:1:e:ac', 'IPv6 with "::" and 7 words' );
- assertTrueIPv6( '2001::df', 'IPv6 with "::" and 2 words' );
- assertTrueIPv6( '2001:5c0:1400:a::df', 'IPv6 with "::" and 5 words' );
- assertTrueIPv6( '2001:5c0:1400:a::df:2', 'IPv6 with "::" and 6 words' );
-
- assertFalseIPv6( 'fc::100:a:d:1:e:ac:0', 'IPv6 with "::" and 8 words' );
- assertFalseIPv6( 'fc::100:a:d:1:e:ac:0:1', 'IPv6 with 9 words' );
-});
-
-QUnit.test( 'isIPv4Address', 11, function ( assert ) {
- // Shortcuts
- function assertFalseIPv4( addy, summary ) {
- assert.strictEqual( mw.util.isIPv4Address( addy ), false, summary );
- }
- function assertTrueIPv4( addy, summary ) {
- assert.strictEqual( mw.util.isIPv4Address( addy ), true, summary );
- }
-
- // Based on IPTest.php > testisIPv4
- assertFalseIPv4( false, 'Boolean false is not an IP' );
- assertFalseIPv4( true, 'Boolean true is not an IP' );
- assertFalseIPv4( '', 'Empty string is not an IP' );
- assertFalseIPv4( 'abc', '"abc" is not an IP' );
- assertFalseIPv4( ':', 'Colon is not an IP' );
- assertFalseIPv4( '124.24.52', 'IPv4 not enough quads' );
- assertFalseIPv4( '24.324.52.13', 'IPv4 out of range' );
- assertFalseIPv4( '.24.52.13', 'IPv4 starts with period' );
-
- assertTrueIPv4( '124.24.52.13', '124.24.52.134 is a valid IP' );
- assertTrueIPv4( '1.24.52.13', '1.24.52.13 is a valid IP' );
- assertFalseIPv4( '74.24.52.13/20', 'IPv4 ranges are not recogzized as valid IPs' );
-});
+ QUnit.test( 'jsMessage', 1, function ( assert ) {
+ var a = mw.util.jsMessage( 'MediaWiki is <b>Awesome</b>.' );
+ assert.ok( a, 'Basic checking of return value' );
+
+ // Clean up
+ $( '#mw-js-message' ).remove();
+ });
+
+ QUnit.test( 'validateEmail', 6, function ( assert ) {
+ assert.strictEqual( mw.util.validateEmail( '' ), null, 'Should return null for empty string ' );
+ assert.strictEqual( mw.util.validateEmail( 'user@localhost' ), true, 'Return true for a valid e-mail address' );
+
+ // testEmailWithCommasAreInvalids
+ assert.strictEqual( mw.util.validateEmail( 'user,foo@example.org' ), false, 'Emails with commas are invalid' );
+ assert.strictEqual( mw.util.validateEmail( 'userfoo@ex,ample.org' ), false, 'Emails with commas are invalid' );
+
+ // testEmailWithHyphens
+ assert.strictEqual( mw.util.validateEmail( 'user-foo@example.org' ), true, 'Emails may contain a hyphen' );
+ assert.strictEqual( mw.util.validateEmail( 'userfoo@ex-ample.org' ), true, 'Emails may contain a hyphen' );
+ });
+
+ QUnit.test( 'isIPv6Address', 40, function ( assert ) {
+ // Shortcuts
+ function assertFalseIPv6( addy, summary ) {
+ return assert.strictEqual( mw.util.isIPv6Address( addy ), false, summary );
+ }
+ function assertTrueIPv6( addy, summary ) {
+ return assert.strictEqual( mw.util.isIPv6Address( addy ), true, summary );
+ }
+
+ // Based on IPTest.php > testisIPv6
+ assertFalseIPv6( ':fc:100::', 'IPv6 starting with lone ":"' );
+ assertFalseIPv6( 'fc:100:::', 'IPv6 ending with a ":::"' );
+ assertFalseIPv6( 'fc:300', 'IPv6 with only 2 words' );
+ assertFalseIPv6( 'fc:100:300', 'IPv6 with only 3 words' );
+
+ $.each(
+ ['fc:100::',
+ 'fc:100:a::',
+ 'fc:100:a:d::',
+ 'fc:100:a:d:1::',
+ 'fc:100:a:d:1:e::',
+ 'fc:100:a:d:1:e:ac::'], function ( i, addy ){
+ assertTrueIPv6( addy, addy + ' is a valid IP' );
+ });
+
+ assertFalseIPv6( 'fc:100:a:d:1:e:ac:0::', 'IPv6 with 8 words ending with "::"' );
+ assertFalseIPv6( 'fc:100:a:d:1:e:ac:0:1::', 'IPv6 with 9 words ending with "::"' );
+
+ assertFalseIPv6( ':::' );
+ assertFalseIPv6( '::0:', 'IPv6 ending in a lone ":"' );
+
+ assertTrueIPv6( '::', 'IPv6 zero address' );
+ $.each(
+ ['::0',
+ '::fc',
+ '::fc:100',
+ '::fc:100:a',
+ '::fc:100:a:d',
+ '::fc:100:a:d:1',
+ '::fc:100:a:d:1:e',
+ '::fc:100:a:d:1:e:ac',
+
+ 'fc:100:a:d:1:e:ac:0'], function ( i, addy ){
+ assertTrueIPv6( addy, addy + ' is a valid IP' );
+ });
+
+ assertFalseIPv6( '::fc:100:a:d:1:e:ac:0', 'IPv6 with "::" and 8 words' );
+ assertFalseIPv6( '::fc:100:a:d:1:e:ac:0:1', 'IPv6 with 9 words' );
+
+ assertFalseIPv6( ':fc::100', 'IPv6 starting with lone ":"' );
+ assertFalseIPv6( 'fc::100:', 'IPv6 ending with lone ":"' );
+ assertFalseIPv6( 'fc:::100', 'IPv6 with ":::" in the middle' );
+
+ assertTrueIPv6( 'fc::100', 'IPv6 with "::" and 2 words' );
+ assertTrueIPv6( 'fc::100:a', 'IPv6 with "::" and 3 words' );
+ assertTrueIPv6( 'fc::100:a:d', 'IPv6 with "::" and 4 words' );
+ assertTrueIPv6( 'fc::100:a:d:1', 'IPv6 with "::" and 5 words' );
+ assertTrueIPv6( 'fc::100:a:d:1:e', 'IPv6 with "::" and 6 words' );
+ assertTrueIPv6( 'fc::100:a:d:1:e:ac', 'IPv6 with "::" and 7 words' );
+ assertTrueIPv6( '2001::df', 'IPv6 with "::" and 2 words' );
+ assertTrueIPv6( '2001:5c0:1400:a::df', 'IPv6 with "::" and 5 words' );
+ assertTrueIPv6( '2001:5c0:1400:a::df:2', 'IPv6 with "::" and 6 words' );
+
+ assertFalseIPv6( 'fc::100:a:d:1:e:ac:0', 'IPv6 with "::" and 8 words' );
+ assertFalseIPv6( 'fc::100:a:d:1:e:ac:0:1', 'IPv6 with 9 words' );
+ });
+
+ QUnit.test( 'isIPv4Address', 11, function ( assert ) {
+ // Shortcuts
+ function assertFalseIPv4( addy, summary ) {
+ assert.strictEqual( mw.util.isIPv4Address( addy ), false, summary );
+ }
+ function assertTrueIPv4( addy, summary ) {
+ assert.strictEqual( mw.util.isIPv4Address( addy ), true, summary );
+ }
+
+ // Based on IPTest.php > testisIPv4
+ assertFalseIPv4( false, 'Boolean false is not an IP' );
+ assertFalseIPv4( true, 'Boolean true is not an IP' );
+ assertFalseIPv4( '', 'Empty string is not an IP' );
+ assertFalseIPv4( 'abc', '"abc" is not an IP' );
+ assertFalseIPv4( ':', 'Colon is not an IP' );
+ assertFalseIPv4( '124.24.52', 'IPv4 not enough quads' );
+ assertFalseIPv4( '24.324.52.13', 'IPv4 out of range' );
+ assertFalseIPv4( '.24.52.13', 'IPv4 starts with period' );
+
+ assertTrueIPv4( '124.24.52.13', '124.24.52.134 is a valid IP' );
+ assertTrueIPv4( '1.24.52.13', '1.24.52.13 is a valid IP' );
+ assertFalseIPv4( '74.24.52.13/20', 'IPv4 ranges are not recogzized as valid IPs' );
+ });
+}( mediaWiki, jQuery ) );
// Called directly, use $_REQUEST params
wfThumbHandleRequest();
}
+
wfLogProfilingData();
//--------------------------------------------------------------------------
* @return void
*/
function wfThumbHandle404() {
- # lighttpd puts the original request in REQUEST_URI, while sjs sets
- # that to the 404 handler, and puts the original request in REDIRECT_URL.
- if ( isset( $_SERVER['REDIRECT_URL'] ) ) {
- # The URL is un-encoded, so put it back how it was
- $uriPath = str_replace( "%2F", "/", urlencode( $_SERVER['REDIRECT_URL'] ) );
- } else {
- $uriPath = $_SERVER['REQUEST_URI'];
- }
- # Just get the URI path (REDIRECT_URL/REQUEST_URI is either a full URL or a path)
- if ( substr( $uriPath, 0, 1 ) !== '/' ) {
- $bits = wfParseUrl( $uriPath );
- if ( $bits && isset( $bits['path'] ) ) {
- $uriPath = $bits['path'];
- } else {
- wfThumbError( 404, 'The source file for the specified thumbnail does not exist.' );
- return;
- }
+ global $wgArticlePath;
+
+ # Set action base paths so that WebRequest::getPathInfo()
+ # recognizes the "X" as the 'title' in ../thumb_handler.php/X urls.
+ $wgArticlePath = false; # Don't let a "/*" article path clober our action path
+
+ $matches = WebRequest::getPathInfo();
+ if ( !isset( $matches['title'] ) ) {
+ wfThumbError( 404, 'Could not determine the name of the requested thumbnail.' );
+ return;
}
- $params = wfExtractThumbParams( $uriPath ); // basic wiki URL param extracting
+ $params = wfExtractThumbParams( $matches['title'] ); // basic wiki URL param extracting
if ( $params == null ) {
- wfThumbError( 404, 'The source file for the specified thumbnail does not exist.' );
+ wfThumbError( 400, 'The specified thumbnail parameters are not recognized.' );
return;
}
* Extract the required params for thumb.php from the thumbnail request URI.
* At least 'width' and 'f' should be set if the result is an array.
*
- * @param $uriPath String Thumbnail request URI path
+ * @param $thumbRel String Thumbnail path relative to the thumb zone
* @return Array|null associative params array or null
*/
-function wfExtractThumbParams( $uriPath ) {
+function wfExtractThumbParams( $thumbRel ) {
$repo = RepoGroup::singleton()->getLocalRepo();
- // Zone URL might be relative ("/images") or protocol-relative ("//lang.site/image")
- $zoneUriPath = $repo->getZoneHandlerUrl( 'thumb' )
- ? $repo->getZoneHandlerUrl( 'thumb' ) // custom URL
- : $repo->getZoneUrl( 'thumb' ); // default to main URL
- $bits = wfParseUrl( wfExpandUrl( $zoneUriPath, PROTO_INTERNAL ) );
- if ( $bits && isset( $bits['path'] ) ) {
- $zoneUriPath = $bits['path'];
- } else {
- return null; // not a valid thumbnail URL
- }
-
$hashDirReg = $subdirReg = '';
for ( $i = 0; $i < $repo->getHashLevels(); $i++ ) {
$subdirReg .= '[0-9a-f]';
$hashDirReg .= "$subdirReg/";
}
- $zoneReg = preg_quote( $zoneUriPath ); // regex for thumb zone URI
// Check if this is a thumbnail of an original in the local file repo
- if ( preg_match( "!^$zoneReg/((archive/)?$hashDirReg([^/]*)/([^/]*))$!", $uriPath, $m ) ) {
+ if ( preg_match( "!^((archive/)?$hashDirReg([^/]*)/([^/]*))$!", $thumbRel, $m ) ) {
list( /*all*/, $rel, $archOrTemp, $filename, $thumbname ) = $m;
// Check if this is a thumbnail of an temp file in the local file repo
- } elseif ( preg_match( "!^$zoneReg/(temp/)($hashDirReg([^/]*)/([^/]*))$!", $uriPath, $m ) ) {
+ } elseif ( preg_match( "!^(temp/)($hashDirReg([^/]*)/([^/]*))$!", $thumbRel, $m ) ) {
list( /*all*/, $archOrTemp, $rel, $filename, $thumbname ) = $m;
} else {
return null; // not a valid looking thumbnail request
}
- $filename = urldecode( $filename );
- $thumbname = urldecode( $thumbname );
-
$params = array( 'f' => $filename, 'rel404' => $rel );
if ( $archOrTemp === 'archive/' ) {
$params['archived'] = 1;