Merge "thumb.php now handles short and long thumbnail name formats when possible."
authorCatrope <roan.kattouw@gmail.com>
Thu, 6 Sep 2012 17:42:29 +0000 (17:42 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 6 Sep 2012 17:42:29 +0000 (17:42 +0000)
28 files changed:
RELEASE-NOTES-1.20
docs/hooks.txt
includes/IP.php
includes/ImagePage.php
includes/SkinTemplate.php
includes/Timestamp.php
includes/api/ApiMain.php
includes/api/ApiMove.php
includes/api/ApiQuery.php
includes/filebackend/FileBackend.php
includes/filebackend/SwiftFileBackend.php
includes/media/FormatMetadata.php
includes/specials/SpecialLog.php
languages/messages/MessagesBar.php
languages/messages/MessagesCkb.php
languages/messages/MessagesDe.php
languages/messages/MessagesDiq.php
languages/messages/MessagesEo.php
languages/messages/MessagesFi.php
languages/messages/MessagesHu.php
languages/messages/MessagesKa.php
languages/messages/MessagesMai.php
languages/messages/MessagesPa.php
languages/messages/MessagesPms.php
languages/messages/MessagesPs.php
languages/messages/MessagesQqq.php
languages/messages/MessagesTa.php
skins/common/preview.js

index a48b81c..51798c7 100644 (file)
@@ -230,11 +230,13 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
   PCRE is compiled without support for unicode properties.
 * (bug 30390) Suggested file name on Special:Upload should not contain
   illegal characters.
-* (bug 27111) Cascading foreign file repos now fetch shared descriptions properly.
 * EXIF below sea level GPS altitude data is now shown correctly.
 * (bug 39284) jquery.tablesorter should not consider "."" or "?"" to be a currency.
 * (bug 39273) "Show changes" should not be incorrectly displayed in the Live Preview state.
 * Made body-content lang attribute honor the variant language when it is set.
+* (bug 36761) "Mark pages as visited" now submits previously established filter options.
+* (bug 39635) PostgreSQL LOCK IN SHARE MODE option is a syntax error.
+* (bug 36329) Accesskey tooltips for Firefox 14 on Mac should use "ctrl-option-" prefix.
 
 === API changes in 1.20 ===
 * (bug 34316) Add ability to retrieve maximum upload size from MediaWiki API.
@@ -251,7 +253,6 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
 * (bug 34927) Output media_type for list=filearchive.
 * (bug 28814) add properties to output of action=parse.
 * (bug 33224) add variants of content language to meta=siteinfo.
-* (bug 36761) "Mark pages as visited" now submits previously established filter options.
 * (bug 32643) action=purge with forcelinkupdate no longer crashes when ratelimit is reached.
 * The paraminfo module now also contains result properties for most modules.
 * (bug 32348) Allow descending order for list=alllinks.
@@ -272,8 +273,8 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
 * (bug 38904) prop=revisions&rvstart=... no longer blows up when continuing.
 * (bug 39032) ApiQuery generates help in constructor.
 * (bug 11142) Improve file extension blacklist error reporting in API upload.
-* (bug 39635) PostgreSQL LOCK IN SHARE MODE option is a syntax error.
-* (bug 36329) Accesskey tooltips for Firefox 14 on Mac should use "ctrl-option-" prefix.
+* (bug 39665) Cache AllowedGenerator array so it doesn't autoload all query classes
+  on every request.
 
 === Languages updated in 1.20 ===
 
index 7844aaf..5b78ed9 100644 (file)
@@ -314,6 +314,13 @@ $body: Body of the message
 Use this to extend core API modules.
 &$module: Module object
 
+'APICheckCanExecute': Called during ApiMain::checkCanExecute. Use to
+further authenticate and authorize API clients before executing the
+module. Return false and set a message to cancel the request.
+$module: Module object
+$user: Current user
+&$message: API usage message to die with
+
 'APIEditBeforeSave': before saving a page with api.php?action=edit,
 after processing request parameters. Return false to let the request
 fail, returning an error message or an <edit result="Failure"> tag
index 1828249..10c707e 100644 (file)
@@ -714,6 +714,7 @@ class IP {
         * @return String: valid dotted quad IPv4 address or null
         */
        public static function canonicalize( $addr ) {
+               $addr = preg_replace( '/\%.*/','', $addr ); // remove zone info (bug 35738)
                if ( self::isValid( $addr ) ) {
                        return $addr;
                }
index 7bbd584..c7afb76 100644 (file)
@@ -94,47 +94,10 @@ class ImagePage extends Article {
        /**
         * Handler for action=render
         * Include body text only; none of the image extras
-        * However, also include the shared description text
-        * so that cascading ForeignAPIRepo's work.
-        *
-        * @note This uses a div with the class "mw-shared-image-desc"
-        *    as opposed to the id "mw-shared-image-desc" since the text
-        *    from here may be cascadingly transcluded to other shared
-        *    repos, and we want all ids to be unique. On normal
-        *    view, the outermost shared description will still have
-        *    the id.
-        *
-        * This also differs from normal view in that "shareddescriptionfollows"
-        * message is not shown. I was not sure if it was appropriate to
-        * add that message here.
         */
        public function render() {
-               $out = $this->getContext()->getOutput();
-                $this->loadFile();
-
-                $descText = $this->mPage->getFile()->getDescriptionText();
-
-               $out->setArticleBodyOnly( true );
-
-               if ( !$descText ) {
-                       // If no description text, just do standard action=render
-                       parent::view();
-               } else {
-                       if ( $this->mPage->getID() !== 0 ) {
-                               // Local description exists. We need to output both
-                               parent::view();
-                               $out->addHTML( '<div class="mw-shared-image-desc">' . $descText . "</div>\n" );
-                       } else {
-                               // We don't want to output both a "noarticletext" message and the shared
-                               // description, so don't call parent::view().
-                               $out->addHTML( '<div class="mw-shared-image-desc">' . $descText . "</div>\n" );
-                               // Since we did not call parent::view(), have to call some methods it
-                               // normally takes care of. (Not that it matters much since skin not displayed)
-                               $out->setArticleFlag( true );
-                               $out->setPageTitle( $this->getTitle()->getPrefixedText() );
-                               $this->mPage->doViewUpdates( $this->getContext()->getUser() );
-                       }
-               }
+               $this->getContext()->getOutput()->setArticleBodyOnly( true );
+               parent::view();
        }
 
        public function view() {
@@ -209,7 +172,7 @@ class ImagePage extends Article {
                        if ( !$fol->isDisabled() ) {
                                $out->addWikiText( $fol->plain() );
                        }
-                       $out->addHTML( '<div id="shared-image-desc" class="mw-shared-image-desc">' . $this->mExtraDescription . "</div>\n" );
+                       $out->addHTML( '<div id="shared-image-desc">' . $this->mExtraDescription . "</div>\n" );
                }
 
                $this->closeShowImage();
index 7f433bc..df94dcb 100644 (file)
@@ -1181,9 +1181,8 @@ class SkinTemplate extends Skin {
                                'href' => self::makeSpecialUrlSubpage( 'Contributions', $rootUser )
                        );
 
-                       $logPage = SpecialPage::getTitleFor( 'Log' );
                        $nav_urls['log'] = array(
-                               'href' => $logPage->getLocalUrl( array( 'user' => $rootUser ) )
+                               'href' => self::makeSpecialUrlSubpage( 'Log', $rootUser )
                        );
 
                        if ( $this->getUser()->isAllowed( 'block' ) ) {
index 41665bc..16be775 100644 (file)
@@ -61,6 +61,7 @@ class MWTimestamp {
         * The actual timestamp being wrapped. Either a DateTime
         * object or a string with a Unix timestamp depending on
         * PHP.
+        * @var string|DateTime
         */
        private $timestamp;
 
@@ -68,7 +69,7 @@ class MWTimestamp {
         * Make a new timestamp and set it to the specified time,
         * or the current time if unspecified.
         *
-        * @param $timestamp Timestamp to set, or false for current time
+        * @param $timestamp bool|string Timestamp to set, or false for current time
         */
        public function __construct( $timestamp = false ) {
                $this->setTimestamp( $timestamp );
@@ -77,17 +78,17 @@ class MWTimestamp {
        /**
         * Set the timestamp to the specified time, or the current time if unspecified.
         *
-        * Parse the given timestamp into either a DateTime object or a Unix teimstamp,
+        * Parse the given timestamp into either a DateTime object or a Unix timestamp,
         * and then store it.
         *
-        * @param $ts Timestamp to store, or false for now
+        * @param $ts string|bool Timestamp to store, or false for now
+        * @throws TimestampException
         */
        public function setTimestamp( $ts = false ) {
-               $uts = 0;
                $da = array();
                $strtime = '';
 
-               if ( !$ts ) { // We want to catch 0, '', null... but not date strings starting with a letter.
+               if ( !$ts || $ts === "\0\0\0\0\0\0\0\0\0\0\0\0\0\0" ) { // We want to catch 0, '', null... but not date strings starting with a letter.
                        $uts = time();
                        $strtime = "@$uts";
                } elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) {
@@ -98,7 +99,6 @@ class MWTimestamp {
                        # TS_MW
                } elseif ( preg_match( '/^-?\d{1,13}$/D', $ts ) ) {
                        # TS_UNIX
-                       $uts = $ts;
                        $strtime = "@$ts"; // http://php.net/manual/en/datetime.formats.compound.php
                } elseif ( preg_match( '/^\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}.\d{6}$/', $ts ) ) {
                        # TS_ORACLE // session altered to DD-MM-YYYY HH24:MI:SS.FF6
@@ -158,7 +158,8 @@ class MWTimestamp {
         * Convert the internal timestamp to the specified format and then
         * return it.
         *
-        * @param $style Output format for timestamp
+        * @param $style int Constant Output format for timestamp
+        * @throws TimestampException
         * @return string The formatted timestamp
         */
        public function getTimestamp( $style = TS_UNIX ) {
@@ -166,7 +167,7 @@ class MWTimestamp {
                        throw new TimestampException( __METHOD__ . ' : Illegal timestamp output type.' );
                }
 
-               if( is_object( $this->timestamp ) ) {
+               if( is_object( $this->timestamp  ) ) {
                        // DateTime object was used, call DateTime::format.
                        $output = $this->timestamp->format( self::$formats[$style] );
                } elseif( TS_UNIX == $style ) {
@@ -217,6 +218,9 @@ class MWTimestamp {
                }
        }
 
+       /**
+        * @return string
+        */
        public function __toString() {
                return $this->getTimestamp();
        }
index 2a94a65..35febd9 100644 (file)
@@ -761,6 +761,12 @@ class ApiMain extends ApiBase {
                                $this->dieReadOnly();
                        }
                }
+
+               // Allow extensions to stop execution for arbitrary reasons.
+               $message = false;
+               if( !wfRunHooks( 'ApiCheckCanExecute', array( $module, $user, &$message ) ) ) {
+                       $this->dieUsageMsg( $message );
+               }
        }
 
        /**
index 55148b1..9d73562 100644 (file)
@@ -75,6 +75,7 @@ class ApiMove extends ApiBase {
                }
 
                // Move the page
+               $toTitleExists = $toTitle->exists();
                $retval = $fromTitle->moveTo( $toTitle, true, $params['reason'], !$params['noredirect'] );
                if ( $retval !== true ) {
                        $this->dieUsageMsg( reset( $retval ) );
@@ -84,13 +85,20 @@ class ApiMove extends ApiBase {
                if ( !$params['noredirect'] || !$user->isAllowed( 'suppressredirect' ) ) {
                        $r['redirectcreated'] = '';
                }
+               if( $toTitleExists ) {
+                       $r['moveoverredirect'] = '';
+               }
 
                // Move the talk page
                if ( $params['movetalk'] && $fromTalk->exists() && !$fromTitle->isTalkPage() ) {
+                       $toTalkExists = $toTalk->exists();
                        $retval = $fromTalk->moveTo( $toTalk, true, $params['reason'], !$params['noredirect'] );
                        if ( $retval === true ) {
                                $r['talkfrom'] = $fromTalk->getPrefixedText();
                                $r['talkto'] = $toTalk->getPrefixedText();
+                               if( $toTalkExists ) {
+                                       $r['talkmoveoverredirect'] = '';
+                               }
                        } else {
                                // We're not gonna dieUsage() on failure, since we already changed something
                                $parsed = $this->parseMsg( reset( $retval ) );
@@ -231,6 +239,7 @@ class ApiMove extends ApiBase {
                                'to' => 'string',
                                'reason' => 'string',
                                'redirectcreated' => 'boolean',
+                               'moveoverredirect' => 'boolean',
                                'talkfrom' => array(
                                        ApiBase::PROP_TYPE => 'string',
                                        ApiBase::PROP_NULLABLE => true
@@ -239,6 +248,7 @@ class ApiMove extends ApiBase {
                                        ApiBase::PROP_TYPE => 'string',
                                        ApiBase::PROP_NULLABLE => true
                                ),
+                               'talkmoveoverredirect' => 'boolean',
                                'talkmove-error-code' => array(
                                        ApiBase::PROP_TYPE => 'string',
                                        ApiBase::PROP_NULLABLE => true
index 7823e2f..9c932a2 100644 (file)
@@ -111,7 +111,8 @@ class ApiQuery extends ApiBase {
                parent::__construct( $main, $action );
 
                // Allow custom modules to be added in LocalSettings.php
-               global $wgAPIPropModules, $wgAPIListModules, $wgAPIMetaModules;
+               global $wgAPIPropModules, $wgAPIListModules, $wgAPIMetaModules,
+                       $wgMemc, $wgAPICacheHelpTimeout;
                self::appendUserModules( $this->mQueryPropModules, $wgAPIPropModules );
                self::appendUserModules( $this->mQueryListModules, $wgAPIListModules );
                self::appendUserModules( $this->mQueryMetaModules, $wgAPIMetaModules );
@@ -120,8 +121,22 @@ class ApiQuery extends ApiBase {
                $this->mListModuleNames = array_keys( $this->mQueryListModules );
                $this->mMetaModuleNames = array_keys( $this->mQueryMetaModules );
 
+               // Get array of query generators from cache if present
+               $key = wfMemcKey( 'apiquerygenerators', SpecialVersion::getVersion( 'nodb' ) );
+
+               if ( $wgAPICacheHelpTimeout > 0 ) {
+                       $cached = $wgMemc->get( $key );
+                       if ( $cached ) {
+                               $this->mAllowedGenerators = $cached;
+                               return;
+                       }
+               }
                $this->makeGeneratorList( $this->mQueryPropModules );
                $this->makeGeneratorList( $this->mQueryListModules );
+
+               if ( $wgAPICacheHelpTimeout > 0 ) {
+                       $wgMemc->set( $key, $this->mAllowedGenerators, $wgAPICacheHelpTimeout );
+               }
        }
 
        /**
index e59a13b..6b25982 100644 (file)
@@ -1105,17 +1105,27 @@ abstract class FileBackend {
        }
 
        /**
-        * Build a Content-Disposition header value per RFC 6266
+        * Build a Content-Disposition header value per RFC 6266.
         *
         * @param $type string One of (attachment, inline)
         * @param $filename string Suggested file name (should not contain slashes)
         * @return string
         * @since 1.20
         */
-       final public static function makeContentDisposition( $type, $filename ) {
+       final public static function makeContentDisposition( $type, $filename = '' ) {
+               $parts = array();
+
                $type = strtolower( $type );
-               $type = in_array( $type, array( 'inline', 'attachment' ) ) ? $type : 'inline';
-               return "$type; filename*=UTF-8''" . rawurlencode( basename( $filename ) );
+               if ( !in_array( $type, array( 'inline', 'attachment' ) ) ) {
+                       throw new MWException( "Invalid Content-Disposition type '$type'." );
+               }
+               $parts[] = $type;
+
+               if ( strlen( $filename ) ) {
+                       $parts[] = "filename*=UTF-8''" . rawurlencode( basename( $filename ) );
+               }
+
+               return implode( ';', $parts );
        }
 
        /**
index 88727e4..ab86107 100644 (file)
@@ -162,6 +162,24 @@ class SwiftFileBackend extends FileBackendStore {
                return false;
        }
 
+       /**
+        * @param $disposition string Content-Disposition header value
+        * @return string Truncated Content-Disposition header value to meet Swift limits
+        */
+       protected function truncDisp( $disposition ) {
+               $res = '';
+               foreach ( explode( ';', $disposition ) as $part ) {
+                       $part = trim( $part );
+                       $new  = ( $res === '' ) ? $part : "{$res};{$part}";
+                       if ( strlen( $new ) <= 255 ) {
+                               $res = $new;
+                       } else {
+                               break; // too long; sigh
+                       }
+               }
+               return $res;
+       }
+
        /**
         * @see FileBackendStore::doCreateInternal()
         * @return Status
@@ -212,7 +230,7 @@ class SwiftFileBackend extends FileBackendStore {
                        }
                        // Set the Content-Disposition header if requested
                        if ( isset( $params['disposition'] ) ) {
-                               $obj->headers['Content-Disposition'] = $params['disposition'];
+                               $obj->headers['Content-Disposition'] = $this->truncDisp( $params['disposition'] );
                        }
                        if ( !empty( $params['async'] ) ) { // deferred
                                $op = $obj->write_async( $params['content'] );
@@ -302,7 +320,7 @@ class SwiftFileBackend extends FileBackendStore {
                        }
                        // Set the Content-Disposition header if requested
                        if ( isset( $params['disposition'] ) ) {
-                               $obj->headers['Content-Disposition'] = $params['disposition'];
+                               $obj->headers['Content-Disposition'] = $this->truncDisp( $params['disposition'] );
                        }
                        if ( !empty( $params['async'] ) ) { // deferred
                                wfSuppressWarnings();
@@ -392,7 +410,7 @@ class SwiftFileBackend extends FileBackendStore {
                        $dstObj = new CF_Object( $dContObj, $dstRel, false, false ); // skip HEAD
                        $hdrs = array(); // source file headers to override with new values
                        if ( isset( $params['disposition'] ) ) {
-                               $hdrs['Content-Disposition'] = $params['disposition'];
+                               $hdrs['Content-Disposition'] = $this->truncDisp( $params['disposition'] );
                        }
                        if ( !empty( $params['async'] ) ) { // deferred
                                $op = $sContObj->copy_object_to_async( $srcRel, $dContObj, $dstRel, null, $hdrs );
@@ -471,7 +489,7 @@ class SwiftFileBackend extends FileBackendStore {
                        $dstObj = new CF_Object( $dContObj, $dstRel, false, false ); // skip HEAD
                        $hdrs = array(); // source file headers to override with new values
                        if ( isset( $params['disposition'] ) ) {
-                               $hdrs['Content-Disposition'] = $params['disposition'];
+                               $hdrs['Content-Disposition'] = $this->truncDisp( $params['disposition'] );
                        }
                        if ( !empty( $params['async'] ) ) { // deferred
                                $op = $sContObj->move_object_to_async( $srcRel, $dContObj, $dstRel, null, $hdrs );
@@ -1218,6 +1236,19 @@ class SwiftFileBackend extends FileBackendStore {
                return $this->conn;
        }
 
+       /**
+        * Close the connection to the Swift proxy
+        *
+        * @return void
+        */
+       protected function closeConnection() {
+               if ( $this->conn ) {
+                       $this->conn->close(); // close active cURL handles in CF_Http object
+                       $this->sessionStarted = 0;
+                       $this->connContainerCache->clear();
+               }
+       }
+
        /**
         * Get the cache key for a container
         *
@@ -1331,6 +1362,7 @@ class SwiftFileBackend extends FileBackendStore {
                }
                if ( $e instanceof InvalidResponseException ) { // possibly a stale token
                        $this->srvCache->delete( $this->getCredsCacheKey( $this->auth->username ) );
+                       $this->closeConnection(); // force a re-connect and re-auth next time
                }
                wfDebugLog( 'SwiftBackend',
                        get_class( $e ) . " in '{$func}' (given '" . FormatJson::encode( $params ) . "')" .
index 35305d1..6914402 100644 (file)
@@ -100,7 +100,7 @@ class FormatMetadata {
                                ) {
                                        continue;
                                }
-                               $tags[$tag] = intval( $h[0] / $h[1] )
+                               $tags[$tag] = str_pad( intval( $h[0] / $h[1] ), 2, '0', STR_PAD_LEFT )
                                        . ':' . str_pad( intval( $m[0] / $m[1] ), 2, '0', STR_PAD_LEFT )
                                        . ':' . str_pad( intval( $s[0] / $s[1] ), 2, '0', STR_PAD_LEFT );
 
index 8ab0976..7800e56 100644 (file)
@@ -33,7 +33,7 @@ class SpecialLog extends SpecialPage {
        /**
         * List log type for which the target is a user
         * Thus if the given target is in NS_MAIN we can alter it to be an NS_USER
-        * Title user instead. 
+        * Title user instead.
         */
        private $typeOnUser = array(
                'block',
@@ -47,7 +47,7 @@ class SpecialLog extends SpecialPage {
 
        public function execute( $par ) {
                global $wgLogRestrictions;
-               
+
                $this->setHeaders();
                $this->outputHeader();
 
@@ -65,7 +65,7 @@ class SpecialLog extends SpecialPage {
 
                // Set values
                $opts->fetchValuesFromRequest( $this->getRequest() );
-               if ( $par ) {
+               if ( $par !== null ) {
                        $this->parseParams( $opts, (string)$par );
                }
 
index c6f313c..f9ffd92 100644 (file)
@@ -652,7 +652,7 @@ Details stehen im [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}}
 'lineno' => 'Zeiln $1:',
 'compareselectedversions' => 'Gwöde Versionen vagleichen',
 'editundo' => 'ryckgängig',
-'diff-multi' => '({{PLURAL:$1|A dazwischenliegerte Versión|$1 dazwischenliegende Versiónen}} vohram {{PLURAL:$2|Benutzer|$2 Benutzern}} {{PLURAL:$1|werd|wern}} néd åzoagt)',
+'diff-multi' => '({{PLURAL:$1|A dazwischenliegerte Versión|$1 dazwischenliegende Versiónen}} {{PLURAL:$2|vohram Benutzer|vo $2 Benutzern}} {{PLURAL:$1|werd|wern}} néd åzoagt)',
 
 # Search results
 'searchresults' => 'Suachergebniss',
index 6b75f91..229956a 100644 (file)
@@ -1244,7 +1244,7 @@ $1",
 'prefs-emailconfirm-label' => 'پشتڕاست کردنەوەی ئیمەیل:',
 'prefs-textboxsize' => 'قەبارەی پەنجەرەی دەستکاریکردن',
 'youremail' => 'ئیمەیل:',
-'username' => 'ناوی به‌كارهێنه‌ر:',
+'username' => 'ناوی به‌کارھێنەر:',
 'uid' => 'ژمارەی بەکارھێنەر:',
 'prefs-memberingroups' => 'ئەندامی {{PLURAL:$1|گرووپی|گرووپەکانی}}:',
 'prefs-registration' => 'کاتی خۆتۆمارکردن:',
@@ -1285,12 +1285,12 @@ $1",
 
 # User rights
 'userrights' => 'بەڕێوەبردنی مافەکانی بەکارھێنەر',
-'userrights-lookup-user' => 'بەڕێوەبردنی گرووپەکانی بەکارهێنەران',
+'userrights-lookup-user' => 'بەڕێوەبردنی گرووپەکانی بەکارھێنەر',
 'userrights-user-editname' => 'ناوی بەکارهێنەرێک بنووسە:',
-'editusergroup' => 'گرووپەکانی بەکارهێنەر بگۆڕە',
+'editusergroup' => 'گرووپەکانی بەکارھێنەر دەستکاری بکە',
 'editinguser' => "گۆڕینی مافەکانی بەکارهێنەر '''[[User:$1|$1]]''' $2",
-'userrights-editusergroup' => 'دەستکاری کردنی گرووپەکانی بەکارهێنەران',
-'saveusergroups' => 'گرÙ\88Ù\88Ù¾Û\8c Ø¨Û\95کارÙ\87Û\8eÙ\86Û\95راÙ\86 پاشەکەوت بکە',
+'userrights-editusergroup' => 'دەستکاریی گرووپەکانی بەکارهێنەر',
+'saveusergroups' => 'گرÙ\88Ù\88Ù¾Û\95کاÙ\86Û\8c Ø¨Û\95کارھÛ\8eÙ\86Û\95ر پاشەکەوت بکە',
 'userrights-groupsmember' => 'ئەندامە لە:',
 'userrights-groups-help' => 'دەتوانی ئەو گرووپانەی ئەم بەکار‌هێنەرە تێیدایە بگۆڕیت:
 * چوارچێوەی نیشان‌کراو مانای ئەوەیە لەو گرووپەدا هەیە.
@@ -1930,7 +1930,7 @@ $1',
 'newuserlogpagetext' => 'ئەمە لۆگێکی دروستکردنی بەکارھێنەرە.',
 
 # Special:ListGroupRights
-'listgrouprights' => 'Ù\85اÙ\81Û\95کاÙ\86Û\8c Ú¯Ø±Ù\88Ù\88Ù¾Û\95 Ø¨Û\95کارھÛ\8eÙ\86Û\95رÛ\8cÛ\8cÛ\95کاÙ\86',
+'listgrouprights' => 'Ù\85اÙ\81Û\95کاÙ\86Û\8c Ú¯Ø±Ù\88Ù\88Ù¾Û\8c Ø¨Û\95کارھÛ\8eÙ\86Û\95ر',
 'listgrouprights-summary' => 'ئەمە لیستێکە لە گرووپەکانی بەکارهێنەر لەسەر ئەم ویکی‌یە، دەگەڵ مافەکانی دەست‌پێ‌گەیشتنی هاوپەیوەندیان.
 لێرەدا لەوانەیە [[{{MediaWiki:Listgrouprights-helppage}}|زانیاری زیاترت]] دەست‌کەوێت سەبارەت بە مافە تاکەکەسیەکان.',
 'listgrouprights-key' => '* <span class="listgrouprights-granted">مافی دراوە</span>
index 3cca140..3a00011 100644 (file)
@@ -1678,8 +1678,8 @@ Dies kann nicht mehr rückgängig gemacht werden.',
 # User rights log
 'rightslog' => 'Rechte-Logbuch',
 'rightslogtext' => 'Dies ist das Logbuch der Änderungen der Benutzerrechte.',
-'rightslogentry' => 'änderte die Benutzerrechte für „$1“ von „$2“ auf „$3“',
-'rightslogentry-autopromote' => 'wurde automatisch von „$2“ nach „$3“ zugeordnet',
+'rightslogentry' => 'änderte die Benutzerrechte für „$1“ von „$2“ zu „$3“',
+'rightslogentry-autopromote' => 'wurde automatisch von „$2“ zu „$3“ zugeordnet',
 'rightsnone' => '(–)',
 
 # Associated actions - in the sentence "You do not have permission to X"
index a5e6dc4..fd6f09e 100644 (file)
@@ -443,7 +443,7 @@ $messages = array(
 'cancel' => 'Bıterkne',
 'moredotdotdot' => 'Vêşêri...',
 'mypage' => 'Pela mı',
-'mytalk' => 'Werênayışi',
+'mytalk' => 'Werênayışê mı',
 'anontalk' => 'Pela werênayışê nê IPy',
 'navigation' => 'Pusula',
 'and' => '&#32;u',
@@ -470,7 +470,7 @@ $messages = array(
 'vector-view-create' => 'Vıraze',
 'vector-view-edit' => 'Bıvurne',
 'vector-view-history' => 'Tarixi bımocne',
-'vector-view-view' => 'Bıwanên',
+'vector-view-view' => 'Bıwane',
 'vector-view-viewsource' => 'Çımey bıvêne',
 'actions' => 'Kerdeni',
 'namespaces' => 'Cayê namey',
@@ -610,7 +610,7 @@ $1',
 'sort-ascending' => 'Ratnayışê Zeydnayışi',
 
 # Short words for each namespace, by default used in the namespace tab in monobook
-'nstab-main' => 'Pele',
+'nstab-main' => 'Per',
 'nstab-user' => 'Pela Karberi',
 'nstab-media' => 'Pela Medya',
 'nstab-special' => 'Pela xısusiye',
@@ -741,7 +741,7 @@ Hesabê şıma biyo a.
 'userlogin' => 'Cı kewe / hesab vıraze',
 'userloginnocreate' => 'Cı kewe',
 'logout' => 'Veciyayış',
-'userlogout' => 'Bıveciyên',
+'userlogout' => 'Bıveciye',
 'notloggedin' => 'Hesab akerde niyo',
 'nologin' => "Hesabê şıma çıniyo? '''$1'''.",
 'nologinlink' => 'Yew hesab ake',
@@ -904,7 +904,7 @@ Parola vêrdiye: $2',
 'subject' => 'Mewzu/serrêze:',
 'minoredit' => 'Vurnayışo werdı',
 'watchthis' => 'Ena pele seyr ke',
-'savearticle' => 'Peler qeyd ke',
+'savearticle' => 'Pele qeyd ke',
 'preview' => 'Verqayt',
 'showpreview' => 'Verqayti bıvin',
 'showlivepreview' => 'Verqayto cıwın',
@@ -1361,7 +1361,7 @@ Pe verbendi ''all:'', vaceyê xo bıvurni ki contenti hemi cıgeyro (pelanê mı
 
 # Preferences page
 'preferences' => 'Tercihi',
-'mypreferences' => 'Tercihi',
+'mypreferences' => 'Tercihê mı',
 '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ê.',
@@ -2050,7 +2050,7 @@ listeya ke ha ver a têna na {{PLURAL:$1|dosyaya ewwili|dosyaya $1 ewwili}} mocn
 'statistics-header-users' => 'Îstatistiksê karberî',
 'statistics-header-hooks' => 'Îstatistiksê binî',
 'statistics-articles' => 'Pelanê tedesteyî',
-'statistics-pages' => 'Peley',
+'statistics-pages' => 'Peri',
 'statistics-pages-desc' => 'Pelanê hemî ke wîkî de estê, pelanê mineqeşeyî, redireksiyon ucb... dehil o.',
 'statistics-files' => 'Dosyayê bar biye',
 'statistics-edits' => 'Amarê vurnayîşî ke wextê {{SITENAME}} ronayîşî ra',
@@ -2303,7 +2303,7 @@ qey heqê şexsi de [[{{MediaWiki:Listgrouprights-helppage}}|hema malumato ziyed
 
 # Watchlist
 'watchlist' => 'lista mına seyr-kerdışi',
-'mywatchlist' => 'Listey seyrkerdışi',
+'mywatchlist' => 'Lista mına seyrkerdış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.',
@@ -2560,7 +2560,7 @@ $1',
 # Contributions
 'contributions' => 'İştiraqê karberi',
 'contributions-title' => '$1 de iştırakê karberi',
-'mycontris' => 'Pêşteni',
+'mycontris' => 'İştıraqê mı',
 'contribsub2' => 'Qandê $1 ($2)',
 'nocontribs' => 'Ena kriteriya de vurnayîş çini yo.',
 'uctop' => '(ser)',
@@ -2588,7 +2588,7 @@ Cıkewtışo tewr peyêno ke bloke biyo, cêr seba referansi belikerdeyo:',
 # What links here
 'whatlinkshere' => 'Çı tiyay rê gırê beno',
 'whatlinkshere-title' => 'Peleye ke  "$1" re gre biyê',
-'whatlinkshere-page' => 'Pele:',
+'whatlinkshere-page' => 'Per:',
 'linkshere' => "Ena peleyan grey biya '''[[:$1]]''':",
 'nolinkshere' => "Yew pel zi '''[[:$1]]''' rê link nibeno.",
 'nolinkshere-ns' => "Ena cayê nameyî de yew pel zi '''[[:$1]]''' rê link nibeno.",
index f838269..b01b0d9 100644 (file)
@@ -3096,6 +3096,7 @@ Datoj de versioj kaj nomoj de redaktantoj estos preservitaj.
 'pageinfo-title' => 'Informoj por "$1"',
 'pageinfo-header-basic' => 'Baza informo',
 'pageinfo-header-edits' => 'Historio de redaktoj',
+'pageinfo-article-id' => 'Paĝa identigo',
 'pageinfo-robot-index' => 'Indeksebla',
 'pageinfo-robot-noindex' => 'Ne indeksebla',
 'pageinfo-views' => 'Nombro de rigardoj',
index 68e4cfa..75754eb 100644 (file)
@@ -2044,6 +2044,7 @@ Jokaisella rivillä on linkit ensimmäiseen ja toiseen ohjaukseen sekä toisen o
 # Miscellaneous special pages
 'nbytes' => '$1 {{PLURAL:$1|tavu|tavua}}',
 'ncategories' => '$1 {{PLURAL:$1|luokka|luokkaa}}',
+'ninterwikis' => '$1 {{PLURAL:$1|interwiki-linkki|interwiki-linkkiä}}',
 'nlinks' => '$1 {{PLURAL:$1|linkki|linkkiä}}',
 'nmembers' => '$1 {{PLURAL:$1|jäsen|jäsentä}}',
 'nrevisions' => '$1 {{PLURAL:$1|muutos|muutosta}}',
@@ -2072,6 +2073,7 @@ Jokaisella rivillä on linkit ensimmäiseen ja toiseen ohjaukseen sekä toisen o
 'mostlinkedtemplates' => 'Viitatuimmat mallineet',
 'mostcategories' => 'Luokitelluimmat sivut',
 'mostimages' => 'Viitatuimmat tiedostot',
+'mostinterwikis' => 'Sivut joilla on eniten kielilinkkejä',
 'mostrevisions' => 'Muokatuimmat sivut',
 'prefixindex' => 'Kaikki sivut katkaisuhaulla',
 'prefixindex-namespace' => 'Kaikki sivut etuliitteellä (nimiavaruus $1)',
@@ -2218,6 +2220,8 @@ Lisätietoa yksittäisistä käyttäjäoikeuksista saattaa löytyä [[{{MediaWik
 'mailnologin' => 'Lähettäjän osoite puuttuu',
 'mailnologintext' => 'Sinun pitää olla [[Special:UserLogin|kirjautuneena sisään]] ja [[Special:Preferences|asetuksissasi]] pitää olla toimiva ja <strong>varmennettu</strong> sähköpostiosoite, jotta voit lähettää sähköpostia muille käyttäjille.',
 'emailuser' => 'Lähetä sähköpostia tälle käyttäjälle',
+'emailuser-title-target' => 'Lähetä sähköpostia tälle {{GENDER:$1|käyttäjälle}}',
+'emailuser-title-notarget' => 'Lähetä sähköpostia käyttäjälle',
 'emailpage' => 'Lähetä sähköpostia käyttäjälle',
 'emailpagetext' => 'Jos tämä käyttäjä on antanut asetuksissaan kelvollisen sähköpostiosoitteen, alla olevalla lomakkeella voit lähettää hänelle viestin. [[Special:Preferences|Omissa asetuksissasi]] annettu sähköpostiosoite näkyy sähköpostin lähettäjän osoitteena, jotta vastaanottaja voi suoraan vastata viestiin.',
 'usermailererror' => 'Postitus palautti virheen:',
@@ -3007,11 +3011,18 @@ Tallenna tiedot koneellesi ja tuo ne tällä sivulla.',
 
 # Info page
 'pageinfo-title' => 'Tietoja sivusta $1',
-'pageinfo-header-edits' => 'Muokkaukset',
+'pageinfo-header-basic' => 'Perustiedot',
+'pageinfo-header-edits' => 'Muokkaushistoria',
+'pageinfo-header-restrictions' => 'Sivun suojaus',
+'pageinfo-header-properties' => 'Sivun ominaisuudet',
 'pageinfo-views' => 'Katselukertojen määrä',
-'pageinfo-watchers' => 'Tarkkailijoiden lukumäärä',
-'pageinfo-edits' => 'Muokkausten lukumäärä',
-'pageinfo-authors' => 'Eri tekijöiden lukumäärä',
+'pageinfo-watchers' => 'Sivun tarkkailijoiden lukumäärä',
+'pageinfo-redirects-name' => 'Sivulle johtavat ohjaukset',
+'pageinfo-subpages-name' => 'Sivun alasivut',
+'pageinfo-firstuser' => 'Sivun luoja',
+'pageinfo-lastuser' => 'Viimeisin muokkaaja',
+'pageinfo-edits' => 'Muokkausten kokonaismäärä',
+'pageinfo-authors' => 'Sivun eri muokkaajien kokonaismäärä',
 
 # Skin names
 'skinname-standard' => 'Perus',
index 6832d26..03586e4 100644 (file)
@@ -573,12 +573,12 @@ További információkat a [[Special:Version|verzióinformációs lapon]] talál
 
 'ok' => 'OK',
 'retrievedfrom' => 'A lap eredeti címe: „$1”',
-'youhavenewmessages' => 'Új üzenet vár $1! (Az üzenetet $2.)',
-'newmessageslink' => 'a vitalapodon',
-'newmessagesdifflink' => 'külön is megtekintheted',
+'youhavenewmessages' => '$1 a vitalapodon! ($2. külön is megtekintheted)',
+'newmessageslink' => 'új üzenet vár',
+'newmessagesdifflink' => 'az utolsó üzenetet',
 'youhavenewmessagesmanyusers' => '$1ed van több szerkesztőtől ($2).',
-'newmessageslinkplural' => '{{PLURAL:$1|egy|$1}} új üzenet',
-'newmessagesdifflinkplural' => 'utolsó {{PLURAL:$1|egy|$1}} változtatás',
+'newmessageslinkplural' => '{{PLURAL:$1|Új üzenet vár|Új üzenetek várnak}}',
+'newmessagesdifflinkplural' => 'Az utolsó {{PLURAL:$1|változtatást|változtatásokat}}',
 'youhavenewmessagesmulti' => 'Új üzenetet vár a(z) $1 wikin',
 'editsection' => 'szerkesztés',
 'editold' => 'szerkesztés',
index 2308b5c..9393fac 100644 (file)
@@ -294,6 +294,7 @@ $messages = array(
 'index-category' => 'გვერდების ინდექსაცია',
 'noindex-category' => 'არ არსებობს ინდექსირებული გვერდები',
 'broken-file-category' => 'გვერდები ფაილების არასწორი ბმულებით',
+'categoryviewer-pagedlinks' => '($1) ($2)',
 
 'linkprefix' => '/^(.*?)([a-zA-Z\\x80-\\xff]+)$/sD',
 
@@ -1142,6 +1143,7 @@ $1",
 'mergehistory-comment' => 'გადატანა[[:$1]]-ის [[:$2]]-ში: $3',
 'mergehistory-same-destination' => 'თავდაპირველი და სამიზნე გვერდები უნდა განსხვავდებოდეს.',
 'mergehistory-reason' => 'მიზეზი:',
+'mergehistory-revisionrow' => '$1 ($2) $3 . . $4 $5 $6',
 
 # Merge log
 'mergelog' => 'გაერთიანებათა ჟურნალი',
@@ -2169,6 +2171,7 @@ $1',
 # User Messenger
 'usermessage-summary' => 'სისტემური შეტყობინების დატოვება.',
 'usermessage-editor' => 'სისტემური მესენჯერი',
+'usermessage-template' => 'MediaWiki:მომხმარებლის შეტყობინება',
 
 # Watchlist
 'watchlist' => 'ჩემი კონტროლის სია',
@@ -2419,6 +2422,7 @@ $UNWATCHURL
 $1',
 'undelete-show-file-confirm' => 'დარწმუნებული ხართ, რომ გსურთ ფაილ <nowiki>$1</nowiki>-ის წაშლილი ვერსიის ხილვა $2 $3-დან?',
 'undelete-show-file-submit' => 'ჰო',
+'undelete-revisionrow' => '$1 $2 ($3) $4 . . $5 $6 $7',
 
 # Namespace form on various pages
 'namespace' => 'სახელთა სივრცე:',
@@ -2803,6 +2807,7 @@ $1',
 'import-error-invalid' => 'გვერდი "$1" იმპორტირება არ მოხდა მიუღებელი სახელის გამო.',
 'import-options-wrong' => 'არასწორი {{PLURAL:$2|პარამეტრი|პარამეტრი}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'ძირეული გვერდის მითითებული სახელი არასწორია.',
+'import-rootpage-nosubpage' => 'სახელტა სივრცეში მითითებულ ძირეულ გვერდში „$1“ ქვეგვერდები დაუშვებელია.',
 
 # Import log
 'importlogpage' => 'იმპორტის ჟურნალი',
@@ -2942,10 +2947,16 @@ $1',
 'pageinfo-header-edits' => 'რედაქტირების ისტორია',
 'pageinfo-header-restrictions' => 'გვერდის დაცვა',
 'pageinfo-header-properties' => 'გვერდის თვისებები',
+'pageinfo-display-title' => 'ნაჩვენები სათაური',
+'pageinfo-default-sort' => 'სტანდარტული სორტირების გასაღები',
+'pageinfo-length' => 'გვერდის სიგრძე (ბაიტებში)',
 'pageinfo-article-id' => 'გვერდის ID',
 'pageinfo-robot-policy' => 'საძიებო სისტემის სტატუსი',
 'pageinfo-views' => 'ხილვების რაოდენობა',
 'pageinfo-watchers' => 'გვერდის დამკვირვებელთა რაოდენობა',
+'pageinfo-redirects-name' => 'გადამისამართება ამ გვერდზე',
+'pageinfo-redirects-value' => '$1',
+'pageinfo-subpages-name' => 'ამ გვერდის ქვეგვერდები',
 'pageinfo-firstuser' => 'გვერდის შემქნელი',
 'pageinfo-firsttime' => 'გვერდის შექმნის თარიღი',
 'pageinfo-lastuser' => 'ბოლო რედაქტორი',
@@ -3021,6 +3032,8 @@ $1',
 'file-info-png-looped' => 'დარგოლილი',
 'file-info-png-repeat' => 'დაკრულია $1 {{PLURAL:$1|ჯერ}}',
 'file-info-png-frames' => '$1 კადრი',
+'file-no-thumb-animation' => "'''შენიშვნა: ტექნიკური მიზეზების გამო, ამ ფაილის მინიატიურები არ იქნება ანიმირებული.'''",
+'file-no-thumb-animation-gif' => "'''შენიშვნა: ტექნიკური მიზეზების გამო, მაღალი გარჩევადობის GIF ფორმატის სურათების მსგავსი მინიატიურები არ იქნება ანიმირებული.'''",
 
 # Special:NewFiles
 'newimages' => 'ახალი ფაილების გალერეა',
@@ -3613,6 +3626,7 @@ $5
 'ellipsis' => '...',
 'percent' => '$1%',
 'parentheses' => '($1)',
+'brackets' => '[$1]',
 
 # Multipage image navigation
 'imgmultipageprev' => '&larr; წინა გვერდი',
@@ -3643,6 +3657,11 @@ $5
 'size-kilobytes' => '$1 კბ',
 'size-megabytes' => '$1 მბ',
 'size-gigabytes' => '$1 გბ',
+'size-terabytes' => '$1 ტბ',
+'size-petabytes' => '$1 პბ',
+'size-exabytes' => '$1 ებ',
+'size-zetabytes' => '$1 ზბ',
+'size-yottabytes' => '$1 იბ',
 
 # Bitrate units
 'bitrate-bits' => '$1 ბ/წმ',
index dccadb8..b9e2f49 100644 (file)
@@ -15,6 +15,7 @@
  * @author Kumariprity
  * @author Manojberma77
  * @author Meno25
+ * @author Nemo bis
  * @author Priyanka.rachna.jha
  * @author Rajesh
  * @author Reedy
@@ -3532,8 +3533,8 @@ $5
 'logentry-move-move-noredirect' => '$1 {{लिंग:$2|हटाएल}} पन्ना $3 सँ $4 घुमौआकेँ बिना छोड़ने',
 'logentry-move-move_redir' => '$1 {{लिंग:$2|हटाएल}} पन्ना $3 सँ $4 घुमौआक अतिरिक्त',
 'logentry-move-move_redir-noredirect' => '$1 {{लिंग:$2|हटाएल}} पन्ना $3 सँ $4 घुमौआक अतितिक्त घुमौआकेँ बिना छोड़ने',
-'logentry-patrol-patrol' => '$1 {{लिंग:$2|चिन्हित}} संशोधन $4 $3 पन्नाक निरीक्षित',
-'logentry-patrol-patrol-auto' => '$1 स्वतः {{लिंग:$2|चिन्हित}} संशोधन $4 $3 पन्नाक निरीक्षित',
+'logentry-patrol-patrol' => '$1 {{GENDER:$2|चिन्हित}} संशोधन $4 $3 पन्नाक निरीक्षित',
+'logentry-patrol-patrol-auto' => '$1 स्वतः {{GENDER:$2|चिन्हित}} संशोधन $4 $3 पन्नाक निरीक्षित',
 'logentry-newusers-newusers' => '$1 {{लिंग:$2|बनाएल}} एकटा प्रयोक्ता खाता',
 'logentry-newusers-create' => '$1 {{लिंग:$2|बनाएल}} एकटा प्रयोक्ता खाता',
 'logentry-newusers-create2' => '$1 {{लिंग:$2|बनाएल}} {{लिंग:$4|एकटा प्रयोक्ता खाता}} $3',
index fdcfabf..c4e0454 100644 (file)
@@ -17,6 +17,7 @@
  * @author Sukh
  * @author Surinder.wadhawan
  * @author TariButtar
+ * @author Xqt
  * @author Ævar Arnfjörð Bjarmason
  * @author לערי ריינהארט
  */
@@ -1340,7 +1341,7 @@ to upload files.',
 'statistics-users-active-desc' => 'ਮੈਂਬਰ, ਜਿੰਨ੍ਹਾ ਨੇ ਆਖ਼ਰੀ {{PLURAL:$1|ਦਿਨ|$1 ਦਿਨਾਂ}} ਵਿਚ ਕੋਈ ਕੰਮ ਕੀਤਾ ਹੈ।',
 'statistics-mostpopular' => 'ਸਭ ਤੋਂ ਵੱਧ ਵੇਖੇ ਪੇਜ',
 
-'disambiguationspage' => 'ਗੁੰਝਲ ਖੋਲ੍ਹ',
+'disambiguationspage' => 'Template:disambig',
 
 'doubleredirects' => 'ਦੋਹਰੇ ਰੀਡਿਰੈਕਟ',
 
index c745ab9..fac2da2 100644 (file)
@@ -2803,11 +2803,11 @@ A lassa gionté na spiegassion ant ël resumé.",
 
 # Spam protection
 'spamprotectiontitle' => 'Filtror dla rumenta',
-'spamprotectiontext' => "La pàgina che a vorìa salvé a l'é staita blocà dal filtror dla rumenta.
+'spamprotectiontext' => "Ël test che a vorìa salvé a l'é stàit blocà dal filtror dla rumenta.
 Sòn a l'é motobin belfé che a sia rivà përchè a-i era n'anliura a un sit estern ëd coj blocà.",
 'spamprotectionmatch' => "Cost-sì a l'é ël test che a l'é restà ciapà andrinta al filtror dla rumenta: $1",
 'spambot_username' => 'MediaWiki - trigomiro che a-j dà deuit a la rumenta',
-'spam_reverting' => "Buta andaré a l'ùltima version che a l'avèissa pa andrinta dj'anliure a $1",
+'spam_reverting' => "Butà andaré a l'ùltima version che a l'avèissa pa andrinta dj'anliure a $1",
 'spam_blanking' => "Pàgina dësveujdà, che tute le version a l'avìo andrinta dj'anliure a $1",
 'spam_deleting' => 'Tute le revision a contnisìo dle liure a $1, scancelament',
 
index 32e3f51..d49080b 100644 (file)
@@ -417,6 +417,8 @@ $1',
 'youhavenewmessages' => 'تاسې $1 لری  ($2).',
 'newmessageslink' => 'نوي پيغامونه',
 'newmessagesdifflink' => 'وروستی بدلون',
+'newmessageslinkplural' => '{{PLURAL:$1|يو نوی پيغام|نوي پيغامونه}}',
+'newmessagesdifflinkplural' => 'وروستي {{PLURAL:$1|بدلون|بدلونونه}}',
 'youhavenewmessagesmulti' => 'تاسې په $1 کې نوي پېغامونه لرۍ',
 'editsection' => 'سمول',
 'editold' => 'سمول',
@@ -736,11 +738,10 @@ $1',
 'userpage-userdoesnotexist-view' => 'د "$1" ګڼون نه دی ثبت شوی.',
 'blocked-notice-logextract' => 'دم مهال په دې کارن بنديز لګېدلی.
 دلته لاندې د بنديز تازه يادښت د سرچينې په توګه ورکړ شوی:',
-'clearyourcache' => "'''يادونه:''' د غوره توبونو د خوندي کولو وروسته، ددې لپاره چې تاسو خپل سر ته رسولي ونجونه وګورۍ نو پکار ده چې د خپل بروزر ساتل شوې حافظه تازه کړی. 
-* '''Ù\85Ù\88زÛ\90Ù\84ا/ Ù\81اÙ\8aرÙ\81اکس/ Ø³Ù\81رÙ\8a:''' Ù¾Ù\87 Ø¯Û\90 Ú©ØªÙ\86Ù\85Ù\84 Ú©Û\90 Ø¯ ''Reload'' Ø¯ Ù¼Ú©Ù\88Ù\87Ù\84Ù\88 Ù¾Ù\87 Ù\88خت Ø¯ ''Shift'' ØªÚ¼Û\8d Ù\86Ù\8aÙ\88Ù\84Û\90 Ù\88ساتÛ\8cØ\8c Ø§Ù\88 Ù\8aا Ù\87Ù\85 ''Ctrl-F5'' Ù\8aا ''Ctrl-R'' تڼۍ کېښکاږۍ (په Apple Mac کمپيوټر باندې ''⌘-R'' کېښکاږۍ)
+'clearyourcache' => "'''يادښت:''' د غوره توبونو د خوندي کولو وروسته، خپل د کتنمل (بروزر) ساتل شوې حافظه تازه کړی.
+* '''Ù\81اÙ\8aرÙ\81اکس/ Ø³Ù\81رÙ\8a:''' Ù¾Ù\87 Ø¯Û\90 Ú©ØªÙ\86Ù\85Ù\84 Ú©Û\90 Ø¯ ''Reload'' Ø¯ Ù¼Ú©Ù\88Ù\87Ù\84Ù\88 Ù¾Ù\87 Ù\88خت Ø¯ ''Shift'' ØªÚ¼Û\8d Ù\86Ù\8aÙ\88Ù\84Û\90 Ù\88ساتÛ\8cØ\8c Ø§Ù\88 Ù\8aا Ù\87Ù\85 ''Ctrl-F5'' Ù\8aا ''Ctrl-R''تڼۍ کېښکاږۍ (په Apple Mac کمپيوټر باندې ''⌘-R'' کېښکاږۍ)
 * '''ګووګل کروم:''' په دې کتنمل کې د ''Ctrl-Shift-R'' تڼۍ کېښکاږۍ (د مک لپاره ''⌘-Shift-R'')
 * '''انټرنټ اېکسپلورر:''' په دې کتنمل کې د ''Refresh'' د ټکوهلو په وخت کې د ''Ctrl'' تڼۍ کېښکاږلې ونيسۍ، او يا هم د ''Ctrl-F5'' تڼۍ کېښکاږۍ
-* '''کانکوېرور:''' په دې کتنمل کې د يواځې د ''Reload'' تڼۍ ټکوهۍ، او يا ''F5'' کېښکاږۍ
 * '''اوپرا''': په دې کتنمل کې د خپل براوزر ساتل شوې حافظه پدې توګه سپينولی شی ''Tools→Preferences''",
 'usercsspreview' => "'''هېر مو نشي چې دا يوازې ستاسې د کارن CSS مخليدنه ده.'''
 '''تر اوسه پورې لا ستاسې بدلونونه نه دي خوندي شوي!'''",
@@ -1008,6 +1009,7 @@ $1',
 'resultsperpage' => 'په هر مخ کې د پايلو شمېر:',
 'stub-threshold-disabled' => 'ناچارن',
 'recentchangesdays' => 'د هغو ورځو شمېر وټاکی چې په وروستي بدلونو کې يې ليدل غواړی:',
+'recentchangesdays-max' => 'حد اکثر $1 {{PLURAL:$1|ورځ|ورځې}}',
 'recentchangescount' => 'د هغو سمونو شمېر چې په تلواليزه بڼه ښکاره بايد شي:',
 'prefs-help-recentchangescount' => 'پدې کې د وروستني بدلونونو، د مخونو د پېښليکونو او يادښتونه شامل دي.',
 'savedprefs' => 'ستاسو غوره توبونه خوندي شوه.',
@@ -1266,6 +1268,7 @@ $1',
 که تاسې بيا هم د خپلې دوتنې پورته کول غواړۍ، نو لطفاً بېرته وګرځۍ او همدغه دوتنه بيا په يوه نوي نوم پورته کړی.
 [[File:$1|thumb|center|$1]]',
 'file-exists-duplicate' => 'همدا دوتنه د {{PLURAL:$1|لاندينۍ دوتنې|لاندينيو دوتنو}} غبرګه لمېسه ده:',
+'uploadwarning' => 'د پورته کولو ګواښ',
 'savefile' => 'دوتنه خوندي کړه',
 'uploadedimage' => '"[[$1]]" پورته شوه',
 'uploaddisabled' => 'پورته کول ناچارن شوي',
@@ -1280,6 +1283,7 @@ $1',
 'watchthisupload' => 'همدا دوتنه کتل',
 'upload-success-subj' => 'دوتنه پورته کېدل په برياليتوب سره ترسره شو',
 'upload-failure-subj' => 'د پورته کېدو ستونزه',
+'upload-warning-subj' => 'د پورته کولو ګواښ',
 
 'upload-file-error' => 'کورنۍ ستونزه',
 'upload-unknown-size' => 'ناڅرګنده کچه',
@@ -1508,6 +1512,7 @@ $1',
 'allpagesprefix' => 'هغه مخونه ښکاره کړه چې مختاړی يې وي:',
 'allpagesbadtitle' => 'ورکړ شوی سرليک سم نه دی او يا هم د ژبو او يا د بېلابېلو ويکي ګانو مختاړی لري. ستاسو په سرليک کې يو يا څو داسې ابېڅې دي کوم چې په سرليک کې نه شي کارېدلی.',
 'allpages-bad-ns' => '{{SITENAME}} د "$1" په نامه هېڅ کوم نوم-تشيال نه لري.',
+'allpages-hide-redirects' => 'مخ ګرځونې پټول',
 
 # Special:Categories
 'categories' => 'وېشنيزې',
@@ -1540,6 +1545,7 @@ $1',
 'activeusers' => 'د فعالو کارنانو لړليک',
 'activeusers-count' => 'په {{PLURAL:$2|تېرې|تېرو}} {{PLURAL:$3|ورځ|$3 ورځو}} کې $1 {{PLURAL:$1|سمون|سمونونه}}',
 'activeusers-from' => 'هغه کارنان کتل چې نومونه يې پېلېږي په:',
+'activeusers-hidebots' => 'روباټونه پټول',
 'activeusers-hidesysops' => 'پازوالان پټول',
 'activeusers-noresult' => 'کارن و نه موندل شو.',
 
@@ -1565,6 +1571,8 @@ $1',
 # E-mail user
 'mailnologin' => 'هېڅ کومه لېږل شوې پته نشته',
 'emailuser' => 'کارن ته برېښليک لېږل',
+'emailuser-title-target' => 'دې {{GENDER:$1|کارن}} ته برېښليک لېږل',
+'emailuser-title-notarget' => 'کارن ته برېښليک لېږل',
 'emailpage' => 'کارن ته برېښليک لېږل',
 'defemailsubject' => 'د "$1" کارن لخوا د {{SITENAME}} برېښليک',
 'usermaildisabled' => 'د کارن برېښليک ناچارند دی',
@@ -2066,10 +2074,10 @@ $UNWATCHURL  نه ليدنه وکړۍ
 
 # Info page
 'pageinfo-title' => 'د "$1" مالومات',
-'pageinfo-header-edits' => 'سÙ\85Ù\88Ù\86Ù\88Ù\86Ù\87',
+'pageinfo-header-edits' => 'د Ø³Ù\85Ù\88Ù\86 Ù¾Û\90Ú\9aÙ\84Ù\8aÚ©',
 'pageinfo-views' => 'د کتنو شمېر',
-'pageinfo-watchers' => 'د کتونکو شمېر',
-'pageinfo-edits' => 'د سمونونو شمېر',
+'pageinfo-watchers' => 'د مخ د کتونکو شمېر',
+'pageinfo-edits' => 'د ټولو سمونونو شمېر',
 
 # Skin names
 'skinname-standard' => 'کلاسيک',
@@ -2080,6 +2088,7 @@ $UNWATCHURL  نه ليدنه وکړۍ
 'skinname-chick' => 'شيک',
 'skinname-simple' => 'ساده',
 'skinname-modern' => 'نوی',
+'skinname-vector' => 'وېکټور',
 
 # Patrolling
 'markaspatrolledtext' => 'دا مخ څارل شوی په نخښه کول',
@@ -2366,6 +2375,11 @@ $5
 'confirm-watch-button' => 'ښه',
 'confirm-unwatch-button' => 'ښه',
 
+# Separators for various lists, etc.
+'percent' => '$1%',
+'parentheses' => '($1)',
+'brackets' => '[$1]',
+
 # Multipage image navigation
 'imgmultipageprev' => '← پخوانی مخ',
 'imgmultipagenext' => 'راتلونکی مخ →',
@@ -2390,6 +2404,17 @@ $5
 'autoredircomment' => '[[$1]] ته وګرځولی شو',
 'autosumm-new' => 'د "$1" تورو مخ جوړ شو',
 
+# Size units
+'size-bytes' => '$1 بايټ',
+'size-kilobytes' => '$1 کيلوبايټ',
+'size-megabytes' => '$1 مېګابايټ',
+'size-gigabytes' => '$1 ګېګابايټ',
+'size-terabytes' => '$1 ټېرابايټ',
+'size-petabytes' => '$1 پېبي بايټ',
+'size-exabytes' => '$1 اېکسبي بايټ',
+'size-zetabytes' => '$1 زېبي بايټ',
+'size-yottabytes' => '$1 يوبي بايټ',
+
 # Live preview
 'livepreview-loading' => 'برسېرېدنې کې دی...',
 'livepreview-ready' => 'برسېرېدنه ... چمتو ده!',
@@ -2427,6 +2452,28 @@ $5
 'iranian-calendar-m11' => 'سلواغه',
 'iranian-calendar-m12' => 'کب',
 
+# Hijri month names
+'hijri-calendar-m1' => 'محرم',
+'hijri-calendar-m2' => 'صفر',
+'hijri-calendar-m3' => 'ربيع الاول',
+'hijri-calendar-m4' => 'ربيع الثاني',
+'hijri-calendar-m5' => 'جمادى الاولى',
+'hijri-calendar-m6' => 'جمادى الثانية',
+'hijri-calendar-m7' => 'رجب',
+'hijri-calendar-m8' => 'شعبان',
+'hijri-calendar-m9' => 'رمضان',
+'hijri-calendar-m10' => 'شوال',
+'hijri-calendar-m11' => 'ذو القعدة',
+'hijri-calendar-m12' => 'ذو الحجة',
+
+# Hebrew month names
+'hebrew-calendar-m1' => 'تيشري',
+'hebrew-calendar-m2' => 'حشوان',
+'hebrew-calendar-m3' => 'كيسليف',
+'hebrew-calendar-m4' => 'تيفيت',
+'hebrew-calendar-m5' => 'شيفات',
+'hebrew-calendar-m6' => 'آدار',
+
 # Signatures
 'signature' => '[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|خبرې اترې]])',
 
index 3c0cb81..01d7c01 100644 (file)
@@ -26,6 +26,7 @@
  * @author Brest
  * @author BrokenArrow
  * @author Byrial
+ * @author BáthoryPéter
  * @author Claudia Hattitten
  * @author Codex Sinaiticus
  * @author Crt
@@ -544,7 +545,7 @@ Do '''not''' replace SITENAME with a translation of Wikipedia or some encycopedi
 Appears in subtitle
 * $1 is a link to the page (HTML)',
 'retrievedfrom' => 'Message which appears in the source of every page, but it is hidden. It is shown when printing. $1 is a link back to the current page: {{FULLURL:{{FULLPAGENAME}}}}.',
-'youhavenewmessages' => 'The blue message appearing when someone edited your user talk page.
+'youhavenewmessages' => 'The yellow message appearing when someone edited your user talk page.
 The format is: "{{int:youhavenewmessages| [[MediaWiki:Newmessageslink/{{SUBPAGENAME}}|{{int:newmessageslink}}]] |[[MediaWiki:Newmessagesdifflink/{{SUBPAGENAME}}|{{int:newmessagesdifflink}}]]}}"',
 'newmessageslink' => 'This is the first link displayed in an orange rectangle when a user gets a message on his talk page. Used in message {{msg-mw|youhavenewmessages}} (as parameter $1).
 
index 8b704d3..e8e584b 100644 (file)
@@ -1260,7 +1260,7 @@ $1",
 'group-autoconfirmed-member' => '{{GENDER:$1|தானாக உறுதிசெய்யப்பட்ட பயனர்}}',
 'group-bot-member' => '{{GENDER:$1|தானியங்கி}}',
 'group-sysop-member' => '{{GENDER:$1|நிர்வாகி}}',
-'group-bureaucrat-member' => '{{GENDER:$1|பà®\9fிபà¯\8dபாளரà¯\8dகள்}}',
+'group-bureaucrat-member' => '{{GENDER:$1|à®\85திà®\95ாரிகள்}}',
 'group-suppress-member' => '{{GENDER:$1|மேற்பார்வை}}',
 
 'grouppage-user' => '{{ns:project}}:பயனர்கள்',
index e0a3c00..c88272d 100644 (file)
 /**
  * Live preview script for MediaWiki
  */
-(function( $ ) {
-       window.doLivePreview = function( e ) {
-               var previewShowing = false;
-
+( function( mw, $ ) {
+       var doLivePreview = function( e ) {
                e.preventDefault();
 
                $( mw ).trigger( 'LivePreviewPrepare' );
 
                var $wikiPreview = $( '#wikiPreview' );
 
-               $( '#mw-content-text' ).css( 'position', 'relative' );
-
-               if ( $wikiPreview.is( ':visible' ) ) {
-                       previewShowing = true;
+               // this needs to be checked before we unconditionally show the preview
+               var overlaySpinner = false;
+               if ( $wikiPreview.is( ':visible' ) || $( '.mw-newarticletext:visible' ).length > 0 ) {
+                       overlaySpinner = true;
                }
 
-               // show #wikiPreview if it's hidden (if it is hidden, it's also empty, so nothing changes in the rendering)
-               // to be able to scroll to it
+               // show #wikiPreview if it's hidden to be able to scroll to it
+               // (if it is hidden, it's also empty, so nothing changes in the rendering)
                $wikiPreview.show();
-
-               // Jump to where the preview will appear
+               // jump to where the preview will appear
                $wikiPreview[0].scrollIntoView();
 
-               var postData = $('#editform').formToArray(); // formToArray: from jquery.form
-               postData.push( { 'name' : e.target.name, 'value' : '1' } );
-
-               // Hide active diff, used templates, old preview if shown
-               var copyElements = ['#wikiPreview', '#wikiDiff', '.templatesUsed', '.hiddencats',
-                                                       '#catlinks', '#p-lang', '.mw-summary-preview'];
-               var copySelector = copyElements.join(',');
+               // list of elements that will be loaded from the preview page
+               // elements absent in the preview page (such as .mw-newarticletext) will be cleared using .empty()
+               var copySelectors = [
+                       '#wikiPreview', '#wikiDiff', '#catlinks', '.hiddencats', '#p-lang', // the meat
+                       '.templatesUsed', '.mw-summary-preview', // editing-related
+                       '.mw-newarticletext' // it is not shown during normal preview, and looks weird with throbber overlaid
+               ];
+               var $copyElements = $( copySelectors.join( ',' ) );
 
-               $.each( copyElements, function( k, v ) {
-                       $( v ).fadeTo( 'fast', 0.4 );
-               } );
+               var $loadSpinner = $( '<div>' ).addClass( 'mw-ajax-loader' );
+               $loadSpinner.css( 'top', '0' ); // move away from header (default is -16px)
 
-               // Display a loading graphic
-               var loadSpinner = $('<div class="mw-ajax-loader"/>');
-               // Move away from header (default is -16px)
-               loadSpinner.css( 'top', '0' );
+               // If the preview is already visible, overlay the spinner on top of it.
+               if ( overlaySpinner ) {
+                       $( '#mw-content-text' ).css( 'position', 'relative' ); // FIXME this seems like a bad idea
 
-               // If the preview is already showing, overlay the spinner on top of it.
-               if ( previewShowing ) {
-                       loadSpinner.css( {
+                       $loadSpinner.css( {
                                'position': 'absolute',
                                'z-index': '3',
                                'left': '50%',
                                'margin-left': '-16px'
                        } );
                }
-               $wikiPreview.before( loadSpinner );
 
-               var page = $('<div/>');
-               var target = $('#editform').attr('action');
+               // fade out the elements and display the throbber
+               $( '#mw-content-text' ).prepend( $loadSpinner );
+               // we can't use fadeTo because it calls show(), and we might want to keep some elements hidden
+               // (e.g. empty #catlinks)
+               $copyElements.animate( { 'opacity': 0.4 }, 'fast' );
 
-               if ( !target ) {
-                       target = window.location.href;
-               }
+               var $previewDataHolder = $( '<div>' );
+               var target = $( '#editform' ).attr( 'action' ) || window.location.href;
 
-               page.load( target + ' ' + copySelector, postData,
-                       function() {
-
-                               for( var i=0; i<copyElements.length; ++i) {
-                                       // For all the specified elements, find the elements in the loaded page
-                                       //  and the real page, empty the element in the real page, and fill it
-                                       //  with the content of the loaded page
-                                       var copyContent = page.find( copyElements[i] ).contents();
-                                       $(copyElements[i]).empty().append( copyContent );
-                                       var newClasses = page.find( copyElements[i] ).prop('class');
-                                       $(copyElements[i]).prop( 'class', newClasses );
-                               }
-
-                               $.each( copyElements, function( k, v ) {
-                                       // Don't belligerently show elements that are supposed to be hidden
-                                       $( v ).fadeTo( 'fast', 1, function() {
-                                               $( this ).css( 'display', '' );
-                                       } );
-                               } );
-
-                               loadSpinner.remove();
-
-                               $( mw ).trigger( 'LivePreviewDone', [copyElements] );
-                       } );
+               // gather all the data from the form
+               var postData = $( '#editform' ).formToArray(); // formToArray: from jquery.form
+               postData.push( { 'name' : e.target.name, 'value' : '1' } );
+
+               // load new preview data
+               // FIXME this should use the action=parse API instead of loading the entire page
+               $previewDataHolder.load( target + ' ' + copySelectors.join( ',' ), postData, function() {
+                       // Copy the contents of the specified elements from the loaded page to the real page.
+                       // Also copy their class attributes.
+                       for ( var i = 0; i < copySelectors.length; i++ ) {
+                               var $from = $previewDataHolder.find( copySelectors[i] );
+                               var $to = $( copySelectors[i] );
+
+                               $to.empty().append( $from.contents() );
+                               $to.attr( 'class', $from.attr( 'class' ) );
+                       }
+
+                       $loadSpinner.remove();
+                       $copyElements.animate( { 'opacity': 1 }, 'fast' );
+
+                       $( mw ).trigger( 'LivePreviewDone', [copySelectors] );
+               } );
        };
 
-       $(document).ready( function() {
-               // construct space for interwiki links if missing
-               // (it is usually not shown when action=edit, but shown if action=submit)
+       $( document ).ready( function() {
+               // construct the elements we need if they are missing (usually when action=edit)
+               // we don't need to hide them, because they are empty when created
+
+               // interwiki links
                if ( !document.getElementById( 'p-lang' ) && document.getElementById( 'p-tb' ) ) {
-                       // we need not hide this, because it's empty anyway
                        $( '#p-tb' ).after( $( '<div>' ).attr( 'id', 'p-lang' ) );
                }
 
-               // construct space for summary preview if missing
+               // summary preview
                if ( $( '.mw-summary-preview' ).length === 0 ) {
                        $( '.editCheckboxes' ).before( $( '<div>' ).addClass( 'mw-summary-preview' ) );
                }
 
-               // construct space for diff if missing. also load diff styles.
+               // diff
                if ( !document.getElementById( 'wikiDiff' ) && document.getElementById( 'wikiPreview' ) ) {
                        $( '#wikiPreview' ).after( $( '<div>' ).attr( 'id', 'wikiDiff' ) );
-                       // diff styles are by default only loaded when needed
-                       // if there was no diff container, we can expect the styles not to be there either
-                       mw.loader.load( 'mediawiki.action.history.diff' );
                }
 
+               // diff styles are usually only loaded during, well, diff, and we might need them
+               // (mw.loader takes care of stuff if they happen to be loaded already)
+               mw.loader.load( 'mediawiki.action.history.diff' );
+
                $( '#wpPreview, #wpDiff' ).click( doLivePreview );
        } );
-}) ( jQuery );
+} )( mediaWiki, jQuery );