Merge "Fixes Algerian messages file so it does not convert to Arabic digits."
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 7 Aug 2014 08:52:02 +0000 (08:52 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 7 Aug 2014 08:52:02 +0000 (08:52 +0000)
79 files changed:
RELEASE-NOTES-1.24
docs/kss/Makefile
docs/kss/scripts/kss-node-check.sh [new file with mode: 0755]
docs/kss/scripts/nodecheck.sh [deleted file]
includes/AutoLoader.php
includes/DefaultSettings.php
includes/Message.php
includes/Setup.php
includes/SkinFallback.php [new file with mode: 0644]
includes/actions/ProtectAction.php
includes/actions/UnprotectAction.php [new file with mode: 0644]
includes/actions/UnwatchAction.php [new file with mode: 0644]
includes/actions/WatchAction.php
includes/api/ApiModuleManager.php
includes/api/ApiQueryAllUsers.php
includes/api/ApiUndelete.php
includes/cache/LocalisationCache.php
includes/installer/i18n/bto.json
includes/installer/i18n/da.json
includes/specials/SpecialActiveusers.php
includes/specials/SpecialProtectedtitles.php
includes/specials/SpecialRandomInCategory.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialSearch.php
includes/specials/SpecialSpecialpages.php
includes/specials/SpecialStatistics.php
includes/specials/SpecialTrackingCategories.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialUnlockdb.php
includes/specials/SpecialUnusedimages.php
includes/specials/SpecialUploadStash.php
includes/specials/SpecialUserrights.php
includes/specials/SpecialWantedpages.php
includes/specials/SpecialWatchlist.php
includes/specials/SpecialWhatlinkshere.php
includes/specials/SpecialWithoutinterwiki.php
languages/i18n/be-tarask.json
languages/i18n/ce.json
languages/i18n/da.json
languages/i18n/de.json
languages/i18n/egl.json
languages/i18n/en.json
languages/i18n/es.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/he.json
languages/i18n/hif-latn.json
languages/i18n/hu.json
languages/i18n/lb.json
languages/i18n/lrc.json
languages/i18n/mk.json
languages/i18n/pl.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ro.json
languages/i18n/ru.json
languages/i18n/sl.json
languages/i18n/sv.json
languages/i18n/tr.json
languages/i18n/uk.json
languages/i18n/wuu.json
languages/i18n/zh-hans.json
maintenance/undelete.php
resources/lib/oojs-ui/i18n/zh-hans.json
resources/lib/oojs-ui/oojs-ui-agora.css
resources/lib/oojs-ui/oojs-ui-apex.css
resources/lib/oojs-ui/oojs-ui.js
resources/lib/oojs-ui/oojs-ui.svg.css
resources/src/mediawiki.ui/components/inputs.less
resources/src/mediawiki/mediawiki.notification.js
resources/src/startup.js
skins/common/IEFixes.js [deleted file]
skins/common/wikibits.js
tests/phpunit/includes/MessageTest.php
tests/phpunit/includes/api/ApiModuleManagerTest.php [new file with mode: 0644]
tests/phpunit/includes/api/PrefixUniquenessTest.php
tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js
tests/qunit/suites/resources/startup.test.js

index ec4bc0f..92b34c6 100644 (file)
@@ -45,6 +45,8 @@ production.
 * The UserCryptPassword and UserComparePassword hooks are no longer called. Any extensions
   using them must be updated to use the Password Hashing API.
 * $wgCompiledFiles has been removed.
+* $wgSortSpecialPages was removed, the listing on Special:SpecialPages is
+  now always sorted.
 
 === New features in 1.24 ===
 * Added a new hook, "WhatLinksHereProps", to allow extensions to annotate
@@ -196,6 +198,14 @@ production.
 * (bug 60734) Actions that use ApiPageSet (e.g. purge, watch,
   setnotificationtimestamp) will now include continuation information when
   using a generator.
+* $wgAPIModules (and the related $wgAPIFormatModules, $wgAPIMetaModules,
+  $wgAPIPropModules, and $wgAPIListModules settings) now allow API modules
+  to be specified using a "module spec" array instead of a plain class name.
+  A "module spec" is an associative array containing at least the 'class' key
+  for the module's class, and optionally a 'factory' key for the factory function
+  to use for the module. This is intended for extensions that want control over
+  the instantiation of their API modules, to allow for proper dependency
+  injection.
 
 === Languages updated in 1.24 ===
 
@@ -291,6 +301,10 @@ changes to languages because of Bugzilla reports.
   setPreloadedText() from EditPage.php. (deprecated since 1.21)
 * Removed global functions wfArrayLookup(), wfArrayMerge(), wfDebugDieBacktrace()
   and wfTime(). (deprecated since 1.22)
+* Microsoft Internet Explorer 6 is now a "grade C" browser, meaning that
+  JavaScript is no longer executed in this browser. The IEFixes script, which
+  existed purely to provide support for MSIE versions below 7 and which was
+  conditionally loaded for those browsers, was also removed.
 
 ==== Renamed classes ====
 * CLDRPluralRuleConverter_Expression to CLDRPluralRuleConverterExpression
index 7d2ee3b..ff735d5 100644 (file)
@@ -1,8 +1,6 @@
 MEDIAWIKI_LOAD_URL ?= http://localhost/w/load.php
 
-kss: nodecheck
-# FIXME: Use more up-to-date Ruby version
-
+kss: kssnodecheck
 # Generates CSS of mediawiki.ui and mediawiki.ui.button using ResourceLoader, then applies it to the
 # KSS style guide
        $(eval KSS_RL_TMP := $(shell mktemp /tmp/tmp.XXXXXXXXXX))
@@ -15,5 +13,5 @@ kssopen: kss
        @command -v xdg-open >/dev/null 2>&1 || { open ${PWD}/static/index.html; exit 0; }
        @xdg-open ${PWD}/static/index.html
 
-nodecheck:
-       @scripts/nodecheck.sh
+kssnodecheck:
+       @scripts/kss-node-check.sh
diff --git a/docs/kss/scripts/kss-node-check.sh b/docs/kss/scripts/kss-node-check.sh
new file mode 100755 (executable)
index 0000000..84ee1c4
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+if command -v npm > /dev/null ; then
+  npm install
+else
+  # If npm isn't installed, but kss-node is, exit normally.
+  # This allows setting it up on one machine, and running it on
+  # another (e.g. Tools Labs execution nodes) that doesn't have npm
+  # installed.  However, "npm install" still needs to be run
+  # occasionally to keep kss updated.
+
+  KSS_NODE="${BASH_SOURCE%/*}/../node_modules/.bin/kss-node"
+  if ! [ -x "$KSS_NODE" ] ; then
+    echo "Neither kss-node nor npm are installed."
+    echo "To install npm, see http://nodejs.org/"
+    echo "When npm is installed, the Makefile can automatically"
+    echo "install kss-node."
+    exit 1
+  fi
+fi
diff --git a/docs/kss/scripts/nodecheck.sh b/docs/kss/scripts/nodecheck.sh
deleted file mode 100755 (executable)
index 3ee0f83..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env bash
-if command -v npm > /dev/null ; then
-  npm install
-else
-  echo "You need to install Node.JS!"
-  echo "See http://nodejs.org/"
-  exit 1
-fi
index 9fa0c13..b84feb2 100644 (file)
@@ -158,6 +158,8 @@ $wgAutoloadLocalClasses = array(
        'SiteStatsInit' => 'includes/SiteStats.php',
        'Skin' => 'includes/Skin.php',
        'SkinTemplate' => 'includes/SkinTemplate.php',
+       'SkinFallback' => 'includes/SkinFallback.php',
+       'SkinFallbackTemplate' => 'includes/SkinFallback.php',
        'SquidPurgeClient' => 'includes/SquidPurgeClient.php',
        'SquidPurgeClientPool' => 'includes/SquidPurgeClient.php',
        'StatCounter' => 'includes/StatCounter.php',
@@ -214,8 +216,8 @@ $wgAutoloadLocalClasses = array(
        'RevisiondeleteAction' => 'includes/actions/RevisiondeleteAction.php',
        'RollbackAction' => 'includes/actions/RollbackAction.php',
        'SubmitAction' => 'includes/actions/EditAction.php',
-       'UnprotectAction' => 'includes/actions/ProtectAction.php',
-       'UnwatchAction' => 'includes/actions/WatchAction.php',
+       'UnprotectAction' => 'includes/actions/UnprotectAction.php',
+       'UnwatchAction' => 'includes/actions/UnwatchAction.php',
        'ViewAction' => 'includes/actions/ViewAction.php',
        'WatchAction' => 'includes/actions/WatchAction.php',
 
index cf6a95d..48e7d98 100644 (file)
@@ -2968,7 +2968,7 @@ $wgDefaultSkin = 'vector';
  *
  * @since 1.24
  */
-$wgFallbackSkin = 'vector';
+$wgFallbackSkin = 'fallback';
 
 /**
  * Specify the names of skins that should not be presented in the list of
@@ -6672,11 +6672,6 @@ $wgDisableQueryPageUpdate = false;
  */
 $wgSpecialPageGroups = array();
 
-/**
- * Whether or not to sort special pages in Special:Specialpages
- */
-$wgSortSpecialPages = true;
-
 /**
  * On Special:Unusedimages, consider images "used", if they are put
  * into a category. Default (false) is not to count those as used.
@@ -6841,16 +6836,45 @@ $wgDebugAPI = false;
 
 /**
  * API module extensions.
- * Associative array mapping module name to class name.
- * Extension modules may override the core modules.
  *
+ * Associative array mapping module name to modules specs;
+ * Each module spec is an associative array containing at least
+ * the 'class' key for the module's class, and optionally a
+ * 'factory' key for the factory function to use for the module.
+ *
+ * That factory function will be called with two parameters,
+ * the parent module (an instance of ApiBase, usually ApiMain)
+ * and the name the module was registered under. The return
+ * value must be an instance of the class given in the 'class'
+ * field.
+ *
+ * For backward compatibility, the module spec may also be a
+ * simple string containing the module's class name. In that
+ * case, the class' constructor will be called with the parent
+ * module and module name as parameters, as described above.
+ *
+ * Examples for registering API modules:
+ *
+ * @code
+ *  $wgAPIModules['foo'] = 'ApiFoo';
+ *  $wgAPIModules['bar'] = array(
+ *    'class' => 'ApiBar',
+ *    'factory' => function( $main, $name ) { ... }
+ *  );
+ *  $wgAPIModules['xyzzy'] = array(
+ *    'class' => 'ApiXyzzy',
+ *    'factory' => array( 'XyzzyFactory', 'newApiModule' )
+ *  );
+ * @endcode
+ *
+ * Extension modules may override the core modules.
  * See ApiMain::$Modules for a list of the core modules.
  */
 $wgAPIModules = array();
 
 /**
  * API format module extensions.
- * Associative array mapping format module name to class name.
+ * Associative array mapping format module name to module specs (see $wgAPIModules).
  * Extension modules may override the core modules.
  *
  * See ApiMain::$Formats for a list of the core format modules.
@@ -6859,7 +6883,7 @@ $wgAPIFormatModules = array();
 
 /**
  * API Query meta module extensions.
- * Associative array mapping meta module name to class name.
+ * Associative array mapping meta module name to module specs (see $wgAPIModules).
  * Extension modules may override the core modules.
  *
  * See ApiQuery::$QueryMetaModules for a list of the core meta modules.
@@ -6868,7 +6892,7 @@ $wgAPIMetaModules = array();
 
 /**
  * API Query prop module extensions.
- * Associative array mapping properties module name to class name.
+ * Associative array mapping prop module name to module specs (see $wgAPIModules).
  * Extension modules may override the core modules.
  *
  * See ApiQuery::$QueryPropModules for a list of the core prop modules.
@@ -6877,7 +6901,7 @@ $wgAPIPropModules = array();
 
 /**
  * API Query list module extensions.
- * Associative array mapping list module name to class name.
+ * Associative array mapping list module name to module specs (see $wgAPIModules).
  * Extension modules may override the core modules.
  *
  * See ApiQuery::$QueryListModules for a list of the core list modules.
index 931a3f9..4df0d80 100644 (file)
@@ -175,10 +175,16 @@ class Message {
        protected $language = null;
 
        /**
-        * @var string|string[] The message key or array of keys.
+        * @var string The message key. If $keysToTry has more than one element,
+        * this may change to one of the keys to try when fetching the message text.
         */
        protected $key;
 
+       /**
+        * @var string[] List of keys to try when fetching the message.
+        */
+       protected $keysToTry;
+
        /**
         * @var array List of parameters which will be substituted into the message.
         */
@@ -224,30 +230,61 @@ class Message {
         * non-empty message for.
         * @param array $params Message parameters.
         * @param Language $language Optional language of the message, defaults to $wgLang.
+        *
+        * @throws InvalidArgumentException
         */
        public function __construct( $key, $params = array(), Language $language = null ) {
                global $wgLang;
 
-               $this->key = $key;
+               if ( !is_string( $key ) && !is_array( $key ) ) {
+                       throw new InvalidArgumentException( '$key must be a string or an array' );
+               }
+
+               $this->keysToTry = (array)$key;
+
+               if ( empty( $this->keysToTry ) ) {
+                       throw new InvalidArgumentException( '$key must not be an empty list' );
+               }
+
+               $this->key = reset( $this->keysToTry );
+
                $this->parameters = array_values( $params );
                $this->language = $language ? $language : $wgLang;
        }
 
        /**
-        * Returns the message key or the first from an array of message keys.
+        * @since 1.24
+        *
+        * @return bool True if this is a multi-key message, that is, if the key provided to the
+        * constructor was a fallback list of keys to try.
+        */
+       public function isMultiKey() {
+               return count( $this->keysToTry ) > 1;
+       }
+
+       /**
+        * @since 1.24
+        *
+        * @return string[] The list of keys to try when fetching the message text,
+        * in order of preference.
+        */
+       public function getKeysToTry() {
+               return $this->keysToTry;
+       }
+
+       /**
+        * Returns the message key.
+        *
+        * If a list of multiple possible keys was supplied to the constructor, this method may
+        * return any of these keys. After the message ahs been fetched, this method will return
+        * the key that was actually used to fetch the message.
         *
         * @since 1.21
         *
         * @return string
         */
        public function getKey() {
-               if ( is_array( $this->key ) ) {
-                       // May happen if some kind of fallback is applied.
-                       // For now, just use the first key. We really need a better solution.
-                       return $this->key[0];
-               } else {
-                       return $this->key;
-               }
+               return $this->key;
        }
 
        /**
@@ -637,7 +674,7 @@ class Message {
                $string = $this->fetchMessage();
 
                if ( $string === false ) {
-                       $key = htmlspecialchars( is_array( $this->key ) ? $this->key[0] : $this->key );
+                       $key = htmlspecialchars( $this->key );
                        if ( $this->format === 'plain' ) {
                                return '<' . $key . '>';
                        }
@@ -997,20 +1034,18 @@ class Message {
        protected function fetchMessage() {
                if ( $this->message === null ) {
                        $cache = MessageCache::singleton();
-                       if ( is_array( $this->key ) ) {
-                               if ( !count( $this->key ) ) {
-                                       throw new MWException( "Given empty message key array." );
-                               }
-                               foreach ( $this->key as $key ) {
-                                       $message = $cache->get( $key, $this->useDatabase, $this->language );
-                                       if ( $message !== false && $message !== '' ) {
-                                               break;
-                                       }
+
+                       foreach ( $this->keysToTry as $key ) {
+                               $message = $cache->get( $key, $this->useDatabase, $this->language );
+                               if ( $message !== false && $message !== '' ) {
+                                       break;
                                }
-                               $this->message = $message;
-                       } else {
-                               $this->message = $cache->get( $this->key, $this->useDatabase, $this->language );
                        }
+
+                       // NOTE: The constructor makes sure keysToTry isn't empty,
+                       //       so we know that $key and $message are initialized.
+                       $this->key = $key;
+                       $this->message = $message;
                }
                return $this->message;
        }
@@ -1038,13 +1073,20 @@ class RawMessage extends Message {
         *
         * @see Message::__construct
         *
-        * @param string|string[] $key Message to use.
+        * @param string $text Message to use.
         * @param array $params Parameters for the message.
+        *
+        * @throws InvalidArgumentException
         */
-       public function __construct( $key, $params = array() ) {
-               parent::__construct( $key, $params );
+       public function __construct( $text, $params = array() ) {
+               if ( !is_string( $text ) ) {
+                       throw new InvalidArgumentException( '$text must be a string' );
+               }
+
+               parent::__construct( $text, $params );
+
                // The key is the message.
-               $this->message = $key;
+               $this->message = $text;
        }
 
        /**
@@ -1057,6 +1099,7 @@ class RawMessage extends Message {
                if ( $this->message === null ) {
                        $this->message = $this->key;
                }
+
                return $this->message;
        }
 
index 03c529e..1eb04c3 100644 (file)
@@ -271,6 +271,10 @@ if ( $wgSkipSkin ) {
        $wgSkipSkins[] = $wgSkipSkin;
 }
 
+// Register a hidden "fallback" skin
+$wgValidSkinNames['fallback'] = 'Fallback'; // SkinFallback
+$wgSkipSkins[] = 'fallback';
+
 if ( $wgLocalInterwiki ) {
        array_unshift( $wgLocalInterwikis, $wgLocalInterwiki );
 }
diff --git a/includes/SkinFallback.php b/includes/SkinFallback.php
new file mode 100644 (file)
index 0000000..ab72a38
--- /dev/null
@@ -0,0 +1,129 @@
+<?php
+/**
+ * Skin file for the fallback skin.
+ *
+ * The structure is copied from the example skin (mediawiki/skins/Example).
+ *
+ * @since 1.24
+ * @file
+ */
+
+/**
+ * SkinTemplate class for the fallback skin
+ */
+class SkinFallback extends SkinTemplate {
+       var $skinname = 'fallback', $template = 'SkinFallbackTemplate';
+
+       /**
+        * Add CSS via ResourceLoader
+        *
+        * @param $out OutputPage
+        */
+       function setupSkinUserCss( OutputPage $out ) {
+               parent::setupSkinUserCss( $out );
+               $out->addModuleStyles( 'mediawiki.skinning.interface' );
+       }
+}
+
+/**
+ * BaseTemplate class for the fallback skin
+ */
+class SkinFallbackTemplate extends BaseTemplate {
+       /**
+        * @return array
+        */
+       private function findInstalledSkins() {
+               global $wgStyleDirectory;
+
+               // Get all subdirectories which might contains skins
+               $possibleSkins = scandir( $wgStyleDirectory );
+               $possibleSkins = array_filter( $possibleSkins, function ( $maybeDir ) {
+                       global $wgStyleDirectory;
+                       return $maybeDir !== '.' && $maybeDir !== '..' && is_dir( "$wgStyleDirectory/$maybeDir" );
+               } );
+
+               // Only keep the ones that contain a .php file with the same name inside
+               $possibleSkins = array_filter( $possibleSkins, function ( $skinDir ) {
+                       global $wgStyleDirectory;
+                       return is_file( "$wgStyleDirectory/$skinDir/$skinDir.php" );
+               } );
+
+               return $possibleSkins;
+       }
+
+       /**
+        * Inform the user why they are seeing this skin.
+        *
+        * @return string
+        */
+       private function buildHelpfulInformationMessage() {
+               global $wgDefaultSkin, $wgValidSkinNames;
+
+               $installedSkins = $this->findInstalledSkins();
+               $enabledSkins = $wgValidSkinNames;
+               $enabledSkins = array_change_key_case( $enabledSkins, CASE_LOWER );
+
+               if ( $installedSkins ) {
+                       $skinsInstalledText = array();
+                       $skinsInstalledSnippet = array();
+
+                       foreach ( $installedSkins as $skin ) {
+                               $normalizedKey = strtolower( $skin );
+                               $isEnabled = array_key_exists( $normalizedKey, $enabledSkins );
+                               if ( $isEnabled ) {
+                                       $skinsInstalledText[] = $this->getMsg( 'default-skin-not-found-row-enabled' )
+                                               ->params( $normalizedKey, $skin )->plain();
+                               } else {
+                                       $skinsInstalledText[] = $this->getMsg( 'default-skin-not-found-row-disabled' )
+                                               ->params( $normalizedKey, $skin )->plain();
+                                       $skinsInstalledSnippet[] = "require_once \"\$IP/skins/$skin/$skin.php\";";
+                               }
+                       }
+
+                       return $this->getMsg( 'default-skin-not-found' )->params(
+                               $wgDefaultSkin,
+                               implode( "\n", $skinsInstalledText ),
+                               implode( "\n", $skinsInstalledSnippet )
+                       )->parseAsBlock();
+               } else {
+                       return $this->getMsg( 'default-skin-not-found-no-skins' )->params(
+                               $wgDefaultSkin
+                       )->parseAsBlock();
+               }
+       }
+
+       /**
+        * Outputs the entire contents of the page. No navigation (other than search box), just the big
+        * warning message and page content.
+        */
+       public function execute() {
+               $this->html( 'headelement' ) ?>
+
+               <div class="warningbox">
+                       <?php echo $this->buildHelpfulInformationMessage() ?>
+               </div>
+
+               <form action="<?php $this->text( 'wgScript' ) ?>">
+                       <input type="hidden" name="title" value="<?php $this->text( 'searchtitle' ) ?>" />
+                       <h3><label for="searchInput"><?php $this->msg( 'search' ) ?></label></h3>
+                       <?php echo $this->makeSearchInput( array( "id" => "searchInput" ) ) ?>
+                       <?php echo $this->makeSearchButton( 'go' ) ?>
+               </form>
+
+               <div class="mw-body" role="main">
+                       <h1 class="firstHeading">
+                               <span dir="auto"><?php $this->html( 'title' ) ?></span>
+                       </h1>
+
+                       <div class="mw-body-content">
+                               <?php $this->html( 'bodytext' ) ?>
+                               <?php $this->html( 'catlinks' ) ?>
+                       </div>
+               </div>
+
+               <?php $this->printTrail() ?>
+               </body></html>
+
+               <?php
+       }
+}
index 8b2bfaa..2c2b470 100644 (file)
@@ -46,21 +46,3 @@ class ProtectAction extends FormlessAction {
        }
 }
 
-/**
- * Handle page unprotection
- *
- * This is a wrapper that will call Article::unprotect().
- *
- * @ingroup Actions
- */
-class UnprotectAction extends ProtectAction {
-
-       public function getName() {
-               return 'unprotect';
-       }
-
-       public function show() {
-
-               $this->page->unprotect();
-       }
-}
diff --git a/includes/actions/UnprotectAction.php b/includes/actions/UnprotectAction.php
new file mode 100644 (file)
index 0000000..6234aba
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+/**
+ * action=unprotect handler
+ *
+ * Copyright © 2012 Timo Tijhof
+ *
+ * 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
+ *
+ * @file
+ * @ingroup Actions
+ * @author Timo Tijhof
+ */
+
+/**
+ * Handle page unprotection
+ *
+ * This is a wrapper that will call Article::unprotect().
+ *
+ * @ingroup Actions
+ */
+class UnprotectAction extends ProtectAction {
+
+       public function getName() {
+               return 'unprotect';
+       }
+
+       public function show() {
+
+               $this->page->unprotect();
+       }
+}
\ No newline at end of file
diff --git a/includes/actions/UnwatchAction.php b/includes/actions/UnwatchAction.php
new file mode 100644 (file)
index 0000000..e2e5a1d
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Performs the unwatch actions on a page
+ *
+ * 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
+ *
+ * @file
+ * @ingroup Actions
+ */
+
+/**
+ * Page removal from a user's watchlist
+ *
+ * @ingroup Actions
+ */
+class UnwatchAction extends WatchAction {
+
+       public function getName() {
+               return 'unwatch';
+       }
+
+       protected function getDescription() {
+               return $this->msg( 'removewatch' )->escaped();
+       }
+
+       public function onSubmit( $data ) {
+               wfProfileIn( __METHOD__ );
+               self::doUnwatch( $this->getTitle(), $this->getUser() );
+               wfProfileOut( __METHOD__ );
+
+               return true;
+       }
+
+       protected function alterForm( HTMLForm $form ) {
+               $form->setSubmitTextMsg( 'confirm-unwatch-button' );
+       }
+
+       protected function preText() {
+               return $this->msg( 'confirm-unwatch-top' )->parse();
+       }
+
+       public function onSuccess() {
+               $this->getOutput()->addWikiMsg( 'removedwatchtext', $this->getTitle()->getPrefixedText() );
+       }
+}
index 2c7502e..a54b7c5 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Performs the watch and unwatch actions on a page
+ * Performs the watch actions on a page
  *
  * 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
@@ -217,39 +217,3 @@ class WatchAction extends FormAction {
                $this->getOutput()->addWikiMsg( 'addedwatchtext', $this->getTitle()->getPrefixedText() );
        }
 }
-
-/**
- * Page removal from a user's watchlist
- *
- * @ingroup Actions
- */
-class UnwatchAction extends WatchAction {
-
-       public function getName() {
-               return 'unwatch';
-       }
-
-       protected function getDescription() {
-               return $this->msg( 'removewatch' )->escaped();
-       }
-
-       public function onSubmit( $data ) {
-               wfProfileIn( __METHOD__ );
-               self::doUnwatch( $this->getTitle(), $this->getUser() );
-               wfProfileOut( __METHOD__ );
-
-               return true;
-       }
-
-       protected function alterForm( HTMLForm $form ) {
-               $form->setSubmitTextMsg( 'confirm-unwatch-button' );
-       }
-
-       protected function preText() {
-               return $this->msg( 'confirm-unwatch-top' )->parse();
-       }
-
-       public function onSuccess() {
-               $this->getOutput()->addWikiMsg( 'removedwatchtext', $this->getTitle()->getPrefixedText() );
-       }
-}
index 8226529..fdf3f02 100644 (file)
@@ -59,13 +59,55 @@ class ApiModuleManager extends ContextSource {
        }
 
        /**
-        * Add a list of modules to the manager
-        * @param array $modules A map of ModuleName => ModuleClass
+        * Add a list of modules to the manager. Each module is described
+        * by a module spec.
+        *
+        * Each module spec is an associative array containing at least
+        * the 'class' key for the module's class, and optionally a
+        * 'factory' key for the factory function to use for the module.
+        *
+        * That factory function will be called with two parameters,
+        * the parent module (an instance of ApiBase, usually ApiMain)
+        * and the name the module was registered under. The return
+        * value must be an instance of the class given in the 'class'
+        * field.
+        *
+        * For backward compatibility, the module spec may also be a
+        * simple string containing the module's class name. In that
+        * case, the class' constructor will be called with the parent
+        * module and module name as parameters, as described above.
+        *
+        * Examples for defining module specs:
+        *
+        * @code
+        *  $modules['foo'] = 'ApiFoo';
+        *  $modules['bar'] = array(
+        *      'class' => 'ApiBar',
+        *      'factory' => function( $main, $name ) { ... }
+        *  );
+        *  $modules['xyzzy'] = array(
+        *      'class' => 'ApiXyzzy',
+        *      'factory' => array( 'XyzzyFactory', 'newApiModule' )
+        *  );
+        * @endcode
+        *
+        * @param array $modules A map of ModuleName => ModuleSpec; The ModuleSpec
+        *        is either a string containing the module's class name, or an associative
+        *        array (see above for details).
         * @param string $group Which group modules belong to (action,format,...)
         */
        public function addModules( array $modules, $group ) {
-               foreach ( $modules as $name => $class ) {
-                       $this->addModule( $name, $group, $class );
+
+               foreach ( $modules as $name => $moduleSpec ) {
+                       if ( is_array( $moduleSpec ) ) {
+                               $class = $moduleSpec['class'];
+                               $factory = ( isset( $moduleSpec['factory'] ) ? $moduleSpec['factory'] : null );
+                       } else {
+                               $class = $moduleSpec;
+                               $factory = null;
+                       }
+
+                       $this->addModule( $name, $group, $class, $factory );
                }
        }
 
@@ -74,37 +116,61 @@ class ApiModuleManager extends ContextSource {
         * classes who wish to add their own modules to their lexicon or override the
         * behavior of inherent ones.
         *
-        * @param string $group Name of the module group
         * @param string $name The identifier for this module.
+        * @param string $group Name of the module group
         * @param string $class The class where this module is implemented.
+        * @param callable|null $factory Callback for instantiating the module.
+        *
+        * @throws InvalidArgumentException
         */
-       public function addModule( $name, $group, $class ) {
+       public function addModule( $name, $group, $class, $factory = null ) {
+               if ( !is_string( $name ) ) {
+                       throw new InvalidArgumentException( '$name must be a string' );
+               }
+
+               if ( !is_string( $group ) ) {
+                       throw new InvalidArgumentException( '$group must be a string' );
+               }
+
+               if ( !is_string( $class ) ) {
+                       throw new InvalidArgumentException( '$class must be a string' );
+               }
+
+               if ( $factory !== null && !is_callable( $factory ) ) {
+                       throw new InvalidArgumentException( '$factory must be a callable (or null)' );
+               }
+
                $this->mGroups[$group] = null;
-               $this->mModules[$name] = array( $group, $class );
+               $this->mModules[$name] = array( $group, $class, $factory );
        }
 
        /**
         * Get module instance by name, or instantiate it if it does not exist
+        *
         * @param string $moduleName Module name
         * @param string $group Optionally validate that the module is in a specific group
         * @param bool $ignoreCache If true, force-creates a new instance and does not cache it
-        * @return mixed The new module instance, or null if failed
+        *
+        * @return ApiBase|null The new module instance, or null if failed
         */
        public function getModule( $moduleName, $group = null, $ignoreCache = false ) {
                if ( !isset( $this->mModules[$moduleName] ) ) {
                        return null;
                }
-               $grpCls = $this->mModules[$moduleName];
-               if ( $group !== null && $grpCls[0] !== $group ) {
+
+               list( $moduleGroup, $moduleClass, $moduleFactory ) = $this->mModules[$moduleName];
+
+               if ( $group !== null && $moduleGroup !== $group ) {
                        return null;
                }
+
                if ( !$ignoreCache && isset( $this->mInstances[$moduleName] ) ) {
                        // already exists
                        return $this->mInstances[$moduleName];
                } else {
                        // new instance
-                       $class = $grpCls[1];
-                       $instance = new $class ( $this->mParent, $moduleName );
+                       $instance = $this->instantiateModule( $moduleName, $moduleClass, $moduleFactory );
+
                        if ( !$ignoreCache ) {
                                // cache this instance in case it is needed later
                                $this->mInstances[$moduleName] = $instance;
@@ -114,6 +180,32 @@ class ApiModuleManager extends ContextSource {
                }
        }
 
+       /**
+        * Instantiate the module using the given class or factory function.
+        *
+        * @param string $name The identifier for this module.
+        * @param string $class The class where this module is implemented.
+        * @param callable|null $factory Callback for instantiating the module.
+        *
+        * @throws MWException
+        * @return ApiBase
+        */
+       private function instantiateModule( $name, $class, $factory = null ) {
+               if ( $factory !== null ) {
+                       // create instance from factory
+                       $instance = call_user_func( $factory, $this->mParent, $name );
+
+                       if ( ! $instance instanceof $class ) {
+                               throw new MWException( "The factory function for module $name did not return an instance of $class!" );
+                       }
+               } else {
+                       // create instance from class name
+                       $instance = new $class( $this->mParent, $name );
+               }
+
+               return $instance;
+       }
+
        /**
         * Get an array of modules in a specific group or all if no group is set.
         * @param string $group Optional group filter
index d0980e6..b27f6c2 100644 (file)
@@ -46,10 +46,11 @@ class ApiQueryAllUsers extends ApiQueryBase {
 
        public function execute() {
                $params = $this->extractRequestParams();
+               $activeUserDays = $this->getConfig()->get( 'ActiveUserDays' );
 
                if ( $params['activeusers'] ) {
                        // Update active user cache
-                       SpecialActiveUsers::mergeActiveUsers( 600 );
+                       SpecialActiveUsers::mergeActiveUsers( 600, $activeUserDays );
                }
 
                $db = $this->getDB();
@@ -161,7 +162,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
                }
 
                if ( $params['activeusers'] ) {
-                       $activeUserSeconds = $this->getConfig()->get( 'ActiveUserDays' ) * 86400;
+                       $activeUserSeconds = $activeUserDays * 86400;
 
                        // Filter query to only include users in the active users cache
                        $this->addTables( 'querycachetwo' );
index 7d6a7e4..3492972 100644 (file)
@@ -56,7 +56,7 @@ class ApiUndelete extends ApiBase {
                        $params['timestamps'][$i] = wfTimestamp( TS_MW, $ts );
                }
 
-               $pa = new PageArchive( $titleObj );
+               $pa = new PageArchive( $titleObj, $this->getConfig() );
                $retval = $pa->undelete(
                        ( isset( $params['timestamps'] ) ? $params['timestamps'] : array() ),
                        $params['reason'],
index cf87129..eb6a57a 100644 (file)
@@ -20,8 +20,6 @@
  * @file
  */
 
-define( 'MW_LC_VERSION', 2 );
-
 /**
  * Class for caching the contents of localisation files, Messages*.php
  * and *.i18n.php.
@@ -35,6 +33,8 @@ define( 'MW_LC_VERSION', 2 );
  * as grammatical transformation, is done by the caller.
  */
 class LocalisationCache {
+       const VERSION = 2;
+
        /** Configuration associative array */
        private $conf;
 
@@ -913,7 +913,7 @@ class LocalisationCache {
                # Add cache dependencies for any referenced globals
                $deps['wgExtensionMessagesFiles'] = new GlobalDependency( 'wgExtensionMessagesFiles' );
                $deps['wgMessagesDirs'] = new GlobalDependency( 'wgMessagesDirs' );
-               $deps['version'] = new ConstantDependency( 'MW_LC_VERSION' );
+               $deps['version'] = new ConstantDependency( 'LocalisationCache::VERSION' );
 
                # Add dependencies to the cache entry
                $allData['deps'] = $deps;
index 39ed367..468bceb 100644 (file)
@@ -4,6 +4,7 @@
                        "Filipinayzd"
                ]
        },
+       "config-title": "Pabutang ka MediaWiki $1",
        "config-information": "Impormasyon",
        "config-your-language": "A kanimong sarita:",
        "config-wiki-language": "Sarita ka Wiki:",
        "config-db-host-oracle": "Database ka TNS:",
        "config-db-wiki-settings": "Mibdiron adin wiki",
        "config-db-name": "Ngaran ka database:",
+       "config-charset-mysql5-binary": "MySQL 4.1/5.0 binary",
        "config-charset-mysql5": "MySQL 4.1/5.0 UTF-8",
+       "config-charset-mysql4": "MySQL 4.0 backwards-compatible UTF-8",
        "config-db-port": "Port ka database:",
        "config-db-schema": "Skema para sa MediaWiki:",
        "config-sqlite-dir": "Direktoryo ka data sa SQLite:",
        "config-oracle-def-ts": "Dating tablescape:",
        "config-oracle-temp-ts": "Temporaryong tablescape:",
+       "config-type-mysql": "MySQL (o compatible)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-header-mysql": "MySQL settings",
        "config-header-postgres": "PostgreSQL settings",
        "config-header-mssql": "Microsoft SQL Server settings",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
+       "config-mysql-binary": "Binary",
        "config-mysql-utf8": "UTF-8",
+       "config-site-name": "Ngaran ka wiki",
+       "config-site-name-blank": "Ibutang a ngaran ka site.",
+       "config-project-namespace": "Bibutangan ka proyekto:",
+       "config-ns-generic": "Proyekto",
        "config-ns-other-default": "MyWiki",
        "config-admin-password": "Password:",
        "config-admin-password-confirm": "Password ulit:",
        "config-admin-email": "Email address:",
        "config-profile-wiki": "Bukas na wiki",
        "config-profile-private": "Pribadong wiki",
+       "config-license-pd": "Pampublikong Domain",
+       "config-email-sender": "Pabalik na email adres:",
        "config-logo": "URL ko logo:",
        "config-cc-again": "Pumili dayday...",
        "config-install-step-done": "tapus na",
+       "config-install-user-alreadyexists": "Agko na ka user na \"$1\"",
+       "config-install-user-create-failed": "Sala a ginigibong user na \"$1\": $2",
        "config-help": "tabang"
 }
index 59eec45..19b02b5 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "Peter Alberti",
                        "Christian List",
-                       "Tjernobyl"
+                       "Tjernobyl",
+                       "Thomsen"
                ]
        },
        "config-page-language": "Sprog",
        "config-page-name": "Navn",
        "config-page-options": "Indstillinger",
        "config-page-install": "Installer",
+       "config-page-complete": "Færdig",
+       "config-page-restart": "Genstarte installation",
+       "config-page-readme": "Læs mig",
+       "config-page-copying": "Kopiering",
+       "config-page-upgradedoc": "Opgradering",
+       "config-page-existingwiki": "Eksisterende wiki",
+       "config-help-restart": "Vil du rydde alle gemte data, du har indtastet og genstarte installationen?",
+       "config-restart": "Ja, genstarte den",
+       "config-env-php": "PHP  $1  er installeret.",
+       "config-db-type": "Databasetype:",
+       "config-db-host": "Database vært:",
+       "config-db-name": "Databasenavn:",
+       "config-mysql-old": "MySQL $1 eller nyere kræves. Du har $2.",
        "config-header-mysql": "MySQL-indstillinger",
        "config-header-postgres": "PostgreSQL-indstillinger",
        "config-header-sqlite": "SQLite-indstillinger",
index 6db9e5f..572eacc 100644 (file)
@@ -52,11 +52,9 @@ class ActiveUsersPager extends UsersPager {
         * @param string $par Parameter passed to the page
         */
        function __construct( IContextSource $context = null, $group = null, $par = null ) {
-               global $wgActiveUserDays;
-
                parent::__construct( $context );
 
-               $this->RCMaxAge = $wgActiveUserDays;
+               $this->RCMaxAge = $this->getConfig()->get( 'ActiveUserDays' );
                $un = $this->getRequest()->getText( 'username', $par );
                $this->requestedUser = '';
                if ( $un != '' ) {
@@ -192,13 +190,11 @@ class ActiveUsersPager extends UsersPager {
        }
 
        function getPageHeader() {
-               global $wgScript;
-
                $self = $this->getTitle();
                $limit = $this->mLimit ? Html::hidden( 'limit', $this->mLimit ) : '';
 
                # Form tag
-               $out = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) );
+               $out = Xml::openElement( 'form', array( 'method' => 'get', 'action' => wfScript() ) );
                $out .= Xml::fieldset( $this->msg( 'activeusers' )->text() ) . "\n";
                $out .= Html::hidden( 'title', $self->getPrefixedDBkey() ) . $limit . "\n";
 
@@ -247,17 +243,17 @@ class SpecialActiveUsers extends SpecialPage {
         * @param string $par Parameter passed to the page or null
         */
        public function execute( $par ) {
-               global $wgActiveUserDays;
+               $days = $this->getConfig()->get( 'ActiveUserDays' );
 
                $this->setHeaders();
                $this->outputHeader();
 
                $out = $this->getOutput();
                $out->wrapWikiMsg( "<div class='mw-activeusers-intro'>\n$1\n</div>",
-                       array( 'activeusers-intro', $this->getLanguage()->formatNum( $wgActiveUserDays ) ) );
+                       array( 'activeusers-intro', $this->getLanguage()->formatNum( $days ) ) );
 
                // Occasionally merge in new updates
-               $seconds = min( self::mergeActiveUsers( 600 ), $wgActiveUserDays * 86400 );
+               $seconds = min( self::mergeActiveUsers( 600, $days ), $days * 86400 );
                // Mention the level of staleness
                $out->addWikiMsg( 'cachedspecial-viewing-cached-ttl',
                        $this->getLanguage()->formatDuration( $seconds ) );
@@ -284,12 +280,11 @@ class SpecialActiveUsers extends SpecialPage {
        }
 
        /**
-        * @param intr $period Seconds (do updates no more often than this)
+        * @param int $period Seconds (do updates no more often than this)
+        * @param int $days How many days user must be idle before he is considered inactive
         * @return int How many seconds old the cache is
         */
-       public static function mergeActiveUsers( $period ) {
-               global $wgActiveUserDays;
-
+       public static function mergeActiveUsers( $period, $days ) {
                $dbr = wfGetDB( DB_SLAVE );
                $cTime = $dbr->selectField( 'querycache_info',
                        'qci_timestamp',
@@ -300,16 +295,16 @@ class SpecialActiveUsers extends SpecialPage {
                        if ( !$cTime || ( time() - wfTimestamp( TS_UNIX, $cTime ) ) > $period ) {
                                $dbw = wfGetDB( DB_MASTER );
                                if ( $dbw->estimateRowCount( 'recentchanges' ) <= 10000 ) {
-                                       $window = $wgActiveUserDays * 86400; // small wiki
+                                       $window = $days * 86400; // small wiki
                                } else {
                                        $window = $period * 2;
                                }
-                               $cTime = self::doQueryCacheUpdate( $dbw, $window ) ?: $cTime;
+                               $cTime = self::doQueryCacheUpdate( $dbw, $days, $window ) ?: $cTime;
                        }
                }
 
                return ( time() -
-                       ( $cTime ? wfTimestamp( TS_UNIX, $cTime ) : $wgActiveUserDays * 86400 ) );
+                       ( $cTime ? wfTimestamp( TS_UNIX, $cTime ) : $days * 86400 ) );
        }
 
        /**
@@ -319,19 +314,18 @@ class SpecialActiveUsers extends SpecialPage {
        public static function cacheUpdate( DatabaseBase $dbw ) {
                global $wgActiveUserDays;
 
-               self::doQueryCacheUpdate( $dbw, $wgActiveUserDays * 86400 );
+               self::doQueryCacheUpdate( $dbw, $wgActiveUserDays, $wgActiveUserDays * 86400 );
        }
 
        /**
         * Update the query cache as needed
         *
         * @param DatabaseBase $dbw
+        * @param int $days How many days user must be idle before he is considered inactive
         * @param int $window Maximum time range of new data to scan (in seconds)
         * @return int|bool UNIX timestamp the cache is now up-to-date as of (false on error)
         */
-       protected static function doQueryCacheUpdate( DatabaseBase $dbw, $window ) {
-               global $wgActiveUserDays;
-
+       protected static function doQueryCacheUpdate( DatabaseBase $dbw, $days, $window ) {
                $lockKey = wfWikiID() . '-activeusers';
                if ( !$dbw->lock( $lockKey, __METHOD__, 1 ) ) {
                        return false; // exclusive update (avoids duplicate entries)
@@ -347,7 +341,7 @@ class SpecialActiveUsers extends SpecialPage {
                // Pick the date range to fetch from. This is normally from the last
                // update to till the present time, but has a limited window for sanity.
                // If the window is limited, multiple runs are need to fully populate it.
-               $sTimestamp = max( $cTimeUnix, $now - $wgActiveUserDays * 86400 );
+               $sTimestamp = max( $cTimeUnix, $now - $days * 86400 );
                $eTimestamp = min( $sTimestamp + $window, $now );
 
                // Get all the users active since the last update
@@ -376,7 +370,7 @@ class SpecialActiveUsers extends SpecialPage {
                $dbw->delete( 'querycachetwo',
                        array(
                                'qcc_type' => 'activeusers',
-                               'qcc_value < ' . $dbw->addQuotes( $now - $wgActiveUserDays * 86400 ) // TS_UNIX
+                               'qcc_value < ' . $dbw->addQuotes( $now - $days * 86400 ) // TS_UNIX
                        ),
                        __METHOD__
                );
index cb6ec3c..b84540c 100644 (file)
@@ -50,7 +50,7 @@ class SpecialProtectedtitles extends SpecialPage {
                $size = $request->getIntOrNull( 'size' );
                $NS = $request->getIntOrNull( 'namespace' );
 
-               $pager = new ProtectedTitlesPager( $this, array(), $type, $level, $NS, $sizetype, $size );
+               $pager = new ProtectedTitlesPager( $this->getContext(), array(), $type, $level, $NS, $sizetype, $size );
 
                $this->getOutput()->addHTML( $this->showOptions( $NS, $type, $level ) );
 
@@ -133,8 +133,7 @@ class SpecialProtectedtitles extends SpecialPage {
         * @private
         */
        function showOptions( $namespace, $type = 'edit', $level ) {
-               global $wgScript;
-               $action = htmlspecialchars( $wgScript );
+               $action = htmlspecialchars( wfScript() );
                $title = $this->getPageTitle();
                $special = htmlspecialchars( $title->getPrefixedDBkey() );
 
@@ -175,14 +174,12 @@ class SpecialProtectedtitles extends SpecialPage {
         * @private
         */
        function getLevelMenu( $pr_level ) {
-               global $wgRestrictionLevels;
-
                // Temporary array
                $m = array( $this->msg( 'restriction-level-all' )->text() => 0 );
                $options = array();
 
                // First pass to load the log names
-               foreach ( $wgRestrictionLevels as $type ) {
+               foreach ( $this->getConfig()->get( 'RestrictionLevels' ) as $type ) {
                        if ( $type != '' && $type != '*' ) {
                                // Messages: restriction-level-sysop, restriction-level-autoconfirmed
                                $text = $this->msg( "restriction-level-$type" )->text();
index 8c01ef2..28a1bc5 100644 (file)
@@ -68,8 +68,6 @@ class SpecialRandomInCategory extends SpecialPage {
        }
 
        public function execute( $par ) {
-               global $wgScript;
-
                $cat = false;
 
                $categoryStr = $this->getRequest()->getText( 'category', $par );
@@ -100,7 +98,7 @@ class SpecialRandomInCategory extends SpecialPage {
                        $submit = Html::input( '', $submitText, 'submit' );
 
                        $msg = $this->msg( 'randomincategory-selectcategory' );
-                       $form = Html::rawElement( 'form', array( 'action' => $wgScript ),
+                       $form = Html::rawElement( 'form', array( 'action' => wfScript() ),
                                Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() ) .
                                $msg->rawParams( $input, $submit )->parse()
                        );
index ea785fa..5938f01 100644 (file)
@@ -192,8 +192,6 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
         * @return bool|ResultWrapper Result or false (for Recentchangeslinked only)
         */
        public function doMainQuery( $conds, $opts ) {
-               global $wgAllowCategorizedRecentChanges;
-
                $dbr = $this->getDB();
                $user = $this->getUser();
 
@@ -247,7 +245,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                );
 
                // Build the final data
-               if ( $wgAllowCategorizedRecentChanges ) {
+               if ( $this->getConfig()->get( 'AllowCategorizedRecentChanges' ) ) {
                        $this->filterByCategories( $rows, $opts );
                }
 
@@ -273,14 +271,14 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
         * @return array
         */
        private function getFeedQuery() {
-               global $wgFeedLimit;
                $query = array_filter( $this->getOptions()->getAllValues(), function ( $value ) {
                        // API handles empty parameters in a different way
                        return $value !== '';
                } );
                $query['action'] = 'feedrecentchanges';
-               if ( $query['limit'] > $wgFeedLimit ) {
-                       $query['limit'] = $wgFeedLimit;
+               $feedLimit = $this->getConfig()->get( 'FeedLimit' );
+               if ( $query['limit'] > $feedLimit ) {
+                       $query['limit'] = $feedLimit;
                }
 
                return $query;
@@ -293,11 +291,9 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
         * @param FormOptions $opts
         */
        public function outputChangesList( $rows, $opts ) {
-               global $wgRCShowWatchingUsers, $wgShowUpdatedMarker;
-
                $limit = $opts['limit'];
 
-               $showWatcherCount = $wgRCShowWatchingUsers
+               $showWatcherCount = $this->getConfig()->get( 'RCShowWatchingUsers' )
                        && $this->getUser()->getOption( 'shownumberswatching' );
                $watcherCache = array();
 
@@ -315,7 +311,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                        $rc = RecentChange::newFromRow( $obj );
                        $rc->counter = $counter++;
                        # Check if the page has been updated since the last visit
-                       if ( $wgShowUpdatedMarker && !empty( $obj->wl_notificationtimestamp ) ) {
+                       if ( $this->getConfig()->get( 'ShowUpdatedMarker' ) && !empty( $obj->wl_notificationtimestamp ) ) {
                                $rc->notificationtimestamp = ( $obj->rc_timestamp >= $obj->wl_notificationtimestamp );
                        } else {
                                $rc->notificationtimestamp = false; // Default
@@ -367,8 +363,6 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
         * @param int $numRows Number of rows in the result to show after this header
         */
        public function doHeader( $opts, $numRows ) {
-               global $wgScript;
-
                $this->setTopText( $opts );
 
                $defaults = $opts->getAllValues();
@@ -420,7 +414,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
 
                $t = $this->getPageTitle();
                $out .= Html::hidden( 'title', $t->getPrefixedText() );
-               $form = Xml::tags( 'form', array( 'action' => $wgScript ), $out );
+               $form = Xml::tags( 'form', array( 'action' => wfScript() ), $out );
                $panel[] = $form;
                $panelString = implode( "\n", $panel );
 
@@ -470,8 +464,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                $extraOpts = array();
                $extraOpts['namespace'] = $this->namespaceFilterForm( $opts );
 
-               global $wgAllowCategorizedRecentChanges;
-               if ( $wgAllowCategorizedRecentChanges ) {
+               if ( $this->getConfig()->get( 'AllowCategorizedRecentChanges' ) ) {
                        $extraOpts['category'] = $this->categoryFilterForm( $opts );
                }
 
@@ -655,8 +648,6 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
         * @return string
         */
        function optionsPanel( $defaults, $nondefaults, $numRows ) {
-               global $wgRCLinkLimits, $wgRCLinkDays;
-
                $options = $nondefaults + $defaults;
 
                $note = '';
@@ -680,12 +671,12 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                }
 
                # Sort data for display and make sure it's unique after we've added user data.
-               $linkLimits = $wgRCLinkLimits;
+               $linkLimits = $this->getConfig()->get( 'RCLinkLimits' );
                $linkLimits[] = $options['limit'];
                sort( $linkLimits );
                $linkLimits = array_unique( $linkLimits );
 
-               $linkDays = $wgRCLinkDays;
+               $linkDays = $this->getConfig()->get( 'RCLinkDays' );
                $linkDays[] = $options['days'];
                sort( $linkDays );
                $linkDays = array_unique( $linkDays );
index 1caed0b..26f67b1 100644 (file)
@@ -186,12 +186,11 @@ class SpecialSearch extends SpecialPage {
                # No match, generate an edit URL
                $title = Title::newFromText( $term );
                if ( !is_null( $title ) ) {
-                       global $wgGoToEdit;
                        wfRunHooks( 'SpecialSearchNogomatch', array( &$title ) );
                        wfDebugLog( 'nogomatch', $title->getFullText(), 'private' );
 
                        # If the feature is enabled, go straight to the edit page
-                       if ( $wgGoToEdit ) {
+                       if ( $this->getConfig()->get( 'GoToEdit' ) ) {
                                $this->getOutput()->redirect( $title->getFullURL( array( 'action' => 'edit' ) ) );
 
                                return;
@@ -204,7 +203,7 @@ class SpecialSearch extends SpecialPage {
         * @param string $term
         */
        public function showResults( $term ) {
-               global $wgDisableTextSearch, $wgSearchForwardUrl, $wgContLang, $wgScript;
+               global $wgContLang;
 
                $profile = new ProfileSection( __METHOD__ );
                $search = $this->getSearchEngine();
@@ -220,9 +219,10 @@ class SpecialSearch extends SpecialPage {
 
                $out = $this->getOutput();
 
-               if ( $wgDisableTextSearch ) {
-                       if ( $wgSearchForwardUrl ) {
-                               $url = str_replace( '$1', urlencode( $term ), $wgSearchForwardUrl );
+               if ( $this->getConfig()->get( 'DisableTextSearch' ) ) {
+                       $searchFowardUrl = $this->getConfig()->get( 'SearchForwardUrl' );
+                       if ( $searchFowardUrl ) {
+                               $url = str_replace( '$1', urlencode( $term ), $searchFowardUrl );
                                $out->redirect( $url );
                        } else {
                                $out->addHTML(
@@ -304,7 +304,7 @@ class SpecialSearch extends SpecialPage {
                                array(
                                        'id' => ( $this->profile === 'advanced' ? 'powersearch' : 'search' ),
                                        'method' => 'get',
-                                       'action' => $wgScript
+                                       'action' => wfScript(),
                                )
                        )
                );
index 3ba50bb..eff06f4 100644 (file)
@@ -49,8 +49,6 @@ class SpecialSpecialpages extends UnlistedSpecialPage {
        }
 
        private function getPageGroups() {
-               global $wgSortSpecialPages;
-
                $pages = SpecialPageFactory::getUsablePages( $this->getUser() );
 
                if ( !count( $pages ) ) {
@@ -76,10 +74,8 @@ class SpecialSpecialpages extends UnlistedSpecialPage {
                }
 
                /** Sort */
-               if ( $wgSortSpecialPages ) {
-                       foreach ( $groups as $group => $sortedPages ) {
-                               ksort( $groups[$group] );
-                       }
+               foreach ( $groups as $group => $sortedPages ) {
+                       ksort( $groups[$group] );
                }
 
                /** Always move "other" to end */
index 371e5ea..67c96a7 100644 (file)
@@ -36,7 +36,10 @@ class SpecialStatistics extends SpecialPage {
        }
 
        public function execute( $par ) {
-               global $wgMemc, $wgDisableCounters, $wgMiserMode;
+               global $wgMemc;
+
+               $disableCounters = $this->getConfig()->get( 'DisableCounters' );
+               $miserMode = $this->getConfig()->get( 'MiserMode' );
 
                $this->setHeaders();
                $this->getOutput()->addModuleStyles( 'mediawiki.special' );
@@ -52,12 +55,12 @@ class SpecialStatistics extends SpecialPage {
 
                # Staticic - views
                $viewsStats = '';
-               if ( !$wgDisableCounters ) {
+               if ( !$disableCounters ) {
                        $viewsStats = $this->getViewsStats();
                }
 
                # Set active user count
-               if ( !$wgMiserMode ) {
+               if ( !$miserMode ) {
                        $key = wfMemcKey( 'sitestats', 'activeusers-updated' );
                        // Re-calculate the count if the last tally is old...
                        if ( !$wgMemc->get( $key ) ) {
@@ -83,7 +86,7 @@ class SpecialStatistics extends SpecialPage {
                $text .= $viewsStats;
 
                # Statistic - popular pages
-               if ( !$wgDisableCounters && !$wgMiserMode ) {
+               if ( !$disableCounters && !$miserMode ) {
                        $text .= $this->getMostViewedPages();
                }
 
@@ -170,8 +173,6 @@ class SpecialStatistics extends SpecialPage {
        }
 
        private function getUserStats() {
-               global $wgActiveUserDays;
-
                return Xml::openElement( 'tr' ) .
                        Xml::tags( 'th', array( 'colspan' => '2' ), $this->msg( 'statistics-header-users' )->parse() ) .
                        Xml::closeElement( 'tr' ) .
@@ -187,16 +188,15 @@ class SpecialStatistics extends SpecialPage {
                                $this->getLanguage()->formatNum( $this->activeUsers ),
                                array( 'class' => 'mw-statistics-users-active' ),
                                'statistics-users-active-desc',
-                               $this->getLanguage()->formatNum( $wgActiveUserDays )
+                               $this->getLanguage()->formatNum( $this->getConfig()->get( 'ActiveUserDays' ) )
                        );
        }
 
        private function getGroupStats() {
-               global $wgGroupPermissions, $wgImplicitGroups;
                $text = '';
-               foreach ( $wgGroupPermissions as $group => $permissions ) {
+               foreach ( $this->getConfig()->get( 'GroupPermissions' ) as $group => $permissions ) {
                        # Skip generic * and implicit groups
-                       if ( in_array( $group, $wgImplicitGroups ) || $group == '*' ) {
+                       if ( in_array( $group, $this->getConfig()->get( 'ImplicitGroups' ) ) || $group == '*' ) {
                                continue;
                        }
                        $groupname = htmlspecialchars( $group );
index 73bdbd6..5e5588c 100644 (file)
@@ -37,9 +37,6 @@ class SpecialTrackingCategories extends SpecialPage {
        }
 
        function execute( $par ) {
-               // Global array containing names of tracking categories
-               global $wgTrackingCategories;
-
                $this->setHeaders();
                $this->outputHeader();
                $this->getOutput()->allowClickjacking();
@@ -59,7 +56,7 @@ class SpecialTrackingCategories extends SpecialPage {
                        </tr></thead>"
                );
 
-               foreach ( $wgTrackingCategories as $catMsg ) {
+               foreach ( $this->getConfig()->get( 'TrackingCategories' ) as $catMsg ) {
                        /*
                         * Check if the tracking category varies by namespace
                         * Otherwise only pages in the current namespace will be displayed
index 25f520e..8acf8a2 100644 (file)
@@ -36,11 +36,19 @@ class PageArchive {
        /** @var Status */
        protected $revisionStatus;
 
-       function __construct( $title ) {
+       /** @var Config */
+       protected $config;
+
+       function __construct( $title, Config $config = null ) {
                if ( is_null( $title ) ) {
                        throw new MWException( __METHOD__ . ' given a null title.' );
                }
                $this->title = $title;
+               if ( $config === null ) {
+                       wfDebug( __METHOD__ . ' did not have a Config object passed to it' );
+                       $config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
+               }
+               $this->config = $config;
        }
 
        /**
@@ -115,8 +123,6 @@ class PageArchive {
         * @return ResultWrapper
         */
        function listRevisions() {
-               global $wgContentHandlerUseDB;
-
                $dbr = wfGetDB( DB_SLAVE );
 
                $tables = array( 'archive' );
@@ -126,7 +132,7 @@ class PageArchive {
                        'ar_comment', 'ar_len', 'ar_deleted', 'ar_rev_id', 'ar_sha1',
                );
 
-               if ( $wgContentHandlerUseDB ) {
+               if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
                        $fields[] = 'ar_content_format';
                        $fields[] = 'ar_content_model';
                }
@@ -190,8 +196,6 @@ class PageArchive {
         * @return Revision|null
         */
        function getRevision( $timestamp ) {
-               global $wgContentHandlerUseDB;
-
                $dbr = wfGetDB( DB_SLAVE );
 
                $fields = array(
@@ -209,7 +213,7 @@ class PageArchive {
                        'ar_sha1',
                );
 
-               if ( $wgContentHandlerUseDB ) {
+               if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
                        $fields[] = 'ar_content_format';
                        $fields[] = 'ar_content_model';
                }
@@ -442,8 +446,6 @@ class PageArchive {
         * @return Status Status object containing the number of revisions restored on success
         */
        private function undeleteRevisions( $timestamps, $unsuppress = false, $comment = '' ) {
-               global $wgContentHandlerUseDB;
-
                if ( wfReadOnly() ) {
                        throw new ReadOnlyError();
                }
@@ -516,7 +518,7 @@ class PageArchive {
                        'ar_sha1'
                );
 
-               if ( $wgContentHandlerUseDB ) {
+               if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
                        $fields[] = 'ar_content_format';
                        $fields[] = 'ar_content_model';
                }
@@ -806,12 +808,10 @@ class SpecialUndelete extends SpecialPage {
        }
 
        function showSearchForm() {
-               global $wgScript;
-
                $out = $this->getOutput();
                $out->setPageTitle( $this->msg( 'undelete-search-title' ) );
                $out->addHTML(
-                       Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) ) .
+                       Xml::openElement( 'form', array( 'method' => 'get', 'action' => wfScript() ) ) .
                                Xml::fieldset( $this->msg( 'undelete-search-box' )->text() ) .
                                Html::hidden( 'title', $this->getPageTitle()->getPrefixedDBkey() ) .
                                Html::rawElement(
@@ -891,7 +891,7 @@ class SpecialUndelete extends SpecialPage {
                        return;
                }
 
-               $archive = new PageArchive( $this->mTargetObj );
+               $archive = new PageArchive( $this->mTargetObj, $this->getConfig() );
                if ( !wfRunHooks( 'UndeleteForm::showRevision', array( &$archive, $this->mTargetObj ) ) ) {
                        return;
                }
@@ -1198,7 +1198,7 @@ class SpecialUndelete extends SpecialPage {
                        array( 'undeletepagetitle', wfEscapeWikiText( $this->mTargetObj->getPrefixedText() ) )
                );
 
-               $archive = new PageArchive( $this->mTargetObj );
+               $archive = new PageArchive( $this->mTargetObj, $this->getConfig() );
                wfRunHooks( 'UndeleteForm::showHistory', array( &$archive, $this->mTargetObj ) );
                /*
                $text = $archive->getLastRevisionText();
@@ -1610,9 +1610,7 @@ class SpecialUndelete extends SpecialPage {
        }
 
        function undelete() {
-               global $wgUploadMaintenance;
-
-               if ( $wgUploadMaintenance && $this->mTargetObj->getNamespace() == NS_FILE ) {
+               if ( $this->getConfig()->get( 'UploadMaintenance' ) && $this->mTargetObj->getNamespace() == NS_FILE ) {
                        throw new ErrorPageError( 'undelete-error', 'filedelete-maintenance' );
                }
 
@@ -1621,7 +1619,7 @@ class SpecialUndelete extends SpecialPage {
                }
 
                $out = $this->getOutput();
-               $archive = new PageArchive( $this->mTargetObj );
+               $archive = new PageArchive( $this->mTargetObj, $this->getConfig() );
                wfRunHooks( 'UndeleteForm::undelete', array( &$archive, $this->mTargetObj ) );
                $ok = $archive->undelete(
                        $this->mTargetTimestamp,
index 35141d8..a8b97d7 100644 (file)
@@ -37,11 +37,9 @@ class SpecialUnlockdb extends FormSpecialPage {
        }
 
        public function checkExecutePermissions( User $user ) {
-               global $wgReadOnlyFile;
-
                parent::checkExecutePermissions( $user );
                # If the lock file isn't writable, we can do sweet bugger all
-               if ( !file_exists( $wgReadOnlyFile ) ) {
+               if ( !file_exists( $this->getConfig()->get( 'ReadOnlyFile' ) ) ) {
                        throw new ErrorPageError( 'lockdb', 'databasenotlocked' );
                }
        }
@@ -62,20 +60,19 @@ class SpecialUnlockdb extends FormSpecialPage {
        }
 
        public function onSubmit( array $data ) {
-               global $wgReadOnlyFile;
-
                if ( !$data['Confirm'] ) {
                        return Status::newFatal( 'locknoconfirm' );
                }
 
+               $readOnlyFile = $this->getConfig()->get( 'ReadOnlyFile' );
                wfSuppressWarnings();
-               $res = unlink( $wgReadOnlyFile );
+               $res = unlink( $readOnlyFile );
                wfRestoreWarnings();
 
                if ( $res ) {
                        return Status::newGood();
                } else {
-                       return Status::newFatal( 'filedeleteerror', $wgReadOnlyFile );
+                       return Status::newFatal( 'filedeleteerror', $readOnlyFile );
                }
        }
 
index 743c587..36ec09e 100644 (file)
@@ -44,7 +44,6 @@ class UnusedimagesPage extends ImageQueryPage {
        }
 
        function getQueryInfo() {
-               global $wgCountCategorizedImagesAsUsed;
                $retval = array(
                        'tables' => array( 'image', 'imagelinks' ),
                        'fields' => array(
@@ -58,7 +57,7 @@ class UnusedimagesPage extends ImageQueryPage {
                        'join_conds' => array( 'imagelinks' => array( 'LEFT JOIN', 'il_to = img_name' ) )
                );
 
-               if ( $wgCountCategorizedImagesAsUsed ) {
+               if ( $this->getConfig()->get( 'CountCategorizedImagesAsUsed' ) ) {
                        // Order is significant
                        $retval['tables'] = array( 'image', 'page', 'categorylinks',
                                'imagelinks' );
index cb821cb..b5b4176 100644 (file)
@@ -159,15 +159,13 @@ class SpecialUploadStash extends UnlistedSpecialPage {
         * @return bool Success
         */
        private function outputThumbFromStash( $file, $params ) {
-               // this global, if it exists, points to a "scaler", as you might find in
+               $flags = 0;
+               // this config option, if it exists, points to a "scaler", as you might find in
                // the Wikimedia Foundation cluster. See outputRemoteScaledThumb(). This
                // is part of our horrible NFS-based system, we create a file on a mount
                // point here, but fetch the scaled file from somewhere else that
                // happens to share it over NFS.
-               global $wgUploadStashScalerBaseUrl;
-
-               $flags = 0;
-               if ( $wgUploadStashScalerBaseUrl ) {
+               if ( $this->getConfig()->get( 'UploadStashScalerBaseUrl' ) ) {
                        $this->outputRemoteScaledThumb( $file, $params, $flags );
                } else {
                        $this->outputLocallyScaledThumb( $file, $params, $flags );
@@ -230,11 +228,10 @@ class SpecialUploadStash extends UnlistedSpecialPage {
         * @return bool Success
         */
        private function outputRemoteScaledThumb( $file, $params, $flags ) {
-               // This global probably looks something like
+               // This option probably looks something like
                // 'http://upload.wikimedia.org/wikipedia/test/thumb/temp'. Do not use
                // trailing slash.
-               global $wgUploadStashScalerBaseUrl;
-               $scalerBaseUrl = $wgUploadStashScalerBaseUrl;
+               $scalerBaseUrl = $this->getConfig()->get( 'UploadStashScalerBaseUrl' );
 
                if ( preg_match( '/^\/\//', $scalerBaseUrl ) ) {
                        // this is apparently a protocol-relative URL, which makes no sense in this context,
index 0ec85ba..cefdad0 100644 (file)
@@ -328,9 +328,7 @@ class UserrightsPage extends SpecialPage {
         * @return Status
         */
        public function fetchUser( $username ) {
-               global $wgUserrightsInterwikiDelimiter;
-
-               $parts = explode( $wgUserrightsInterwikiDelimiter, $username );
+               $parts = explode( $this->getConfig()->get( 'UserrightsInterwikiDelimiter' ), $username );
                if ( count( $parts ) < 2 ) {
                        $name = trim( $username );
                        $database = '';
@@ -417,13 +415,12 @@ class UserrightsPage extends SpecialPage {
         * Output a form to allow searching for a user
         */
        function switchForm() {
-               global $wgScript;
                $this->getOutput()->addHTML(
                        Html::openElement(
                                'form',
                                array(
                                        'method' => 'get',
-                                       'action' => $wgScript,
+                                       'action' => wfScript(),
                                        'name' => 'uluser',
                                        'id' => 'mw-userrights-form1'
                                )
index c54d9f4..38f1808 100644 (file)
@@ -54,8 +54,7 @@ class WantedPagesPage extends WantedQueryPage {
        }
 
        function getQueryInfo() {
-               global $wgWantedPagesThreshold;
-               $count = $wgWantedPagesThreshold - 1;
+               $count = $this->getConfig()->get( 'WantedPagesThreshold' ) - 1;
                $query = array(
                        'tables' => array(
                                'pagelinks',
index 5691e50..8f2f86b 100644 (file)
@@ -38,8 +38,6 @@ class SpecialWatchlist extends ChangesListSpecialPage {
         * @param string $subpage
         */
        function execute( $subpage ) {
-               global $wgEnotifWatchlist, $wgShowUpdatedMarker;
-
                // Anons don't get a watchlist
                $this->requireLogin( 'watchlistanontext' );
 
@@ -66,7 +64,8 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $user = $this->getUser();
                $opts = $this->getOptions();
 
-               if ( ( $wgEnotifWatchlist || $wgShowUpdatedMarker )
+               $config = $this->getConfig();
+               if ( ( $config->get( 'EnotifWatchlist' ) || $config->get( 'ShowUpdatedMarker' ) )
                        && $request->getVal( 'reset' )
                        && $request->wasPosted()
                ) {
@@ -198,8 +197,6 @@ class SpecialWatchlist extends ChangesListSpecialPage {
         * @return bool|ResultWrapper Result or false (for Recentchangeslinked only)
         */
        public function doMainQuery( $conds, $opts ) {
-               global $wgShowUpdatedMarker;
-
                $dbr = $this->getDB();
                $user = $this->getUser();
 
@@ -238,7 +235,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                        ),
                );
 
-               if ( $wgShowUpdatedMarker ) {
+               if ( $this->getConfig()->get( 'ShowUpdatedMarker' ) ) {
                        $fields[] = 'wl_notificationtimestamp';
                }
                if ( $limitWatchlist ) {
@@ -332,8 +329,6 @@ class SpecialWatchlist extends ChangesListSpecialPage {
         * @param FormOptions $opts
         */
        public function outputChangesList( $rows, $opts ) {
-               global $wgShowUpdatedMarker, $wgRCShowWatchingUsers;
-
                $dbr = $this->getDB();
                $user = $this->getUser();
                $output = $this->getOutput();
@@ -366,13 +361,13 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                        $rc = RecentChange::newFromRow( $obj );
                        $rc->counter = $counter++;
 
-                       if ( $wgShowUpdatedMarker ) {
+                       if ( $this->getConfig()->get( 'ShowUpdatedMarker' ) ) {
                                $updated = $obj->wl_notificationtimestamp;
                        } else {
                                $updated = false;
                        }
 
-                       if ( $wgRCShowWatchingUsers && $user->getOption( 'shownumberswatching' ) ) {
+                       if ( $this->getConfig()->get( 'RCShowWatchingUsers' ) && $user->getOption( 'shownumberswatching' ) ) {
                                $rc->numberofWatchingusers = $dbr->selectField( 'watchlist',
                                        'COUNT(*)',
                                        array(
@@ -494,14 +489,13 @@ class SpecialWatchlist extends ChangesListSpecialPage {
        }
 
        function setTopText( FormOptions $opts ) {
-               global $wgEnotifWatchlist, $wgShowUpdatedMarker;
-
                $nondefaults = $opts->getChangedValues();
                $form = "";
                $user = $this->getUser();
 
                $dbr = $this->getDB();
                $numItems = $this->countItems( $dbr );
+               $showUpdatedMarker = $this->getConfig()->get( 'ShowUpdatedMarker' );
 
                // Show watchlist header
                $form .= "<p>";
@@ -509,16 +503,16 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                        $form .= $this->msg( 'nowatchlist' )->parse() . "\n";
                } else {
                        $form .= $this->msg( 'watchlist-details' )->numParams( $numItems )->parse() . "\n";
-                       if ( $wgEnotifWatchlist && $user->getOption( 'enotifwatchlistpages' ) ) {
+                       if ( $this->getConfig()->get( 'EnotifWatchlist' ) && $user->getOption( 'enotifwatchlistpages' ) ) {
                                $form .= $this->msg( 'wlheader-enotif' )->parse() . "\n";
                        }
-                       if ( $wgShowUpdatedMarker ) {
+                       if ( $showUpdatedMarker ) {
                                $form .= $this->msg( 'wlheader-showupdated' )->parse() . "\n";
                        }
                }
                $form .= "</p>";
 
-               if ( $numItems > 0 && $wgShowUpdatedMarker ) {
+               if ( $numItems > 0 && $showUpdatedMarker ) {
                        $form .= Xml::openElement( 'form', array( 'method' => 'post',
                                'action' => $this->getPageTitle()->getLocalURL(),
                                'id' => 'mw-watchlist-resetbutton' ) ) . "\n" .
index 60ac02f..7dc6da1 100644 (file)
@@ -42,7 +42,6 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
        }
 
        function execute( $par ) {
-               global $wgQueryPageDefaultLimit;
                $out = $this->getOutput();
 
                $this->setHeaders();
@@ -52,7 +51,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
 
                $opts->add( 'target', '' );
                $opts->add( 'namespace', '', FormOptions::INTNULL );
-               $opts->add( 'limit', $wgQueryPageDefaultLimit );
+               $opts->add( 'limit', $this->getConfig()->get( 'QueryPageDefaultLimit' ) );
                $opts->add( 'from', 0 );
                $opts->add( 'back', 0 );
                $opts->add( 'hideredirs', false );
@@ -101,8 +100,6 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
         * @param int $back Display from this article ID at backwards scrolling (default: 0)
         */
        function showIndirectLinks( $level, $target, $limit, $from = 0, $back = 0 ) {
-               global $wgMaxRedirectLinksRetrieved, $wgUseLinkNamespaceDBFields;
-
                $out = $this->getOutput();
                $dbr = wfGetDB( DB_SLAVE );
 
@@ -126,9 +123,10 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                        'il_to' => $target->getDBkey(),
                );
 
+               $useLinkNamespaceDBFields = $this->getConfig()->get( 'UseLinkNamespaceDBFields' );
                $namespace = $this->opts->getValue( 'namespace' );
                if ( is_int( $namespace ) ) {
-                       if ( $wgUseLinkNamespaceDBFields ) {
+                       if ( $useLinkNamespaceDBFields ) {
                                $conds['pagelinks']['pl_from_namespace'] = $namespace;
                                $conds['templatelinks']['tl_from_namespace'] = $namespace;
                                $conds['imagelinks']['il_from_namespace'] = $namespace;
@@ -151,8 +149,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                        $conds['pagelinks'][] = 'rd_from is NOT NULL';
                }
 
-               $queryFunc = function ( $dbr, $table, $fromCol ) use ( $conds, $target, $limit ) {
-                       global $wgUseLinkNamespaceDBFields;
+               $queryFunc = function ( $dbr, $table, $fromCol ) use ( $conds, $target, $limit, $useLinkNamespaceDBFields ) {
                        // Read an extra row as an at-end check
                        $queryLimit = $limit + 1;
                        $on = array(
@@ -160,7 +157,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                                'rd_title' => $target->getDBkey(),
                                'rd_interwiki = ' . $dbr->addQuotes( '' ) . ' OR rd_interwiki IS NULL'
                        );
-                       if ( $wgUseLinkNamespaceDBFields ) { // migration check
+                       if ( $useLinkNamespaceDBFields ) { // migration check
                                $on['rd_namespace'] = $target->getNamespace();
                        }
                        // Inner LIMIT is 2X in case of stale backlinks with wrong namespaces
@@ -278,7 +275,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
 
                        if ( $row->rd_from && $level < 2 ) {
                                $out->addHTML( $this->listItem( $row, $nt, $target, true ) );
-                               $this->showIndirectLinks( $level + 1, $nt, $wgMaxRedirectLinksRetrieved );
+                               $this->showIndirectLinks( $level + 1, $nt, $this->getConfig()->get( 'MaxRedirectLinksRetrieved' ) );
                                $out->addHTML( Xml::closeElement( 'li' ) );
                        } else {
                                $out->addHTML( $this->listItem( $row, $nt, $target ) );
@@ -415,8 +412,6 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
        }
 
        function whatlinkshereForm() {
-               global $wgScript;
-
                // We get nicer value from the title object
                $this->opts->consumeValue( 'target' );
                // Reset these for new requests
@@ -426,7 +421,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                $namespace = $this->opts->consumeValue( 'namespace' );
 
                # Build up the form
-               $f = Xml::openElement( 'form', array( 'action' => $wgScript ) );
+               $f = Xml::openElement( 'form', array( 'action' => wfScript() ) );
 
                # Values that should not be forgotten
                $f .= Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() );
index e05faef..bd01461 100644 (file)
@@ -41,8 +41,6 @@ class WithoutInterwikiPage extends PageQueryPage {
        }
 
        function getPageHeader() {
-               global $wgScript;
-
                # Do not show useless input form if special page is cached
                if ( $this->isCached() ) {
                        return '';
@@ -51,7 +49,7 @@ class WithoutInterwikiPage extends PageQueryPage {
                $prefix = $this->prefix;
                $t = $this->getPageTitle();
 
-               return Html::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) ) . "\n" .
+               return Html::openElement( 'form', array( 'method' => 'get', 'action' => wfScript() ) ) . "\n" .
                        Html::openElement( 'fieldset' ) . "\n" .
                        Html::element( 'legend', null, $this->msg( 'withoutinterwiki-legend' )->text() ) . "\n" .
                        Html::hidden( 'title', $t->getPrefixedText() ) . "\n" .
index 0a3d2fd..5fff51d 100644 (file)
        "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",
+       "logentry-upload-upload": "$1 {{GENDER:$2|загрузіў|загрузіла}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|загрузіў|загрузіла}} новую вэрсію $3",
        "rightsnone": "(няма)",
        "feedback-bugornote": "Калі Вы гатовы падрабязна апісаць тэхнічную праблему, калі ласка [$1 паведаміце пра памылку]. \nУ адваротным выпадку, Вы можаце выкарыстоўваць простую форму пададзеную ніжэй. Ваш камэнтар будзе дададзены на старонку «[$3 $2]», разам з Вашым іменем удзельніка і выкарыстоўваемым браўзэрам.",
        "feedback-subject": "Тэма:",
index e5d6366..c054fa8 100644 (file)
        "changeemail-password": "Хьан пароль «{{SITENAME}}» проектан:",
        "changeemail-submit": "Хийца email",
        "changeemail-cancel": "Цаоьшу",
+       "changeemail-throttled": "Хьо дукха гӀиртира.\nДехар до, собар де $1 юха гӀортале.",
        "resettokens": "Токенаш кхоссар",
        "resettokens-text": "Хьан йиш ю токенаш кхосса, цара йиш хуьлуьйту цхьаболу долара хаамашна тӀекхача, уьш ю хьан дӀаяздар ца вовшахтесна. \n\nХьона иза оьшу, ахьа хьай токенаш цхьам гучу яьхна елахь я хьан аккаунт йохийна елахь.",
        "resettokens-no-tokens": "Кхосса токенаш яц.",
        "blankarticle": "<strong>ДӀахьедар:</strong> Ахьа кхуллуш йолу агӀо еса ю.\nЮху кнопка «{{int:savearticle}}» тӀетаӀаяхь, агӀо цхьа чулацам боцуш кхуллур ю.",
        "anoneditwarning": "'''Тергам бе''': Ахьа хьай цӀарца тадарш деш дац. Хьан IP-адрес дӀаяздина хира ду хӀокху агӀон истори чу.",
        "anonpreviewwarning": "''Системин чу цагӀахь хьан IP-адрес агӀона истори чу дӀаяз лур ду.''",
+       "missingsummary": "'''Дагадаийтар.''' Ахьа хийцамаш лаьцна доца яздина дац. Кнопка «{{int:savearticle}}» юху тӀетаӀича хийцамах лаьцна хӀума доцуш Ӏалашбира бу.",
        "missingcommenttext": "Дехар до дӀаязбе хайн хаам лахахь.",
+       "missingcommentheader": "'''Дагадаийтар.''' Ахьа хӀокху къамелан дӀахьедар/корта билгал бина бац. Кнопка «{{int:savearticle}}» юху тӀетаӀича хийцамах лаьцна хӀума доцуш Ӏалашбира бу.",
        "summary-preview": "Цуьнах лаьцна хирду:",
        "subject-preview": "Коьрта могӀа хира бу:",
        "blockedtitle": "Декъашхочун блоктоьхана",
        "logentry-rights-rights": "$1 {{GENDER:$2|хийцина}} $3 бакъо $4 → $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|хийцина}} хӏокхуна $3 бакъо",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|вара|яра}} автоматически {{GENDER:$2|сихьа ваьлла|сихьа яьлла}} $4 $5 чу",
+       "logentry-upload-revert": "$1 {{GENDER:$2|чуяьккхина}} $3",
        "rightsnone": "(яц)",
        "feedback-bugornote": "Хьайн техникин халонах лаьцна яздан хӀума делахь, дехар до, [$1 хаам бе тхоьга].\nДацахь хьан йиш ю хӀокху атта кепаца «[$3 $2]» агӀонг къамел тӀетоха хьан декъашхочун цӀарца, кхин лелош йолу браузер билгал еш.",
        "feedback-subject": "Къамел:",
index b505ce4..587a411 100644 (file)
@@ -46,7 +46,8 @@
                        "Søren Løvborg",
                        "Tjernobyl",
                        "Urhixidur",
-                       "아라"
+                       "아라",
+                       "Thomsen"
                ]
        },
        "tog-underline": "Understreg henvisninger:",
        "uploadwarning": "Advarsel",
        "uploadwarning-text": "Vær venlig at ændre filbeskrivelsen nedenfor og prøv igen.",
        "savefile": "Gem fil",
-       "uploadedimage": "lagde \"[[$1]]\" op",
-       "overwroteimage": "lagde en ny version af \"[[$1]]\" op",
        "uploaddisabled": "Desværre er funktionen til at lægge filer op afbrudt på denne server.",
        "copyuploaddisabled": "Upload via URL er slået fra.",
        "uploaddisabledtext": "Oplægning af filer er deaktiveret.",
        "watchlist-details": "Du har $1 {{PLURAL:$1|side|sider}} på din overvågningsliste (ekskl. diskussionssider).",
        "wlheader-enotif": "E-mail-underretning er slået til.",
        "wlheader-showupdated": "Sider, der er ændret siden dit sidste besøg, er vist med '''fed skrift'''.",
-       "wlnote2": "Nedenfor ses ændringerne i {{PLURAL:$1|den sidste time|de sidste <strong>$1</strong> timer}} op til den $2 kl. $3.",
+       "wlnote": "Nedenfor ses {{PLURAL:$1|den seneste ændring|de seneste '''$1''' ændringer}} i {{PLURAL:$2|den sidste time|de sidste '''$2''' timer}} op til den $3 kl. $4.",
        "wlshowlast": "Vis de seneste $1 timer $2 dage $3",
        "watchlist-options": "Indstillinger for overvågningslisten",
        "watching": "Tilføjer overvågning …",
index e88fb72..ab5c5f0 100644 (file)
        "logentry-rights-rights": "$1 {{GENDER:$2|änderte}} die Gruppenzugehörigkeit für $3 von $4 zu $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|änderte}} die Gruppenzugehörigkeit für $3",
        "logentry-rights-autopromote": "$1 wurde automatisch von $4 zu $5 {{GENDER:$2|zugeordnet}}",
+       "logentry-upload-upload": "$1 {{GENDER:$2|lud}} $3 hoch",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|lud}} eine neue Version von $3 hoch",
+       "logentry-upload-revert": "$1 {{GENDER:$2|lud}} $3 hoch",
        "rightsnone": "(–)",
        "feedback-bugornote": "Sofern du detailliert ein technisches Problem beschreiben möchtest, melde bitte [$1 einen Fehler].\nAnderenfalls kannst du auch das untenstehende einfache Formular nutzen. Dein Kommentar wird, zusammen mit deinem Benutzernamen und der Version des von dir verwendeten Webbrowsers sowie Betriebssystems, auf der Seite „[$3 $2]“ hinzugefügt.",
        "feedback-subject": "Betreff:",
index a67d33e..6691b64 100644 (file)
@@ -22,6 +22,7 @@
        "tog-watchdefault": "Zûnta al pàgini e i file mudifichê int i tgnû 'd ôc specêl.",
        "tog-watchmoves": "Zûnta al pàgini e i file spustê int i tgnû 'd ôc specêl.",
        "tog-watchdeletion": "Zûnta al pàgini e i file scanşlê int i tgnû 'd ôc specêl.",
+       "tog-watchrollback": "Zûta al pàgini in dóv' ó fât al ritōren a la pàgina 'd préma a i tgnû 'd ôc specêl",
        "tog-minordefault": "Sògna ògni mudéfica cme céca (sōl cme pre-stabilî)",
        "tog-previewontop": "Fà vèder còl ch' ò fât sōver la caşèla ed mudéfica e mìa sòta.",
        "tog-previewonfirst": "Fà vèder còl ch' ò fât almēno 'na vôlta préma 'd salvêr",
        "preview": "Guêrda préma",
        "showpreview": "Guêrda préma 'd salvêr",
        "showdiff": "Guêrda i cambiamèint",
+       "blankarticle": "<strong>Atèinti:</strong>la pàgina che t'é drē fêr la gh'à gnînto dèinter. S' ét tōren a schisêr in sém a \"{{int:savearticle}}\", la pàgina la srà fât sèinsa gnînto dèinter.",
        "anoneditwarning": "'''Atensiòun:''' Ingrès mìa fât. Al tó indirés IP al srà sgnê int la stòria ed cla pàgina chè.",
        "anonpreviewwarning": "\"An n'é mìa stê fât l'ingrès. Mèinter es sêlva la pàgina, l'indirés IP al srà sgnê int la stòria 'd la pàgina.\"",
        "missingsummary": "'''Atensiòun:''' an n'é mìa stê precişê al mutîv de sté mudéfica. S'es tōrna a clichêr insém a \"{{int:savearticle}}\" la mudéfica la gnirà salvêda cun al mutîv vōd.",
        "rev-deleted-event": "(asiòun dal log armôsa)",
        "rev-deleted-user-contribs": "(nòm utèint o indirés IP armôs - mudéfica lughêda da la stòria)",
        "rev-deleted-text-permission": "Cla versiòun ché 'd la pàgina l'é stêda <strong> scanşlêda </strong>. \nConsultêr al [{{fullurl:{{#Special:Log}}/delete|page={{PAGENAMEE}}}} log dal canşladûri] per nōv particulêr.",
+       "rev-suppressed-text-permission": "Cla versiòun ché 'd la pàgina l'é stêda <strong> scanşlêda </strong>. Consultêr al [{{fullurl:{{#Special:Log}}/ suppress |page={{ FULLPAGENAMEE }}}} log dal canşladûri] per nōv particulêr.",
        "rev-deleted-text-unhide": "Cla versiòun ché 'd la pàgina l'é stêda <strong> scanşlêda </strong>. Consultêr al [{{fullurl:{{#Special:Log}}/delete|page={{PAGENAMEE}}}} log dal canşladûri] per nōv particulêr.\nS' l' é necesâri a j aministradōr a gh'é incòra permés [$1 ed guardêr cla versiòun ché].",
        "rev-suppressed-text-unhide": "Cla versiòun ché 'd la pàgina l'é stêda <strong> scanşlêda </strong>. Consultêr al [{{fullurl:{{#Special:Log}}/delete|page={{PAGENAMEE}}}} log dal canşladûri] per nōv particulêr.\nS' l' é necesâri a j aministradōr a gh'é incòra permés [$1 ed guardêr cla versiòun ché].",
        "rev-deleted-text-view": "Cla versiòun ché 'd la pàgina l'é stêda <strong> scanşlêda </strong>. J aministradōr a pōlen incòra guardêrla; \nconsultêr al [{{fullurl:{{#Special:Log}}/delete|page={{PAGENAMEE}}}} log dal canşladûri] per nōv particulêr.",
        "powersearch-togglenone": "Nisûn",
        "powersearch-remember": "Arcôrda la siēlta per êtri sèirchi ch'é vō fêr",
        "search-external": "Sèirca fâta fōra",
+       "searchdisabled": "La sèirca intêrna ed {{SITENAME}} l'a funsiòuna mìa; int al mèinter a s' pōl pruvêr a druvêr un mutōr ed sèirca d'ed fōra cme Google. (A gh' è da nutêr però che còl che gh'é dèinter in {{SITENAME}} che es câten in chi mutōr a prém èser mìa arnuvê.)",
+       "search-error": "É sucès un erōr mèinter a's fêva la sèirca:$1",
        "preferences": "Preferèinsa",
        "mypreferences": "Preferèinsi",
        "prefs-edits": "Mudéfichi fâti:",
+       "prefsnologintext2": "Es prèiga ed $1 per impustêr al preferèinsi 'd l'utèint.",
        "prefs-skin": "Aspèt grâfich (skin)",
        "skin-preview": "Guêrda préma",
        "datedefault": "Nisóna preferèinsa",
+       "prefs-labs": "Funsiòun adâti in sperimèint",
+       "prefs-user-pages": "Pàgini utèint",
+       "prefs-personal": "Prufîl utèint",
+       "prefs-rc": "Ûltmi mudéfichi",
+       "prefs-watchlist": "Tgnîr sòt ôc",
+       "prefs-watchlist-days": "Nómer ed dé da fêr vèder int i tgnû 'd ôc specêl:",
+       "prefs-watchlist-days-max": "Mâsim $1 {{PLURAL:$1|dé}}",
        "saveprefs": "Sêlva",
        "prefs-editing": "Caşèla 'd mudéfica",
        "rows": "Rîghi",
index 11c6c60..00159a4 100644 (file)
        "action-pagelang": "change the page language",
        "log-name-pagelang": "Change language log",
        "log-description-pagelang": "This is a log of changes in page languages.",
-       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|changed}} page language for $3 from $4 to $5."
+       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|changed}} page language for $3 from $4 to $5.",
+       "default-skin-not-found": "Whoops! The default skin for your wiki (<code>$wgDefaultSkin</code>), <code>$1</code>, is not available.\n\nYour installation seems to include the following skins. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable them and choose the default.\n\n$2\n\n; If you have just installed MediaWiki:\n: You probably installed from git, or directly from the source code using some other method. This is expected.\n:* Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory].\n:* Download the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it.\n: Doing this should not interfere with your git repository if you're a MediaWiki developer.\n\n; If you have just upgraded MediaWiki:\n: MediaWiki 1.24 and newer no longer automatically enables installed skins (see [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). You can paste the following lines into <code>LocalSettings.php</code> to enable all currently installed skins:\n\n<pre>$3</pre>\n\n; If you have just modified <code>LocalSettings.php</code>:\n: Double-check the skin names for typos.",
+       "default-skin-not-found-no-skins": "Whoops! The default skin for your wiki (<code>$wgDefaultSkin</code>), <code>$1</code>, is not available.\n\nYou have no installed skins.\n\n; If you have just installed MediaWiki:\n: You probably installed from git, or directly from the source code using some other method. This is expected.\n:* Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory].\n:* Download the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it.\n: Doing this should not interfere with your git repository if you're a MediaWiki developer. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable skins and choose the default.\n",
+       "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (enabled)",
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''disabled''')"
 }
index c546f96..a28151d 100644 (file)
        "hidetoc": "ocultar",
        "collapsible-collapse": "Contraer",
        "collapsible-expand": "Expandir",
+       "confirmable-confirm": "¿Estás {{GENDER:$1|seguro|segura}}?",
+       "confirmable-yes": "Sí",
+       "confirmable-no": "No",
        "thisisdeleted": "¿Ver o restaurar $1?",
        "viewdeleted": "¿Quieres ver $1?",
        "restorelink": "{{PLURAL:$1|una edición borrada|$1 ediciones borradas}}",
        "blocklist-userblocks": "Ocultar bloqueos de cuenta",
        "blocklist-tempblocks": "Ocultar bloqueos temporales",
        "blocklist-addressblocks": "Ocultar bloqueos de una sola dirección IP",
-       "blocklist-rangeblocks": "Ocultar bloqueos de rango",
+       "blocklist-rangeblocks": "Ocultar bloqueos por intervalo",
        "blocklist-timestamp": "Fecha y hora",
        "blocklist-target": "Destino",
        "blocklist-expiry": "Caduca",
        "logentry-rights-rights": "$1 modificó los grupos a los que pertenece $3: de $4 a $5",
        "logentry-rights-rights-legacy": "$1 modificó los grupos a los que pertenece $3",
        "logentry-rights-autopromote": "$1 ha sido {{GENDER:$2|promocionado|promocionada}} automáticamente de $4 a $5",
+       "logentry-upload-upload": "$1 {{GENDER:$2|subió}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|subió}} una nueva versión de $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|subió}} $3",
        "rightsnone": "(ninguno)",
        "feedback-bugornote": "Si estás preparado para describir en detalle un problema técnico, [$1 informa de un bug] por favor.\n\nEn otro caso, puedes usar el siguiente formulario. Tu comentario será añadido a la página [$3 $2], junto con tu nombre de usuario y el navegador que usas.",
        "feedback-subject": "Asunto:",
index 51e07bd..e7891f2 100644 (file)
@@ -53,6 +53,7 @@
        "tog-watchdefault": "صفحه‌ها و پرونده‌هایی که ویرایش می‌کنم به فهرست پی‌گیری‌هایم افزوده شود",
        "tog-watchmoves": "صفحه‌ها و پرونده‌هایی که منتقل می‌کنم به فهرست پی‌گیری‌هایم افزوده شود",
        "tog-watchdeletion": "صفحه‌ها و پرونده‌هایی که حذف می‌کنم به فهرست پی‌گیری‌هایم افزوده شود",
+       "tog-watchrollback": "افزودن صفحاتی که واگردانی کردم برای فهرست پیگیری‌هایم",
        "tog-minordefault": "همهٔ ویرایش‌ها به طور پیش‌فرض به عنوان «جزئی» علامت بخورد",
        "tog-previewontop": "پیش‌نمایش قبل از جعبهٔ ویرایش نمایش یابد",
        "tog-previewonfirst": "پیش‌نمایش هنگام اولین ویرایش نمایش یابد",
        "uploadwarning": "هشدار بارگذاری",
        "uploadwarning-text": "لطفاً توضیحات پرونده را در زیر تغییر دهید و دوباره تلاش کنید.",
        "savefile": "ذخیرهٔ پرونده",
-       "uploadedimage": "«[[$1]]» را بارگذاری کرد",
-       "overwroteimage": "نسخه جدیدی از  «[[$1]]» را بارگذاری کرد",
        "uploaddisabled": "بارگذاری غیرفعال است.",
        "copyuploaddisabled": "بارگذاری از طریق نشانی اینترنتی غیرفعال است.",
        "uploaddisabledtext": "امکان بارگذاری پرونده غیرفعال است.",
        "nolicense": "هیچ کدام انتخاب نشده‌است",
        "licenses-edit": "گزینه‌های مجوز ویرایش",
        "license-nopreview": "(پیش‌نمایش وجود ندارد)",
-       "upload_source_url": "(یک نشانی اینترنتی معتبر و قابل دسترسی برای عموم)",
-       "upload_source_file": "(پرÙ\88Ù\86دÙ\87â\80\8cاÛ\8c Ø¯Ø± Ø±Ø§Û\8cاÙ\86Ù\87Ù\94 Ø´Ù\85ا)",
+       "upload_source_url": "(شما یک پرونده انتخاب از یک URL معتبر و دسترس عموم انتخاب کردید)",
+       "upload_source_file": "(پرÙ\88Ù\86دÙ\87â\80\8cاÛ\8c Ø§Ø² Ø±Ø§Û\8cاÙ\86Ù\87Ù\94 Ø´Ù\85ا Ø§Ù\86تخاب Ø´Ø¯Ù\87â\80\8cاست)",
        "listfiles-delete": "حذف",
        "listfiles-summary": "این صفحهٔ ویژه تمام پرونده‌های بارگذاری‌شده را نمایش می‌دهد.",
        "listfiles_search_for": "جستجو به دنبال نام پرونده چندرسانه‌ای:",
        "watchlist-details": "بدون احتساب صفحه‌های جداگانهٔ بحث، {{PLURAL:$1|$1 صفحه|$1 صفحه}} در فهرست پی‌گیری‌های شما قرار {{PLURAL:$1|دارد|دارند}}.",
        "wlheader-enotif": "آگاه‌سازی رایانامه‌ای فعال است.",
        "wlheader-showupdated": "صفحه‌هایی که پس از آخرین بازدید شما تغییر کرده‌اند '''پررنگ''' نمایش داده شده‌اند.",
-       "wlnote": "در زیر {{PLURAL:$1|تغییری|$1 تغییری}} که در {{PLURAL:$2|ساعت|$2 ساعت}} گذشته انجام شده موجود است، تاریخ آخرین بازیابی: $3، $4",
+       "wlnote": "در زیر {{PLURAL:$1|تغییری|<strong>$1</strong> تغییری}} که در {{PLURAL:$2|ساعت|<strong>$2</strong> ساعت}} گذشته انجام شده موجود است، تاریخ آخرین بازیابی: $3، $4",
        "wlshowlast": "نمایش آخرین $1 ساعت $2 روز $3",
        "watchlist-options": "گزینه‌های پی‌گیری",
        "watching": "پی‌گیری...",
        "logentry-rights-rights": "$1 عضویت $3 را از گروه $4 به $5 {{GENDER:$2|تغییر داد}}",
        "logentry-rights-rights-legacy": "$1 گروه عضویت $3 را {{GENDER:$2|تغییر داد}}",
        "logentry-rights-autopromote": "$1 به طور خودکار از $4 به $5 {{GENDER:$2|ارتقاء داد}}",
+       "logentry-upload-upload": "$1 {{GENDER:$2|بارگذاری کرد}} $3",
+       "logentry-upload-overwrite": "$1 یک نسخهٔ جدید {{GENDER:$2|بارگذاری‌کرد}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|بارگذاری کرد}} $3",
        "rightsnone": "(هیچ)",
        "feedback-bugornote": "اگر آماده‌اید تا مشکلی فنی را با جزئیاتش شرح دهید لطفاً [$1 یک ایراد گزارش دهید]. در غیر این صورت می‌توانید از فرم سادهٔ زیر استفاده کنید. نظر شما به همراه نام کاربری و مرورگرتان به صفحهٔ «[$3 $2]» افزوده خواهد شد.",
        "feedback-subject": "موضوع:",
index c947ff7..7cab271 100644 (file)
@@ -86,7 +86,7 @@
        "underline-never": "Ei koskaan",
        "underline-default": "Ulkoasun tai selaimen oletustapa",
        "editfont-style": "Muokkauskentän kirjasintyyppi",
-       "editfont-default": "Selaimen oletus",
+       "editfont-default": "Selaimen vakioasetus",
        "editfont-monospace": "Tasalevyinen kirjasin",
        "editfont-sansserif": "Sans-serif-kirjasin",
        "editfont-serif": "Serif-kirjasin",
        "mergehistory-from": "Lähdesivu:",
        "mergehistory-into": "Kohdesivu:",
        "mergehistory-list": "Sivuhistoria, joka voidaan yhdistää",
-       "mergehistory-merge": "Seuraavat versiot sivusta [[:$1]] muutokset voidaan yhdistää sivuun [[:$2]]. \n\nVoit valita, mitä versioita yhdistetään. Pallomerkillä valitaan vain ne versiot, jotka on luotu määriteltynä ajankohtana tai sitä ennen.\nOta huomioon, että jos käytät navigaatiolinkkejä, tekemäsi valinta poistuu.",
+       "mergehistory-merge": "Seuraavat versiot sivusta [[:$1]] voidaan yhdistää sivuun [[:$2]]. \n\nValintamerkin sijoituksella voit yhdistää vain ne versiot, jotka on luotu valittuna ajankohtana tai sitä ennen (listassa alaspäin). \nOta huomioon, että jos käytät navigaatiolinkkejä, tekemäsi valinta poistuu.",
        "mergehistory-go": "Etsi muokkaukset, jotka voidaan yhdistää",
        "mergehistory-submit": "Yhdistä versiot",
-       "mergehistory-empty": "Ei liitettäviä muutoksia.",
+       "mergehistory-empty": "Mitään versioita ei voida yhdistää.",
        "mergehistory-success": "$3 {{PLURAL:$3|versio|versiota}} sivusta [[:$1]] yhdistettiin onnistuneesti sivuun [[:$2]].",
-       "mergehistory-fail": "Muutoshistorian liittäminen epäonnistui. Tarkista määritellyt sivut ja versiot.",
+       "mergehistory-fail": "Sivuhistorioiden yhdistämistä ei voida suorittaa. Tarkista lähde- ja kohdesivujen nimet sekä versioiden aikamääritys.",
        "mergehistory-fail-toobig": "Sivuhistorian yhdistämistä ei voi tehdä, koska enemmän kuin sallittu määrä $1 {{PLURAL:$1|versio|versiota}} siirrettäisiin.",
        "mergehistory-no-source": "Lähdesivua $1 ei ole olemassa.",
        "mergehistory-no-destination": "Kohdesivua $1 ei ole olemassa.",
-       "mergehistory-invalid-source": "Lähdesivulla pitää olla kelvollinen nimi.",
-       "mergehistory-invalid-destination": "Kohdesivulla pitää olla kelvollinen nimi.",
-       "mergehistory-autocomment": "Yhdisti sivun [[:$1]] sivuun [[:$2]]",
+       "mergehistory-invalid-source": "Lähdesivun nimen pitää olla kelvollinen.",
+       "mergehistory-invalid-destination": "Kohdesivun nimen pitää olla kelvollinen.",
+       "mergehistory-autocomment": "Ak: Yhdisti sivun [[:$1]] sivuun [[:$2]]",
        "mergehistory-comment": "Yhdisti sivun [[:$1]] sivuun [[:$2]]: $3",
        "mergehistory-same-destination": "Lähde- ja kohdesivut eivät voi olla samat",
        "mergehistory-reason": "Syy:",
        "group-bot": "botit",
        "group-sysop": "ylläpitäjät",
        "group-bureaucrat": "byrokraatit",
-       "group-suppress": "häivytysoikeuden käyttäjät",
+       "group-suppress": "häivyttäjät",
        "group-all": "(kaikki)",
        "group-user-member": "{{GENDER:$1|käyttäjä}}",
        "group-autoconfirmed-member": "{{GENDER:$1|automaattisesti hyväksytty käyttäjä}}",
        "group-bot-member": "{{GENDER:$1|botti}}",
        "group-sysop-member": "{{GENDER:$1|ylläpitäjä}}",
        "group-bureaucrat-member": "{{GENDER:$1|byrokraatti}}",
-       "group-suppress-member": "{{GENDER:$1|häivytysoikeuden käyttäjä}}",
+       "group-suppress-member": "{{GENDER:$1|häivyttäjä}}",
        "grouppage-user": "{{ns:project}}:Käyttäjät",
        "grouppage-autoconfirmed": "{{ns:project}}:Automaattisesti hyväksytyt käyttäjät",
        "grouppage-bot": "{{ns:project}}:Botit",
        "upload_source_file": "(valitsemasi tiedosto omasta tietokoneestasi)",
        "listfiles-delete": "poista",
        "listfiles-summary": "Tämä toimintosivu näyttää kaikki tallennetut tiedostot.",
-       "listfiles_search_for": "Nimihaku",
+       "listfiles_search_for": "Etsi tiedoston nimellä:",
        "imgfile": "tiedosto",
        "listfiles": "Tiedostoluettelo",
        "listfiles_thumb": "Pienoiskuva",
        "filerevert-success": "'''[[Media:$1|$1]]''' on palautettu takaisin [$4 versioon, joka luotiin $2 kello $3].",
        "filerevert-badversion": "Tiedostosta ei ole luotu versiota kyseisellä ajan hetkellä.",
        "filedelete": "Poistetaan tiedosto $1",
-       "filedelete-legend": "Tiedoston poisto",
-       "filedelete-intro": "Olet poistamassa tiedoston '''[[Media:$1|$1]]''' ja kaiken sen historian.",
+       "filedelete-legend": "Poista tiedosto",
+       "filedelete-intro": "Olet poistamassa tiedoston '''[[Media:$1|$1]]''' ja lisäksi koko sen muokkaushistorian.",
        "filedelete-intro-old": "<span class=\"plainlinks\">Olet poistamassa tiedoston '''[[Media:$1|$1]]''' [$4 päivämäärällä $2 kello $3 luotua versiota].</span>",
        "filedelete-comment": "Syy:",
        "filedelete-submit": "Poista",
        "movetalk": "Siirrä myös keskustelusivu",
        "move-subpages": "Siirrä kaikki alasivut (enintään $1)",
        "move-talk-subpages": "Siirrä kaikki keskustelusivun alasivut (enintään $1)",
-       "movepage-page-exists": "Sivu $1 on jo olemassa ja sitä ei voi automaattisesti korvata.",
+       "movepage-page-exists": "Sivu $1 on jo olemassa ja sen päälle ei voida automaattisesti siirtää.",
        "movepage-page-moved": "Sivu $1 on siirretty nimelle $2.",
        "movepage-page-unmoved": "Sivua $1 ei voitu siirtää nimelle $2.",
        "movepage-max-pages": "Enimmäismäärä sivuja on siirretty, eikä enempää siirretä enää automaattisesti.\n$1 {{PLURAL:$1|sivu|sivua}} siirrettiin.",
        "export-pagelinks": "Sisällytä linkkien kohteina olevat sivut syvyydelle:",
        "allmessages": "Järjestelmäviestit",
        "allmessagesname": "Nimi",
-       "allmessagesdefault": "Oletusarvo",
-       "allmessagescurrent": "Nykyinen arvo",
+       "allmessagesdefault": "Viestin tekstin perusmuoto",
+       "allmessagescurrent": "Viestin teksti tällä hetkellä",
        "allmessagestext": "Tämä on luettelo järjestelmäviesteistä, jotka ovat saatavilla MediaWiki-nimiavaruudessa.\nJos haluat muokata MediaWikin yleistä kotoistusta, käy [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWikin kotoistussivuilla] ja sivustolla [//translatewiki.net translatewiki.net].",
        "allmessagesnotsupportedDB": "Tämä sivu ei ole käytössä, koska <tt>$wgUseDatabaseMessages</tt>-asetus on pois päältä.",
        "allmessages-filter-legend": "Suodata",
        "logentry-newusers-autocreate": "Käyttäjätunnus $1 {{GENDER:$2|luotiin}} automaattisesti",
        "logentry-rights-rights": "$1 {{GENDER:$2|muutti}} käyttäjän $3 oikeudet ryhmistä $4 ryhmiin $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|muutti}} käyttäjän $3 jäsenyyttä ryhmässä",
-       "logentry-rights-autopromote": "$1 {{GENDER:$2|muutettiin}} automaattisesti ryhmistä $4 ryhmiin $5",
+       "logentry-rights-autopromote": "Käyttäjän $1 oikeudet {{GENDER:$2|muuttuivat}} automaattisesti ryhmistä $4 ryhmiin $5",
+       "logentry-upload-upload": "$1 {{GENDER:$2|tallensi}} tiedoston $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|tallensi}} uuden version tiedostosta $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|tallensi}} tiedoston $3",
        "rightsnone": "(ei oikeuksia)",
        "feedback-bugornote": "Jos voit kuvailla teknisen ongelman tarkasti – [$1 ilmoita ohjelmointivirheestä].\nMuussa tapauksessa voit käyttää alla olevaa helpompaa lomaketta. Kommenttisi lisätään sivulle [$3 $2], ja siinä on mukana käyttäjätunnuksesi.",
        "feedback-subject": "Otsikko",
        "api-error-illegal-filename": "Tiedoston nimi ei kelpaa.",
        "api-error-internal-error": "Sisäinen virhe: jotain meni vikaan tallennuksesi käsittelyssä.",
        "api-error-invalid-file-key": "Sisäinen virhe: tiedostoa ei löytynyt välikaisvarastosta.",
-       "api-error-missingparam": "Sisäinen virhe: pyynnöstä puutuu parametrejä.",
+       "api-error-missingparam": "Sisäinen virhe: pyynnöstä puutuu parametreja.",
        "api-error-missingresult": "Sisäinen virhe: ei voitu varmistaa, että tallennus onnistui.",
        "api-error-mustbeloggedin": "Sinun pitää olla kirjautunut sisään, jotta voisit tallentaa tiedostoja.",
        "api-error-mustbeposted": "Sisäinen virhe: HTTP POST-pyyntö edellytetty.",
index 3c307d9..30a496d 100644 (file)
        "logentry-rights-rights": "$1 {{GENDER:$2|a modifié}} l'appartenance au groupe pour $3 de $4 à $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|a modifié}} l'appartenance au groupe pour $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|a été promu}} automatiquement de $4 à $5",
+       "logentry-upload-upload": "$1 {{GENDER:$2|a téléchargé}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|a téléchargé}} une nouvelle version de $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|a téléchargé}} $3",
        "rightsnone": "(aucun)",
        "feedback-bugornote": "Si vous êtes prêt à décrire un problème technique en détail, veuillez [$1 signaler un bogue].\nSinon, vous pouvez utiliser le formulaire simplifié ci-dessous. Votre commentaire sera ajouté à la page « [$3 $2] », avec votre nom d'utilisateur.",
        "feedback-subject": "Objet :",
index 9d0769d..81b91c6 100644 (file)
        "logentry-rights-rights": "$1 {{GENDER:$2|שינה|שינתה}} את ההרשאות של $3 מ$4 ל$5&rlm;",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|שינה|שינתה}} את ההרשאות של $3",
        "logentry-rights-autopromote": "$1 קודם אוטומטית מ$4 ל$5",
+       "logentry-upload-upload": "$1 {{GENDER:$2|העלה|העלתה}} את $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|העלה|העלתה}} גרסה חדשה של $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|העלה|העלתה}} את $3",
        "rightsnone": "(כלום)",
        "feedback-bugornote": "אם אתם מוכנים לתאר בעיה טכנית בפרטים, אנא [$1 דווחו באג].\nאחרת, תוכלו להשתמש בטופס הפשוט שלהלן. הערתכם תתווסף לדף \"[$3 $2]\", יחד עם שם המשתמש שלכם.",
        "feedback-subject": "נושא:",
index 21f50ce..d674ff4 100644 (file)
@@ -10,7 +10,8 @@
                        "Malafaya",
                        "Thakurji",
                        "아라",
-                       "Soul Train"
+                       "Soul Train",
+                       "Filipinayzd"
                ]
        },
        "tog-underline": "Jorr ke niche line khicho:",
        "talkpagelinktext": "Baat",
        "specialpage": "Khaas Panna",
        "personaltools": "Aapan aujaar",
-       "postcomment": "Nawaa section",
        "articlepage": "Content waala panna ke dekho",
        "talk": "Salah",
        "views": "Bichar",
        "externaldberror": "Koi bahaari database authentication error hai, nai to aap ke bahaari account badle ke adhikar nai hai.",
        "login": "Log in karo",
        "nav-login-createaccount": "Log in karo/ nawaa account banao",
-       "loginprompt": "Login kare ke khatir  {{SITENAME}} cookies ke laabu kare ke chaahi.",
        "userlogin": "Log in karo/ nawaa account banao",
        "userloginnocreate": "Log in karo",
        "logout": "Log out",
        "saveprefs": "Save karo",
        "restoreprefs": "Sab default settings ke pahile jaise karo (sab vibhag me)",
        "prefs-editing": "Badaltaa hai",
-       "rows": "Line:",
+       "rows": "Taytay:",
        "columns": "Column:",
        "searchresultshead": "Khojo",
        "stub-threshold": "Threshold ke khatir <a href=\"#\" class=\"stub\">stub link</a> formatting (bytes):",
        "uploadwarning": "Upload ke baare me chetauni",
        "uploadwarning-text": "Meharbani kar ke file ke baaare me aur jankari ke niche badal ke aur fir se kosis karo.",
        "savefile": "File ke save karo",
-       "uploadedimage": "\"[[$1]]\" ke upload kar dewa gae",
-       "overwroteimage": "\"[[$1]]\" ke nawaa version ke upload karaa gais hai",
        "uploaddisabled": "Uploads ke disable kar dewa gais hai",
        "copyuploaddisabled": "URL se upload kare pe rok lagae dewa gais hae.",
        "uploaddisabledtext": "File uploads ke disable kar dewa gais hai.",
        "watchlist-details": "{{PLURAL:$1|$1 panna|$1 panna}} pe dhyan dewa jae hai, baat waala panna ke chhorr ke.",
        "wlheader-enotif": "E-mail notification ke enable kar dewa gais hai.",
        "wlheader-showupdated": "Panna jiske aap ke pichhla visit ke ke baad badal dewa gais hia ke '''bold''' me dekhawa jaawe hai.",
+       "wlnote": "Niche ke {{PLURAL:$1|pahile waala badlao hai| pahile '''$1''' badlao hai}} pichhle {{PLURAL:$2|ghanta|'''$2''' ghanta}} me as of $3, $4..",
        "wlshowlast": "Pichhla $1 ghanta $2 din $3 ke dekhao",
        "watchlist-options": "Dhyan suchi ke options",
        "watching": "Dekhtaa...",
index d8afa7d..4cde5fa 100644 (file)
        "listgrouprights-addgroup-self-all": "az összes csoportot hozzáadhatja a saját fiókjához",
        "listgrouprights-removegroup-self-all": "az összes csoporból eltávolíthatja a saját fiókját",
        "listgrouprights-namespaceprotection-namespace": "Névtér",
-       "trackingcategories-nodesc": "Nincs leírás.",
+       "trackingcategories-nodesc": "Nem található leírás.",
        "trackingcategories-disabled": "A kategória le van tiltva",
        "mailnologin": "Nincs feladó",
        "mailnologintext": "Ahhoz hogy másoknak e-mailt küldhess, [[Special:UserLogin|be kell jelentkezned]] és meg kell adnod egy érvényes e-mail címet a [[Special:Preferences|beállításaidban]].",
index 10f3cd7..6f60e60 100644 (file)
        "logentry-rights-rights": "$1 {{GENDER:$2|huet}} d'Gruppen zou deenen de Benotzer $3 gehéiert vu(n) $4 op $5 geännert",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|huet}} d'Gruppen zou deenen de Benotzer $3 gehéiert geännert",
        "logentry-rights-autopromote": "De Benotzer $1 {{GENDER:$2|krut}} d'Benotzerrechter automatesch vu(n) $4 op $5 geännert",
+       "logentry-upload-upload": "$1 huet $3 {{GENDER:$2|eropgelueden}}",
+       "logentry-upload-overwrite": "$1 huet eng nei Versioun vu(n) $3 {{GENDER:$2|eropgelueden}}",
+       "logentry-upload-revert": "$1 huet $3 {{GENDER:$2|eropgelueden}}",
        "rightsnone": "(keen)",
        "feedback-bugornote": "Wann Dir bereet sidd fir en technesche Problem am Detail ze beschreiwen da [$1 mellt w.e.g. e Feeler (Bug)].\nSoss kënnt Dir den einfache Formulär hei drënner benotzen. Är Bemierkung gëtt op d'Säit \"[$3 $2]\" derbäigesat, zesumme mat Ärem Benotzernumm an dem Numm vum Browser deen Dir benotzt.",
        "feedback-subject": "Sujet:",
index 182ecf3..50a1e59 100644 (file)
        "editinginterface": "<strong>زئنار دئن:</strong> شما داریت بلگه ای نه که سی      بیه ویرایشت می کید.",
        "cascadeprotected": "ای بلگه د ویرایشت محافظت بیه سی یه که {{جمی:$1|وه بلگه یه |ونو بلگه یان}} که ها دش د                 :\n$2",
        "namespaceprotected": "شما حقی سی ویرایشت بلگه یایی که هان د نومجا  <strong>$1</strong> ناریت.",
+       "customcssprotected": "شما سی ویرایشت ای بلگه سی اس اس اجازه ناریت سی یه که میزونکاری دونسمنیا شخصی یه کاریار هنی ها د وه.",
+       "customjsprotected": "شما سی ویرایشت ای بلگه جاوا اسکریپت اجازه ناریت سی یه که میزونکاری دونسمنیا شخصی یه کاریار هنی ها د وه.",
        "mycustomcssprotected": "شما حق ناریت ای بلگه سی اس اس نه ویرایشت بکید",
        "mycustomjsprotected": "شما حق ناریت ای بلگه جاوا اسکریپت نه ویرایشت بکید",
        "myprivateinfoprotected": "شما حق ناریت دونسمنیا خصوصی نه ویرایشت بکید",
        "mypreferencesprotected": "شما حق ناریت ویجگی یا هنی تونه ویرایشت بکید",
        "ns-specialprotected": "بلگیا ویجه نتونن ویرایشت بوئن",
+       "titleprotected": "ای دیارگر د دروس بیئن وه دس [[کاریار:$1|$1]].\n نهاگری بیه.\nدلیلش ونه\"<em>$2</em>\".",
+       "filereadonlyerror": "نبوئه جانیا \"$1\" آلشت بکیتو سی یه که اماییه گه \"$2\" فقط د حال و بال حننیه.\n\nدیوونداری که یه نه قلف کرده موئه د واشکافت \"$3\" بکیتو.",
        "invalidtitle-knownnamespace": "نوم نامعتور سی نوم جا \"$2\" و نیسه \"$3\"",
        "invalidtitle-unknownnamespace": "نوم نامعتور سی شماره نومجا ناشناس $1 و نیسه \"$2\"",
        "exception-nologin": "نبوئه وارد بوئيد",
+       "exception-nologin-text": "شما وارد [[ویجه:وامین اومائن کاریار|وامین اومائن]] بوئیت سی یه تونستویت که د ای بلگه یا کنشت دسرسی داشتویت.",
        "exception-nologin-text-manual": "خواهشمنیدم که $1 تونسه بوئه د ای بلگه دسرسی داشتوه یا کاری انجوم بیئه.",
+       "virus-badscanner": "سازواره گن:ویروس ناشناس:<em>$1</em>",
        "virus-scanfailed": "زل بیئن شکست حرد($1)",
        "virus-unknownscanner": "ويروس كش ناآشگار",
+       "logouttext": "<strong>شما هنی نریتته وه در.</strong>\n\nد ویرتو با که ویرگه نهو انجومیارتو نه پاکسا نکیت، سی یه پاره ای د بلگه یا ممکنه جوری نشو دئه بوئن چی یه که منیستی  شما هنی هایین وامین.",
        "welcomeuser": "خوش اومايت،$1!",
+       "welcomecreation-msg": "حساوتو دروس بیه.\nد ویرتو نروئه که{{نوم دیارگه}} [[Special:Preferences|preferences]]  خوتونه آلشت بکیت",
        "yourname": "نوم کاریاری:",
        "userlogin-yourname": "نوم كاروری",
        "userlogin-yourname-ph": "نوم کاریاری تو نه وارد بكيد",
        "userlogin-signwithsecure": "د وصل بيئن امن استفاده كو",
        "yourdomainname": "پوشگیر شما:",
        "password-change-forbidden": "شما نتونید پاسوردیانه د ای ویکی آلشت بکید",
+       "externaldberror": "اشتوایی د ارتواط وا رسینه گا پیش اومائه یا ینه که شما اجازه وه هنگوم سازی حساو خارجی تونه ناریت.",
        "login": "اومائن",
        "nav-login-createaccount": " اومائن د سيستم/راس كردن حساو",
        "userlogin": " اومائن د سيستم/راس كردن حساو",
        "passwordremindertitle": "پاسورد موقت تازه سی {{SITENAME}}",
        "noemail": "هیچ نشونی ایمیلی سی کارور $1 ضفط نبیه.",
        "noemailcreate": "شما باید یه نشونی نومه معتور فراهم بکید",
+       "passwordsent": "یه گل پاسورد هنی سی تیرنشون انجانامه ای که \"$1\" واش ثوت نام کرده بی کل بیه.\nخواهش میکیم هنی رویئت وامین و اوسه بئریتش.",
+       "blocked-mailpassword": "نها آی پی شما سی ویرایشت گرته بیه، و",
        "mailerror": "خطا داره کل موئه:$1",
        "emailauthenticated": "نشونی انجومانامه تونه د $2 سی 3$ مئکم بیه.",
        "emailconfirmlink": "نشونی ايملتو نه محكم بكيد",
        "prefs-i18n": "جهون ولاتمنی",
        "prefs-signature": "امضا",
        "prefs-dateformat": "شلک وخت",
+       "prefs-timeoffset": "جا وه جایی زمونی",
        "prefs-advancedediting": "گزینه یا عمومی",
        "prefs-editor": "ويرايشتگر",
        "prefs-preview": "پیش سیل",
        "prefs-advancedwatchlist": "گزینه یا پیشکرده",
        "prefs-displayrc": "گزینه یا نه نشو بیه",
        "prefs-displaywatchlist": "گزینه یا نه نشو بیه",
+       "prefs-tokenwatchlist": "نشو",
        "prefs-diffs": "فرخیا",
        "email-address-validity-valid": "نشونی ایمیل دیار بیه خوئه",
        "email-address-validity-invalid": "یه گل نشونی ایمیل خو وارد بکید",
        "action-createpage": "راس کردن بلگیا",
        "action-createtalk": "بلگه یا چک چنه نه راس بکید",
        "action-createaccount": "حساو ای کارور نه راس بکید",
+       "action-history": "ویرگار ای بلگه نه بوینیت",
        "action-minoredit": "ای ویرایشت نه چی یه حیرده ویرایشت نشو بیئت",
        "action-move": "لی بلگه جا وه جا کو",
        "action-move-subpages": "ای بلگه و زیر بلگه یاشه جا وه جا بکید",
        "recentchanges-label-minor": "يه ويرايشت كؤچكيه",
        "recentchanges-label-bot": "ای ويرايشت نه يه بوت انجوم ديئه",
        "recentchanges-label-unpatrolled": "ای ويرايشت هنی تيه واداشت نبيه",
+       "recentchanges-label-plusminus": "انازه بلگه وه شمار ای بایتیا آلشت کرده.",
        "recentchanges-legend-heading": "'''میراث:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (همچنو بوینیت [[ویجه:بلگیا تازه|نوم گه بلگیا تازه]])",
        "rcnotefrom": "د هار آلشتیا د $2 هیئن(د بال د $1 نشون دئه بیه)",
        "uploadnologin": "وارد نبیه",
        "uploadnologintext": "لطفن $1 سی سوارکرد جانیایا.",
        "uploaderror": "خطا د سوار کردن",
+       "upload-permitted": "جورا جانیا مجاز:$1.",
+       "upload-preferred": "جورا جانیا مجاز:$1.",
+       "upload-prohibited": "جورا جانیا مجاز:$1.",
        "uploadlogpage": "سوارکرد",
        "filename": "نوم فایل",
        "filedesc": "چكسته",
        "filestatus": "حال و بال کپی رایت",
        "filesource": "سرچشمه:",
        "ignorewarnings": "د هر زنهار تیه پوشی کو",
+       "filename-toolong": "نوم جانیا شایت گپتر د 240 بایت نبا.",
        "badfilename": "نوم جانیا د \"$1\" آلشت بیه.",
        "empty-file": "فایلی که دئی ته حالی بیه.",
        "file-too-large": "فایلی که دئی ته فره گپ بی.",
        "unknown-error": "یه گل خطا نادیار ری ون کرده.",
        "tmp-create-error": "نبوئه جانیا موقتی نه راس بکیتو.",
        "tmp-write-error": "خطا د نیسنن جانیا موقتی.",
+       "uploadwarning": "هشدار سوارکرد",
        "savefile": "جانیا نه اماییه کو",
        "uploaddisabled": "سوار کردن د کار نئ.",
        "copyuploaddisabled": "سوار کردن وا یو آر ال د کار نئ.",
        "uploaddisabledtext": "سوار کرد فایلیا د کار نئ.",
        "uploadinvalidxml": "ایکس ام الی که سوار بیه نبوئه نوتیج با.",
+       "uploadvirus": "د ای جانیا ویروس هئ!\nجزیات:$1",
        "upload-source": "سرچشمه فایل",
        "sourcefilename": "سرچشمه نوم جانیا:",
        "sourceurl": "سرچشمه يو آر ال:",
        "upload-success-msg": "سوارکرد شما سی [$2] خوو بی.وه د ایچه هئش:[[:{{ns:file}}:$1]]",
        "upload-failure-subj": "مشگل د سوارکردن",
        "upload-failure-msg": "یه گل مشلگل د سوارکردتو سی [$2] بی:$1",
+       "upload-warning-subj": "هشدار سوارکرد",
        "upload-proto-error": "پروتکل نادروس",
        "upload-file-error": "خطا مینونه",
        "upload-misc-error": "خطا سوار کرد ناشناخته",
        "upload-too-many-redirects": "ای یو آر ال د ورگیرنه واگردونیا فرئی هئ",
+       "upload-http-error": "یه گل خطا اچ تی تی پی پیش اومائه:$1",
        "upload-copy-upload-invalid-domain": "ورداشتن سوارکردیا د ای پوشگئر د دسرس نئ.",
        "backend-fail-notexists": "فایل $1 وجود ناره.",
+       "backend-fail-invalidpath": "\"$1\" ره خوئی سی امائیه کردن نئ.",
        "backend-fail-delete": "نبوئه جانیا $1 پاکسا بوئه",
        "backend-fail-describe": "نبوئه گپ دونسمنیا سی جانیا\"$1\" آلشت بوئه.",
+       "backend-fail-alreadyexists": "جانیا \"$1\" ایسه هیئش.",
        "backend-fail-store": "نبوئه جانیا \"$1\" د \"$2\" امبار بوئه.",
+       "backend-fail-copy": "نبوئه جانیا $1 د $2 ورداشته بوئه",
        "backend-fail-move": "نبوئه جانیا \"$1\" د \"$2\" جا وه جا بوئه",
        "backend-fail-opentemp": "نبوئه جانیا موقتی وا بوئه.",
        "backend-fail-writetemp": "نبوئه د جانیا موقتی چی بنیسیت.",
+       "backend-fail-closetemp": "نبوئه جانیا موقتی بسته با.",
        "backend-fail-read": "نبوئه جانیا\"$1\" حنه بوئه.",
+       "backend-fail-create": "نبوئه د جانیا\"$1\" نوشته با.",
        "lockmanager-fail-closelock": "نبوئه قلف جانیا سی \"$1\" بسه بوئه.",
        "lockmanager-fail-openlock": "نبوئه قلف جانیا سی \"$1\" وا بوئه.",
+       "uploadstash": "اماییه جا سوارکرد",
+       "uploadstash-clear": "پاک کردن جانیایا اماییه بیه",
+       "uploadstash-nofiles": "شما هیژ جانیا اماییه بیه ای ناریت.",
        "uploadstash-refresh": "نومه گه جانیایا نه د نو تازه کو",
+       "invalid-chunk-offset": "جا وه جایی نامعتور برشت",
        "img-auth-accessdenied": "دسرسی منع بی",
        "img-auth-nofile": "فایل $1 وجود ناره.",
        "http-invalid-url": "یو آر ال نامعتور:$1",
        "filepage-nofile": "چنو فایلی وا ای نوم نئ.",
        "uploadnewversion-linktext": "یه گل نسقه تازه د ای جانیا سوار بکید",
        "shared-repo-from": "د $1",
+       "filerevert": "د سرگرتن سی $1",
+       "filerevert-legend": "د سرگرتن جانیا",
        "filerevert-comment": "دليل:",
        "filerevert-submit": "ورگنین",
        "filedelete": "$1 پاکسا کو",
        "doubleredirects": "واگردونیا دوتایی",
        "double-redirect-fixed-move": "[[$1]]جا وه جا بیه .\nوه خودکارونه وه روز بیه و ایسه وه د[[$2]] واگردونی بیه.",
        "double-redirect-fixer": "تعمیر کننه واگردونی",
+       "brokenredirects": "واگردونیا بی سرانجوم",
        "brokenredirectstext": "واگردونیا نهاتر د بلگه یایی که وجود نارن هوم پیوند بینه.",
        "brokenredirects-edit": "ویرایشت",
        "brokenredirects-delete": "پاكسا كردن",
        "withoutinterwiki": "بلگه یایی که هوم پیوند زون نارن",
        "withoutinterwiki-legend": "پیشون",
        "withoutinterwiki-submit": "نشون دائن",
+       "fewestrevisions": "بلگه یایی که کمتری وانئری نه دارن",
        "nbytes": "$1{{جمی:$1|بايت|بایتیا}}",
        "ncategories": "$1{{جمی:$1|دسه|دسه يا}}",
        "ninterwikis": "$1 {{جمی:$1|مئن ویکی|مئن ویکیا}}",
        "nlinks": "$1 {{جمی:$1|هوم پیوند|هوم پیوندیا}}",
        "nmembers": "$1 {{PLURAL:$1|اندوم|اندوميا}}",
        "nmemberschanged": "$1 → $2 {{جمی:$2|اندوم|اندومیا}}",
+       "nrevisions": "$1 {{جمس:$1|وانئری|وانئریا}}",
        "nviews": "$1 {{جمی:$1|دیئن|دیئنیا}}",
        "nimagelinks": "$1 {{جمی:$1|بلگه|بلگيا}} استفاده بیه",
        "ntransclusions": "$1 {{جمی:$1|بلگه|بلگيا}} استفاده بیه",
        "mostlinkedtemplates": "چوئه یایی که بیشتر هوم پیوند بینه",
        "mostcategories": "بلگه یا که بیشتر دسه بنی بینه",
        "mostimages": "فایلیایی که بیشتر هوم پیوند بینه",
+       "mostinterwikis": "بلگه یایی که بیشتری مینجا ویکی نه دارن",
+       "mostrevisions": "بلگه یایی که بیشتری وانئری نه دارن",
        "prefixindex": "همه بلگيا وا پيشون",
        "shortpages": "بلگه یا کؤچک",
        "longpages": "بلگه یا گپ",
        "protectedpages-unknown-performer": "کارور ناشناس",
        "listusers": "نوم گه کارور",
        "listusers-editsonly": "فقط کاروریایی که ویرایشت می کن نشو بیه",
+       "listusers-creationsort": "سرجاخودگری د اساس گات دروس بیین",
+       "listusers-desc": "سرجاخودگری د اساس گپ د کؤچک",
        "usereditcount": "$1{{جمی:$1|ویرایشت|ویرایشتیا}}",
        "usercreated": "{{جنسیت:$3|راس بیه}}د $1 at $2",
        "newpages": "بلگيا نو",
        "booksources": "سرچشمه يل كتاو",
        "booksources-search-legend": "پی جوری سی سرچشمه یا کتاو",
        "booksources-go": "رو",
+       "specialloguserlabel": "انجومکار:",
        "log": "نیسنن رخ ونیا",
        "all-logs-page": "همه پهرستنومه یا عمومی",
        "allpages": "همه بلگيا",
        "nextpage": "بلگه نهایی($1)",
        "prevpage": "بلگه دمایی($1)",
+       "allpagesfrom": "بلگه یای که د شرو بینه نشو بیه:",
+       "allpagesto": "بلگه یایی که د تموم بینه نشو بیه.",
        "allarticles": "همه بلگيا",
+       "allinnamespace": "همه بلگه یا($1 نوم جا)",
        "allpagessubmit": "رو",
+       "allpagesprefix": "بلگه یایی که پس نوم دارن نشو بیه:",
        "allpagesbadtitle": "عنوان بلگه حاسته بیه معتور نی،یا  یه گل مئن زونی یا مئن ویکی عنوان غلطه.\nیه شایت شومل یکی با یا بیشتر کاراکتریا نبوئه که سی ای موضوعیا استفاده بوئن",
+       "allpages-bad-ns": "{{نوم دیارگه}} د ای نوم جا نئ \"$1\".",
        "allpages-hide-redirects": "واگردونیا قام بیه",
        "cachedspecial-refresh-now": "دیئن آخری.",
        "categories": "دسه يا",
+       "special-categories-sort-count": "سرجاخودگری د اساس شمارشت",
+       "special-categories-sort-abc": "سرجاخودگری د اساس الفبا",
        "deletedcontributions": "هومیاریا پاکسا بیه کارور",
        "deletedcontributions-title": "هومیاریا پاک بیه کارور",
        "sp-deletedcontributions-contribs": "هومیاریا",
+       "linksearch": "هوم پیوند پی جوری خارجی",
+       "linksearch-pat": "سازه یار پی جوری:",
        "linksearch-ns": "نوم جا:",
        "linksearch-ok": "پی جوری",
        "linksearch-line": "$1 داره د $2 هوم پیوند بوئه",
+       "listusersfrom": "کاریاریایی که د شرو بینه نشو بیه:",
        "listusers-submit": "نشو دئن",
        "listusers-noresult": "هیچ کاروری پیدا نبی",
        "listusers-blocked": "(قلف بيه)",
        "activeusers": "نوم گه کاروریا کارکو",
+       "activeusers-from": "کاریاریایی که د شرو بینه نشو بیه:",
        "activeusers-hidebots": "بوتیا قام کو",
        "activeusers-hidesysops": "دیوون داریا نه قام کو",
        "activeusers-noresult": "هیچ کاروری پیدا نبی",
+       "listgrouprights": "حقوق گرو کاریاری",
+       "listgrouprights-key": "Legend:\n* <span class=\"listgrouprights-granted\">دئه بیه د سمت راست</span>\n* <span class=\"listgrouprights-revoked\">انجوم شیو بیه د سمت راست</span>",
        "listgrouprights-group": "دسه",
        "listgrouprights-rights": "حقوقیا",
+       "listgrouprights-helppage": "هومیاری:حقوق گرو",
        "listgrouprights-members": "(نوم گه اندومیا)",
+       "listgrouprights-addgroup": "{{جمی:$2|گرویا|گرویا}} اضاف بکیتو: $1",
+       "listgrouprights-removegroup": "{{جمی:$2|گرویا|گرویا}} ورداریت: $1",
        "listgrouprights-addgroup-all": "همه گرویا نه اضاف کو",
        "listgrouprights-removegroup-all": "همه گرویا نه وردار",
        "listgrouprights-addgroup-self": " {{جمی:$2|گروه|گرویا}} نه د حساو: $1 اضاف کو",
+       "listgrouprights-removegroup-self": "{{جمی:$2|گرویا|گرویا}} نه د حساو ورداریت: $1",
+       "listgrouprights-addgroup-self-all": "همه گرویا نه د حساو خوشو اضاف بکیت",
+       "listgrouprights-removegroup-self-all": "همه گرویا نه د حساو خوشو ورداریت",
+       "listgrouprights-namespaceprotection-namespace": "نوم جا",
+       "trackingcategories-name": "نوم پیغوم",
+       "trackingcategories-disabled": "دسه ناکشتگر بیه",
        "mailnologin": "هیپچ نشونی یی کل نبیه",
        "emailuser": "ای كارور نه ايميل كو",
        "emailuser-title-target": "ایمیل سی ای {{جنس:$1|کارور}}",
        "defemailsubject": "{{نوم سیل جا}} ایمیل د کارور \"$1\"",
        "usermaildisabled": "ایمیل کارور د کار افتائه",
        "noemailtitle": "هیچ نشونی ایمیلی نئ",
+       "emailtarget": "یه گل نوم کاریاری سی پذریشتگر وارد بکیت",
        "emailusername": "نوم كاروری:",
        "emailusernamesubmit": "دئن",
        "emailfrom": "د:",
        "emailccsubject": " پیغومتو سی $1:$2 ورداشته بی",
        "emailsent": "ایمیل کل بیه",
        "emailsenttext": "پیغوم ایمیلی تو کل بیه.",
+       "usermessage-summary": "رئتن د سامونه پیغوم",
        "usermessage-editor": "پیغوم فرسن سیستم",
        "watchlist": "سیل برگ",
        "mywatchlist": "سیل برگ",
        "watchlistfor2": "سي $1 $2",
+       "nowatchlist": "شما هیچی د سیل برگ خوتو ناریت",
        "watchnologin": "وارد نبیه",
+       "addwatch": "اضاف کردن د سیل برگ",
+       "removewatch": "جا وه جا کردن د سیل برگ",
+       "removedwatchtext": "بلگه\"[[:$1]]\" د [[Special:سیل برگ|سیل برگ خوتو]] جا وه جا بیه.",
+       "removedwatchtext-short": "بلگه \"$1\" د سیل برگ جا وه جا بیه.",
        "watch": "سيل كردن",
        "watchthispage": "ديئن ای بلگه",
        "unwatch": "ديه نبيه",
        "unwatchthispage": "واداشتن دیئن",
        "notanarticle": "مینونه هیچ بلگه ای نئ",
+       "notvisiblerev": "آخری وانئری که د دس یه کاریار هنی انجوم بیه پاکسا بیه.",
        "watchlist-details": "{{جمی:$1|$1 بلگه|$1 بلگیا}} د سیل برگتو هیش بلگه قسه کردن نی .",
        "wlheader-enotif": "وارسیاری ایمیل فعال بیه.",
        "wlheader-showupdated": "بلگه یایی که د آخرین کرتی که شما دشو دیئن کردیته آلشت بینه د <strong>توپر</strong>نشون دئه بینه",
        "deleteotherreason": "دليليا هنی:",
        "deletereasonotherlist": "دلیل هنی",
        "deletereason-dropdown": "* دلیلیا پاکسا کردن رسم بیه\n** اسپم\n** خراوکاری\n** رعایت نبین کپی رایت\n** درحاست نیسنه\n** نهاورگشت شکست حرده",
+       "delete-edit-reasonlist": "دلیلیا پاکسا کردنه نه ویرایشت بکید",
        "rollbacklink": "ورگشتن",
        "sessionfailure-title": "شکست حردن نشینگه",
        "protectlogpage": "حفاظت کردن",
        "modifiedarticleprotection": "ریتراز حفاظت د \"[[$1]]\" آلشت بیه",
        "protect-title": "ریتراز حفاظت د \"$1\" آلشت بیه",
        "prot_1movedto2": "[[$1]] د [[$2]] جا وه جا بی",
+       "protectcomment": "دلیل:",
        "protect-default": "همه کاروریا اجازه دارن",
        "protect-othertime": "وخت هنی:",
+       "protect-othertime-op": "گات هنی",
+       "protect-otherreason-op": "دلیل هنی",
        "protect-expiry-options": "1 ساعت:1 ساعت,1 روز:1 روز,1 هفته:1 هفته,2 هفته:2 هفته,1 ما:1 ما,3 ما:3 ما,6 ما:6 ما,1 سال:1 سال,بی حساو:بی حساو",
        "restriction-type": "دسرسی:",
+       "minimum-size": "انازه کمترونه",
+       "maximum-size": "انازه بیشترونه",
+       "pagesize": "(بایتیا)",
        "restriction-edit": "ويرايشت",
        "restriction-move": "جاوه جا بوئيت",
        "restriction-create": "راس كردن",
        "whatlinkshere-filters": "فيلتريا",
        "block": "منع کارور",
        "blockip": "منع کارور",
+       "ipaddressorusername": "نوم نشون آی پی يا نوم كاروری:",
        "ipbreason": "دليل:",
        "ipbemailban": "نهاگرتن کاریار د کل کردن انجومانامه",
        "ipbother": "وخت هنی:",
        "unblocklink": "بی قطی",
        "change-blocklink": "اجازه نديئن سی  آلشت",
        "contribslink": "هومكاری",
+       "emaillink": "انجومانامه نه کل کو",
        "blocklogpage": "قلف",
        "blocklogentry": " [[$1]] وا یه گل وخت تموم بیئن $2 و $3  قلف بیه",
        "block-log-flags-nocreate": "حساو راس کردن عاجز بیه.",
        "block-log-flags-nousertalk": "نبوئه بلگه چک چنه خوتونه ویرایشت بکید",
+       "proxyblocker": "قلف کننه پروکسی",
        "lockdb": "قلف کردن رسینه گا",
        "unlockconfirm": "هره، مه واقعند میهام که رسینه گا وا بوئه.",
+       "lockbtn": "قلف کردن رسینه گا",
        "unlockbtn": "رسینه گا قلف نبیه",
        "lockdbsuccesssub": "رسینه گا د خوئی قلف بیه",
        "move-page": "$1 جا وه جا کو",
+       "move-page-legend": "بلگه نه جا وه جا کو",
        "movenotallowed": "شما وه جا وه جا کردن بلگه دسرسی ناریت",
        "movenotallowedfile": "شما وه جا وه جا کردن جانیایا دسرسی ناریت",
        "movepagebtn": "بلگه جا وه جا کو",
+       "pagemovedsub": "د خوئی جا وه جا بیه",
        "movepage-moved-redirect": "یه گل واگردونی دروس بیه.",
        "movelogpage": "جاوه جا کردن",
        "movelogpagetext": "د هار یه گل نوم گه د جا وه جایی یا بلگه هئ",
+       "movereason": "دلیل:",
        "revertmove": "لرستن",
        "delete_and_move": "پاکسا و جا وه جا بوئه",
        "export": "وه صحرا ديئن بلگيا",
+       "export-addcat": "اضاف کو",
+       "export-addns": "اضاف كو",
        "export-download": "ذخیره کردن جانیا",
+       "export-templates": "شامل چوئه یا",
+       "allmessages": "سامونه پیغومیا",
        "allmessagesname": "نوم",
        "allmessagesdefault": "سفارشت متنی پيش فرض",
+       "allmessages-filter-legend": "فیلتر",
+       "allmessages-filter-all": "همه",
+       "allmessages-filter-modified": "آلشت بیه",
+       "allmessages-prefix": "فیلتر بیه وا نهاون:",
        "allmessages-language": "زون:",
        "allmessages-filter-submit": "رو",
+       "allmessages-filter-translate": "والرن",
        "thumbnail-more": "گپ كردن",
        "filemissing": "گم بیئن جانیا",
        "thumbnail_error": "خطا د راس بیئن بن کلئکی:$1",
index 5515951..c60d146 100644 (file)
        "logentry-rights-rights": "$1 {{GENDER:$2|го измени}} групното членство на $3 од $4 во $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|го измени}} групното членство во $3",
        "logentry-rights-autopromote": "$1 автоматски {{GENDER:$2|унапреден|унапредена}} од $4 во $5",
+       "logentry-upload-upload": "$1 {{GENDER:$2|ја подигна}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|подигна}} нова верзија на $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|ја подигна}} $3",
        "rightsnone": "(нема)",
        "feedback-bugornote": "Ако сте спремни подробно да го опишете техничкиот проблем, тогаш [$1 пријавете грешка]. \nВо спротивно, послужете се со едноставниот образец подолу. Вашиот коментар ќе стои на страницата „[$3 $2]“, заедно со корисничкото име и прелистувачот што го користите.",
        "feedback-subject": "Наслов:",
index a3cce1b..fe35a4a 100644 (file)
        "hidetoc": "ukryj",
        "collapsible-collapse": "Zwiń",
        "collapsible-expand": "Rozwiń",
+       "confirmable-confirm": "Jesteś {{GENDER:$1|pewny|pewna}}?",
+       "confirmable-yes": "Tak",
+       "confirmable-no": "Nie",
        "thisisdeleted": "Pokazać lub odtworzyć $1?",
        "viewdeleted": "Zobacz $1",
        "restorelink": "{{PLURAL:$1|jedną usuniętą wersję|$1 usunięte wersje|$1 usuniętych wersji}}",
index 122ec60..28c37a6 100644 (file)
        "logentry-rights-rights": "$1 modificou os privilégios do utilizador $3 de $4 para $5",
        "logentry-rights-rights-legacy": "$1 alterou os grupos de $3",
        "logentry-rights-autopromote": "$1 foi automaticamente {{GENDER:$2|promovido|promovida}} de $4 a $5",
+       "logentry-upload-upload": "$1 {{GENDER:$2|carregou}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|carregou}} uma nova versão de $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|carregou}} $3",
        "rightsnone": "(nenhum)",
        "feedback-bugornote": "Se está pronto para descrever um problema técnico em detalhe, por favor, [$1 comunique o defeito].\nCaso contrário, pode facilmente usar o formulário abaixo. O seu comentário será adicionado à página \"[$3 $2]\", junto com o seu nome de utilizador e o navegador que está a usar.",
        "feedback-subject": "Assunto:",
index ed4e1b6..0ec9349 100644 (file)
        "hidetoc": "This is the link used to hide the table of contents\n\n{{Identical|Hide}}",
        "collapsible-collapse": "{{Doc-actionlink}}\nThis is the link used to collapse a collapsible element. (used as plaintext. No wikitext or html is parsed.)\n\nSee also:\n* {{msg-mw|Collapsible-expand}}\n{{Identical|Collapse}}",
        "collapsible-expand": "{{Doc-actionlink}}\nThis is the link used to expand a collapsible element (used as plaintext. No wikitext or html is parsed.)\n\nSee also:\n* {{msg-mw|Collapsible-collapse}}\n\nSee the following example:\n{{Identical|Expand}}",
-       "confirmable-confirm": "Question asking the user to confirm a potentially uncancellable action.\n\"Yes\" and \"No\" buttons are displayed beside it.\n\nSee also:\n* {{msg-mw|confirmable-yes}}\n* {{msg-mw|confirmable-no}}\n",
+       "confirmable-confirm": "Question asking the user to confirm a potentially uncancellable action.\n\"Yes\" and \"No\" buttons are displayed beside it.\n\nSee also:\n* {{msg-mw|confirmable-yes}}\n* {{msg-mw|confirmable-no}}",
        "confirmable-yes": "{{Doc-actionlink}}\nText of a button that will confirm triggering of a potentially uncancellable action.\n\nSee also:\n* {{msg-mw|confirmable-confirm}}\n* {{msg-mw|confirmable-no}}",
        "confirmable-no": "{{Doc-actionlink}}\nText of a button that will cancel triggering of a potentially uncancellable action.\n\nSee also:\n* {{msg-mw|confirmable-confirm}}\n* {{msg-mw|confirmable-yes}}",
        "thisisdeleted": "Message shown on a deleted page when the user has the undelete right. Parameters:\n* $1 - a link to [[Special:Undelete]], with {{msg-mw|restorelink}} as the text\nSee also:\n* {{msg-mw|viewdeleted}}",
        "action-pagelang": "{{Doc-action|pagelang}}",
        "log-name-pagelang": "Display entry for log name for changes in page language in Special:Log.",
        "log-description-pagelang": "Display description for log name for changes in page language in Special:Log.",
-       "logentry-pagelang-pagelang": "{{Logentry}}\nAdditional parameters:\n* $4 - old language code, or \"[def]\" (hard-coded)\n* $5 - new language code, or \"[def]\" (hard-coded)"
+       "logentry-pagelang-pagelang": "{{Logentry}}\nAdditional parameters:\n* $4 - old language code, or \"[def]\" (hard-coded)\n* $5 - new language code, or \"[def]\" (hard-coded)",
+       "default-skin-not-found": "Message shown when the default skin for this MediaWiki installation can not be found.\n\nParameters:\n* $1: skin identifier for the default skin\n* $2: list of installed skins, composed using {{msg-mw|default-skin-not-found-row-enabled}} and {{msg-mw|default-skin-not-found-row-disabled}}\n* $3: code snippet to use to enable installed skins",
+       "default-skin-not-found-no-skins": "Message shown when the default skin for this MediaWiki installation can not be found and the installation has no skins at all.\n\nParameters:\n* $1: name of the default skin",
+       "default-skin-not-found-row-enabled": "One row of the list of installed skins shown as a part of {{msg-mw|default-skin-not-found}}, for an enabled skin.\n\nParameters:\n* $1: skin identifier\n$2: human-readable skin name",
+       "default-skin-not-found-row-disabled": "One row of the list of installed skins shown as a part of {{msg-mw|default-skin-not-found}}, for a disabled skin.\n\nParameters:\n* $1: skin identifier\n$2: human-readable skin name"
 }
index a28d93b..1f6c368 100644 (file)
        "logentry-rights-rights": "$1 {{GENDER:$2|a schimbat}} apartenența la grup pentru $3 de la $4 la $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|a schimbat}} apartenența la grup pentru $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|a fost promovat|a fost promovată}} în mod automat de la $4 la $5",
+       "logentry-upload-upload": "$1 {{GENDER:$2|a încărcat}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|a încărcat}} o nouă versiune pentru $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|a încărcat}} $3",
        "rightsnone": "(niciunul)",
        "feedback-bugornote": "Dacă sunteți pregătit să descrieți o problemă tehnică în detaliu vă rugăm să [$1 raportați un bug].\nÎn caz contrar, puteți utiliza formularul de mai jos. Comentariul dumneavoastră va fi adăugat pe pagina „[$3 $2]”, împreună cu numele de utilizator și numele navigatorului pe care îl folosiți.",
        "feedback-subject": "Subiect:",
index afd1194..725c9f3 100644 (file)
        "logentry-rights-rights": "$1 {{GENDER:$2|изменил|изменила}} членство в группах для $3 с $4 на $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|изменил|изменила}} членство в группах для $3",
        "logentry-rights-autopromote": "$1 был{{GENDER:$2||а}} автоматически переведен{{GENDER:$2||а}} из $4 в $5",
+       "logentry-upload-upload": "$1 загрузил{{GENDER:$2||а}} $3",
+       "logentry-upload-overwrite": "$1 загрузил{{GENDER:$2||а}} новую версию $3",
+       "logentry-upload-revert": "$1 загрузил{{GENDER:$2||а}} $3",
        "rightsnone": "(нет)",
        "feedback-bugornote": "Если вы готовы подробно описать техническую проблему, пожалуйста, [$1 сообщите об ошибке].\nВ противном случае вы можете использовать данную простую форму. Ваш комментарий будет добавлен на страницу «[$3 $2]» вместе с вашим именем участника и используемым браузером.",
        "feedback-subject": "Тема:",
index 70efbcb..7b28fe6 100644 (file)
        "logentry-rights-rights": "$1 je {{GENDER:$2|spremenil|spremenila|spremenil(-a)}} uporabniške pravice uporabnika $3 z $4 na $5",
        "logentry-rights-rights-legacy": "$1 je {{GENDER:$2|spremenil|spremenila|spremenil(-a)}} uporabniške pravice uporabnika $3",
        "logentry-rights-autopromote": "$1 je {{GENDER:$2|bil samodejno povišan|bila samodejno povišana|bil(-a) samodejno povišan(-a)}} z $4 na $5",
+       "logentry-upload-upload": "$1 je {{GENDER:$2|naložil|naložila|naložil(-a)}} $3",
+       "logentry-upload-overwrite": "$1 je {{GENDER:$2|naložil|naložila|naložil(-a)}} novo različico $3",
+       "logentry-upload-revert": "$1 je {{GENDER:$2|naložil|naložila|naložil(-a)}} $3",
        "rightsnone": "(nobeno)",
        "feedback-bugornote": "Če ste pripravljeni podrobno opisati tehnično težavo, vložite [$1 poročilo o hrošču].\nV nasprotnem primeru lahko uporabite preprost obrazec spodaj. Vašo pripombo bomo dodali na stran »[$3 $2]«, skupaj z vašim uporabniškim imenom in podatkom o brskalniku, ki ga uporabljate.",
        "feedback-subject": "Zadeva:",
index 63cb26c..e17791e 100644 (file)
        "logentry-rights-rights": "$1 {{GENDER:$2|ändrade}} gruppmedlemskapet för $3 från $4 till $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|ändrade}} gruppmedlemskapet för $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|befordrades}} automatiskt från $4 till $5",
+       "logentry-upload-upload": "$1 {{GENDER:$2|laddade upp}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|laddade upp}} en ny version av $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|laddade upp}} $3",
        "rightsnone": "(inga)",
        "feedback-bugornote": "Om du är redo att beskriva ett tekniskt problem detaljerat, var god [$1 rapporterar en bugg].\nAnnars kan du använda det enkla formuläret nedan. Din kommentar kommer att läggas till på sidan \"[$3 $2]\", tillsammans med ditt användarnamn och vilken webbläsare du använder.",
        "feedback-subject": "Ämne:",
index 5bd5645..5875525 100644 (file)
        "versionrequiredtext": "Bu sayfayı kullanmak için MediaWiki'nin $1 sürümü gerekmektedir. [[Special:Version|Sürüm sayfasına]] bakınız.",
        "ok": "Tamam",
        "pagetitle-view-mainpage": "{{SITENAME}}",
+       "backlinksubtitle": "←$1",
        "retrievedfrom": "\"$1\" adresinden alındı.",
        "youhavenewmessages": "$1 {{PLURAL:$3|var}} ($2).",
        "youhavenewmessagesfromusers": "{{PLURAL:$3|Başka bir kullanıcıdan|$3 kullanıcıdan}} $1 var ($2).",
index 84c45fa..bc12336 100644 (file)
        "logentry-rights-rights": "$1 {{GENDER:$1|змінив|змінила}} членство в групах для $3 із $4 на $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$1|змінив|змінила}} членство в групах для $3",
        "logentry-rights-autopromote": "$1 було автоматично переведено із $4 в $5",
+       "logentry-upload-upload": "$1 {{GENDER:$2|завантажив|завантажила}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|завантажив|завантажила}} нову версію $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|завантажив|завантажила}} $3",
        "rightsnone": "(нема)",
        "feedback-bugornote": "Якщо ви готові описати технічні проблеми в деталях, будь ласка, [$1 повідомте про помилку].\nАбо можете використати форму нижче. Ваш коментар буде додано на сторінку \"[$3  $2]\", разом з іменем користувача.",
        "feedback-subject": "Тема:",
index af52399..77f5c47 100644 (file)
        "windows-nonascii-filename": "箇wiki弗支持文件名用特別個字符。",
        "uploadwarning": "上载警告",
        "savefile": "保存文件",
-       "uploadedimage": "上传 \"[[$1]]\"",
        "sourcefilename": "源文件:",
        "destfilename": "目标文件名:",
        "watchthisupload": "關注箇文件",
index 839fb90..b40630f 100644 (file)
@@ -77,7 +77,8 @@
                        "아라",
                        "Mywood",
                        "Impersonator 1",
-                       "Duolaimi"
+                       "Duolaimi",
+                       "TianyinLee"
                ]
        },
        "tog-underline": "链接下划线:",
        "mainpage": "首页",
        "mainpage-description": "首页",
        "policy-url": "Project:方针",
-       "portal": "社å\8cºä¸\93页",
+       "portal": "社å\8cºä¸»页",
        "portal-url": "Project:社区专页",
        "privacy": "隐私权政策",
        "privacypage": "Project:隐私权政策",
        "logentry-rights-rights": "$1{{GENDER:$2|更改}}$3的用户组自$4至$5",
        "logentry-rights-rights-legacy": "$1更改$3的用户组",
        "logentry-rights-autopromote": "$1被自动地{{GENDER:$2|提升}}自$4至$5",
+       "logentry-upload-upload": "$1{{GENDER:$2|上传了}}$3",
+       "logentry-upload-overwrite": "$1{{GENDER:$2|上传了}}$3的新版本",
+       "logentry-upload-revert": "$1{{GENDER:$2|上传了}}$3",
        "rightsnone": "(无)",
        "feedback-bugornote": "如果你准备好详细描述一个技术问题,请[$1 报告bug]。或者你可以使用下面的简单表格。你的评论将被添加至页面“[$3 $2]”,附有你的用户名。",
        "feedback-subject": "主题:",
index c890c69..adebd27 100644 (file)
@@ -47,7 +47,7 @@ class Undelete extends Maintenance {
                if ( !$wgUser ) {
                        $this->error( "Invalid username", true );
                }
-               $archive = new PageArchive( $title );
+               $archive = new PageArchive( $title, RequestContext::getMain()->getConfig() );
                $this->output( "Undeleting " . $title->getPrefixedDBkey() . '...' );
                $archive->undelete( array(), $reason );
                $this->output( "done\n" );
index 50df67a..02bdafa 100644 (file)
                        "Xiaomingyan",
                        "Yfdyh000",
                        "Zhangjintao",
-                       "乌拉跨氪"
+                       "乌拉跨氪",
+                       "Great Brightstar"
                ]
        },
        "ooui-outline-control-move-down": "下移项",
        "ooui-outline-control-move-up": "上移项",
        "ooui-outline-control-remove": "删除项",
        "ooui-toolbar-more": "更多",
-       "ooui-dialog-message-accept": "",
+       "ooui-dialog-message-accept": "确定",
        "ooui-dialog-message-reject": "取消",
        "ooui-dialog-process-error": "发生一些错误",
        "ooui-dialog-process-dismiss": "解除",
index 525304c..22c3079 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (dd294dc785)
+ * OOjs UI v0.1.0-pre (0e50d2e336)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2014-07-30T23:10:53Z
+ * Date: 2014-08-06T12:56:55Z
  */
 .oo-ui-dialog-content > .oo-ui-window-head,
 .oo-ui-dialog-content > .oo-ui-window-body,
index 1267a3c..c53772e 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (dd294dc785)
+ * OOjs UI v0.1.0-pre (0e50d2e336)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2014-07-30T23:10:53Z
+ * Date: 2014-08-06T12:56:55Z
  */
 .oo-ui-dialog-content > .oo-ui-window-head,
 .oo-ui-dialog-content > .oo-ui-window-body,
index 737113e..6f63575 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (dd294dc785)
+ * OOjs UI v0.1.0-pre (0e50d2e336)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2014-07-30T23:10:53Z
+ * Date: 2014-08-06T12:56:55Z
  */
 ( function ( OO ) {
 
@@ -1114,6 +1114,7 @@ OO.ui.Frame = function OoUiFrame( config ) {
        // Properties
        this.loading = null;
        this.config = config;
+       this.dir = null;
 
        // Initialize
        this.$element
@@ -1287,7 +1288,7 @@ OO.ui.Frame.prototype.load = function () {
        win = this.$element.prop( 'contentWindow' );
        doc = win.document;
 
-       // Figure out directionality:
+       // Cache directionality
        this.dir = OO.ui.Element.getDir( this.$element ) || 'ltr';
 
        // Initialize contents
@@ -1298,7 +1299,7 @@ OO.ui.Frame.prototype.load = function () {
        doc.write(
                '<!doctype html>' +
                '<html>' +
-                       '<body class="oo-ui-frame-content oo-ui-' + this.dir + '" dir="' + this.dir + '">' +
+                       '<body class="oo-ui-frame-content oo-ui-' + this.getDir() + '" dir="' + this.getDir() + '">' +
                        '</body>' +
                '</html>'
        );
@@ -1331,6 +1332,15 @@ OO.ui.Frame.prototype.setSize = function ( width, height ) {
        return this;
 };
 
+/**
+ * Get the directionality of the frame
+ *
+ * @return {string} Directionality, 'ltr' or 'rtl'
+ */
+OO.ui.Frame.prototype.getDir = function () {
+       return this.dir;
+};
+
 /**
  * Container for elements.
  *
index bffc230..aa5e6ac 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (dd294dc785)
+ * OOjs UI v0.1.0-pre (0e50d2e336)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2014-07-30T23:10:53Z
+ * Date: 2014-08-06T12:56:55Z
  */
 /* Textures */
 
index 41707aa..6996ab8 100644 (file)
@@ -34,6 +34,7 @@
        width: 100%;
        padding: .3em .3em .3em .6em;
        display: block;
+       vertical-align: middle;
        // Override user agent stylesheet properties. Instead use parent element.
        color: inherit;
        font-family: inherit;
@@ -97,8 +98,14 @@ textarea.mw-ui-input {
 .mw-ui-input-large {
        margin-top: 0;
        margin-bottom: 0;
+
+       // When two large inputs are together, we make them flush by hiding one of the borders
        & + .mw-ui-input-large {
-               border-top-width: 0;
+               margin-top: -1px;
+       }
+       // When focusing, make the input relative to raise it above any attached inputs to unhide its borders
+       &:focus {
+               position: relative;
        }
 }
 
index b5fd69c..79ec310 100644 (file)
                /**
                 * Display a notification message to the user.
                 *
-                * @param {HTMLElement|jQuery|mw.Message|string} message
+                * @param {HTMLElement|HTMLElement[]|jQuery|mw.Message|string} message
                 * @param {Object} options The options to use for the notification.
                 *  See #defaults for details.
                 * @return {mw.Notification} Notification object
index cd21ecc..e2f47f5 100644 (file)
@@ -24,10 +24,10 @@ function isCompatible( ua ) {
                ua = navigator.userAgent;
        }
 
-       // MediaWiki JS or jQuery is known to have issues with:
+       // Browsers with outdated or limited JavaScript engines get the no-JS experience
        return !(
-               // Internet Explorer < 6
-               ( ua.indexOf( 'MSIE' ) !== -1 && parseFloat( ua.split( 'MSIE' )[1] ) < 6 ) ||
+               // Internet Explorer < 7
+               ( ua.indexOf( 'MSIE' ) !== -1 && parseFloat( ua.split( 'MSIE' )[1] ) < 7 ) ||
                // Firefox < 3
                ( ua.indexOf( 'Firefox/' ) !== -1 && parseFloat( ua.split( 'Firefox/' )[1] ) < 3 ) ||
                // BlackBerry < 6
diff --git a/skins/common/IEFixes.js b/skins/common/IEFixes.js
deleted file mode 100644 (file)
index 545acad..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * IE fixes javascript loaded by wikibits.js for IE <= 6.0
- */
-/*global isMSIE55:true, doneIETransform:true, doneIEAlphaFix:true */
-/*global hookit:true, fixalpha:true */
-( function ( mw, $ ) {
-
-var expandedURLs, hasClass;
-
-// Also returns true for IE6, 7, 8, 9 and 10. createPopup is removed in IE11.
-// Good thing this is only loaded for IE <= 6 by wikibits.
-// Might as well set it to true.
-isMSIE55 = ( window.showModalDialog && window.clipboardData && window.createPopup );
-doneIETransform = false;
-doneIEAlphaFix = false;
-
-hookit = function () {
-       if ( !doneIETransform && document.getElementById && document.getElementById( 'bodyContent' ) ) {
-               doneIETransform = true;
-               fixalpha();
-       }
-};
-
-if ( document.attachEvent ) {
-       document.attachEvent( 'onreadystatechange', hookit );
-}
-
-// png alpha transparency fixes
-fixalpha = function ( logoId ) {
-       // bg
-       if ( isMSIE55 && !doneIEAlphaFix ) {
-               var bg, imageUrl, linkFix, logoa, logospan, plogo;
-               plogo = document.getElementById( logoId || 'p-logo' );
-               if ( !plogo ) {
-                       return;
-               }
-
-               logoa = plogo.getElementsByTagName('a')[0];
-               if ( !logoa ) {
-                       return;
-               }
-
-               bg = logoa.currentStyle.backgroundImage;
-               imageUrl = bg.substring( 5, bg.length - 2 );
-
-               doneIEAlphaFix = true;
-
-               if ( imageUrl.substr( imageUrl.length - 4 ).toLowerCase() === '.png' ) {
-                       logospan = logoa.appendChild( document.createElement( 'span' ) );
-
-                       logoa.style.backgroundImage = 'none';
-                       logospan.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + imageUrl + ')';
-                       logospan.style.height = '100%';
-                       logospan.style.position = 'absolute';
-                       logospan.style.width = logoa.currentStyle.width;
-                       logospan.style.cursor = 'hand';
-                       // Center image with hack for IE5.5
-                       if ( document.documentElement.dir === 'rtl' ) {
-                               logospan.style.right = '50%';
-                               logospan.style.setExpression( 'marginRight', '"-" + (this.offsetWidth / 2) + "px"' );
-                       } else {
-                               logospan.style.left = '50%';
-                               logospan.style.setExpression( 'marginLeft', '"-" + (this.offsetWidth / 2) + "px"' );
-                       }
-                       logospan.style.top = '50%';
-                       logospan.style.setExpression( 'marginTop', '"-" + (this.offsetHeight / 2) + "px"' );
-
-                       linkFix = logoa.appendChild( logoa.cloneNode() );
-                       linkFix.style.position = 'absolute';
-                       linkFix.style.height = '100%';
-                       linkFix.style.width = '100%';
-               }
-       }
-};
-
-if ( isMSIE55 ) {
-       // ondomready
-       $( fixalpha );
-}
-
-// Expand links for printing
-hasClass = function ( classText, classWanted ) {
-       var i = 0, classArr = classText.split(/\s/);
-       for ( i = 0; i < classArr.length; i++ ) {
-               if ( classArr[i].toLowerCase() === classWanted.toLowerCase() ) {
-                       return true;
-               }
-       }
-       return false;
-};
-
-window.onbeforeprint = function () {
-       var allLinks, contentEl, expandedLink, expandedText, i;
-
-       expandedURLs = [];
-       contentEl = document.getElementById( 'content' );
-
-       if ( contentEl ) {
-               allLinks = contentEl.getElementsByTagName( 'a' );
-
-               for ( i = 0; i < allLinks.length; i++ ) {
-                       if ( hasClass( allLinks[i].className, 'external' ) && !hasClass( allLinks[i].className, 'free' ) ) {
-                               expandedLink = document.createElement( 'span' );
-                               expandedText = document.createTextNode( ' (' + allLinks[i].href + ')' );
-                               expandedLink.appendChild( expandedText );
-                               allLinks[i].parentNode.insertBefore( expandedLink, allLinks[i].nextSibling );
-                               expandedURLs[i] = expandedLink;
-                       }
-               }
-       }
-};
-
-window.onafterprint = function () {
-       for ( var i = 0; i < expandedURLs.length; i++ ) {
-               if ( expandedURLs[i] ) {
-                       expandedURLs[i].removeNode( true );
-               }
-       }
-};
-
-}( mediaWiki, jQuery ) );
index b6689f9..5c6e63b 100644 (file)
@@ -5,7 +5,6 @@
        var msg,
                win = window,
                ua = navigator.userAgent.toLowerCase(),
-               isIE6 = ( /msie ([0-9]{1,}[\.0-9]{0,})/.exec( ua ) && parseFloat( RegExp.$1 ) <= 6.0 ),
                onloadFuncts = [];
 
 /**
@@ -199,8 +198,4 @@ win.importStylesheetURI = function ( url, media ) {
        return l;
 };
 
-if ( isIE6 ) {
-       win.importScriptURI( mw.config.get( 'stylepath' ) + '/common/IEFixes.js' );
-}
-
 }( mediaWiki, jQuery ) );
index 6a36b4b..c2acec0 100644 (file)
@@ -317,4 +317,52 @@ class MessageTest extends MediaWikiLangTestCase {
        public function testInLanguageThrows() {
                wfMessage( 'foo' )->inLanguage( 123 );
        }
+
+       public function keyProvider() {
+               return array(
+                       'string' => array(
+                               'key' => 'mainpage',
+                               'expected' => array( 'mainpage' ),
+                       ),
+                       'single' => array(
+                               'key' => array( 'mainpage' ),
+                               'expected' => array( 'mainpage' ),
+                       ),
+                       'multi' => array(
+                               'key' => array( 'mainpage-foo', 'mainpage-bar', 'mainpage' ),
+                               'expected' => array( 'mainpage-foo', 'mainpage-bar', 'mainpage' ),
+                       ),
+                       'empty' => array(
+                               'key' => array(),
+                               'expected' => null,
+                               'exception' => 'InvalidArgumentException',
+                       ),
+                       'null' => array(
+                               'key' => null,
+                               'expected' => null,
+                               'exception' => 'InvalidArgumentException',
+                       ),
+                       'bad type' => array(
+                               'key' => 17,
+                               'expected' => null,
+                               'exception' => 'InvalidArgumentException',
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider keyProvider()
+        *
+        * @covers Message::getKey
+        */
+       public function testGetKey( $key, $expected, $exception = null ) {
+               if ( $exception ) {
+                       $this->setExpectedException( $exception );
+               }
+
+               $msg = new Message( $key );
+               $this->assertEquals( $expected, $msg->getKeysToTry() );
+               $this->assertEquals( count( $expected ) > 1, $msg->isMultiKey() );
+               $this->assertContains( $msg->getKey(), $expected );
+       }
 }
diff --git a/tests/phpunit/includes/api/ApiModuleManagerTest.php b/tests/phpunit/includes/api/ApiModuleManagerTest.php
new file mode 100644 (file)
index 0000000..1ac9b9d
--- /dev/null
@@ -0,0 +1,274 @@
+<?php
+
+/**
+ * @covers ApiModuleManager
+ *
+ * @group API
+ * @group Database
+ * @group medium
+ */
+class ApiModuleManagerTest extends MediaWikiTestCase {
+
+       private function getModuleManager() {
+               $request = new FauxRequest();
+               $main = new ApiMain( $request );
+               return new ApiModuleManager( $main );
+       }
+
+       public function newApiLogin( $main, $action ) {
+               return new ApiLogin( $main, $action );
+       }
+
+       public function addModuleProvider() {
+               return array(
+                       'plain class' => array(
+                               'login',
+                               'action',
+                               'ApiLogin',
+                               null,
+                       ),
+
+                       'with factory' => array(
+                               'login',
+                               'action',
+                               'ApiLogin',
+                               array( $this, 'newApiLogin' ),
+                       ),
+
+                       'with closure' => array(
+                               'logout',
+                               'action',
+                               'ApiLogout',
+                               function( ApiMain $main, $action ) {
+                                               return new ApiLogout( $main, $action );
+                               },
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider addModuleProvider
+        */
+       public function testAddModule( $name, $group, $class, $factory = null ) {
+               $moduleManager = $this->getModuleManager();
+               $moduleManager->addModule( $name, $group, $class, $factory );
+
+               $this->assertTrue( $moduleManager->isDefined( $name, $group ), 'isDefined' );
+               $this->assertNotNull( $moduleManager->getModule( $name, $group, true ), 'getModule' );
+       }
+
+       public function addModulesProvider() {
+               return array(
+                       'empty' => array(
+                               array(),
+                               'action',
+                       ),
+
+                       'simple' => array(
+                               array(
+                                       'login' => 'ApiLogin',
+                                       'logout' => 'ApiLogout',
+                               ),
+                               'action',
+                       ),
+
+                       'with factories' => array(
+                               array(
+                                       'login' => array(
+                                               'class' => 'ApiLogin',
+                                               'factory' => array( $this, 'newApiLogin' ),
+                                       ),
+                                       'logout' => array(
+                                               'class' => 'ApiLogout',
+                                               'factory' => function( ApiMain $main, $action ) {
+                                                       return new ApiLogout( $main, $action );
+                                               },
+                                       ),
+                               ),
+                               'action',
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider addModulesProvider
+        */
+       public function testAddModules( array $modules, $group ) {
+               $moduleManager = $this->getModuleManager();
+               $moduleManager->addModules( $modules, $group );
+
+               foreach ( array_keys( $modules ) as $name ) {
+                       $this->assertTrue( $moduleManager->isDefined( $name, $group ), 'isDefined' );
+                       $this->assertNotNull( $moduleManager->getModule( $name, $group, true ), 'getModule' );
+               }
+       }
+
+       public function getModuleProvider() {
+               $modules = array(
+                       'feedrecentchanges' => 'ApiFeedRecentChanges',
+                       'feedcontributions' => array( 'class' => 'ApiFeedContributions' ),
+                       'login' => array(
+                               'class' => 'ApiLogin',
+                               'factory' => array( $this, 'newApiLogin' ),
+                       ),
+                       'logout' => array(
+                               'class' => 'ApiLogout',
+                               'factory' => function( ApiMain $main, $action ) {
+                                               return new ApiLogout( $main, $action );
+                                       },
+                       ),
+               );
+
+               return array(
+                       'legacy entry' => array(
+                               $modules,
+                               'feedrecentchanges',
+                               'ApiFeedRecentChanges',
+                       ),
+
+                       'just a class' => array(
+                               $modules,
+                               'feedcontributions',
+                               'ApiFeedContributions',
+                       ),
+
+                       'with factory' => array(
+                               $modules,
+                               'login',
+                               'ApiLogin',
+                       ),
+
+                       'with closure' => array(
+                               $modules,
+                               'logout',
+                               'ApiLogout',
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider getModuleProvider
+        */
+       public function testGetModule( $modules, $name, $expectedClass ) {
+               $moduleManager = $this->getModuleManager();
+               $moduleManager->addModules( $modules, 'test' );
+
+               // should return the right module
+               $module1 = $moduleManager->getModule( $name, null, false );
+               $this->assertInstanceOf( $expectedClass, $module1 );
+
+               // should pass group check (with caching disabled)
+               $module2 = $moduleManager->getModule( $name, 'test', true );
+               $this->assertNotNull( $module2 );
+
+               // should use cached instance
+               $module3 = $moduleManager->getModule( $name, null, false );
+               $this->assertSame( $module1, $module3 );
+
+               // should not use cached instance if caching is disabled
+               $module4 = $moduleManager->getModule( $name, null, true );
+               $this->assertNotSame( $module1, $module4 );
+       }
+
+       public function testGetModule_null() {
+               $modules = array(
+                       'login' => 'ApiLogin',
+                       'logout' => 'ApiLogout',
+               );
+
+               $moduleManager = $this->getModuleManager();
+               $moduleManager->addModules( $modules, 'test' );
+
+               $this->assertNull( $moduleManager->getModule( 'quux' ), 'unknown name' );
+               $this->assertNull( $moduleManager->getModule( 'login', 'bla' ), 'wrong group' );
+       }
+
+       public function testGetNames() {
+               $fooModules = array(
+                       'login' => 'ApiLogin',
+                       'logout' => 'ApiLogout',
+               );
+
+               $barModules = array(
+                       'feedcontributions' => array( 'class' => 'ApiFeedContributions' ),
+                       'feedrecentchanges' => array( 'class' => 'ApiFeedRecentChanges' ),
+               );
+
+               $moduleManager = $this->getModuleManager();
+               $moduleManager->addModules( $fooModules, 'foo' );
+               $moduleManager->addModules( $barModules, 'bar' );
+
+               $fooNames = $moduleManager->getNames( 'foo' );
+               $this->assertArrayEquals( array_keys( $fooModules ), $fooNames );
+
+               $allNames = $moduleManager->getNames();
+               $allModules = array_merge( $fooModules, $barModules );
+               $this->assertArrayEquals( array_keys( $allModules ), $allNames );
+       }
+
+       public function testGetNamesWithClasses() {
+               $fooModules = array(
+                       'login' => 'ApiLogin',
+                       'logout' => 'ApiLogout',
+               );
+
+               $barModules = array(
+                       'feedcontributions' => array( 'class' => 'ApiFeedContributions' ),
+                       'feedrecentchanges' => array( 'class' => 'ApiFeedRecentChanges' ),
+               );
+
+               $moduleManager = $this->getModuleManager();
+               $moduleManager->addModules( $fooModules, 'foo' );
+               $moduleManager->addModules( $barModules, 'bar' );
+
+               $fooNamesWithClasses = $moduleManager->getNamesWithClasses( 'foo' );
+               $this->assertArrayEquals( $fooModules, $fooNamesWithClasses );
+
+               $allNamesWithClasses = $moduleManager->getNamesWithClasses();
+               $allModules = array_merge( $fooModules, array(
+                       'feedcontributions' => 'ApiFeedContributions',
+                       'feedrecentchanges' => 'ApiFeedRecentChanges',
+               ) );
+               $this->assertArrayEquals( $allModules, $allNamesWithClasses );
+       }
+
+       public function testGetModuleGroup() {
+               $fooModules = array(
+                       'login' => 'ApiLogin',
+                       'logout' => 'ApiLogout',
+               );
+
+               $barModules = array(
+                       'feedcontributions' => array( 'class' => 'ApiFeedContributions' ),
+                       'feedrecentchanges' => array( 'class' => 'ApiFeedRecentChanges' ),
+               );
+
+               $moduleManager = $this->getModuleManager();
+               $moduleManager->addModules( $fooModules, 'foo' );
+               $moduleManager->addModules( $barModules, 'bar' );
+
+               $this->assertEquals( 'foo', $moduleManager->getModuleGroup( 'login' ) );
+               $this->assertEquals( 'bar', $moduleManager->getModuleGroup( 'feedrecentchanges' ) );
+               $this->assertNull( $moduleManager->getModuleGroup( 'quux' ) );
+       }
+
+       public function testGetGroups() {
+               $fooModules = array(
+                       'login' => 'ApiLogin',
+                       'logout' => 'ApiLogout',
+               );
+
+               $barModules = array(
+                       'feedcontributions' => array( 'class' => 'ApiFeedContributions' ),
+                       'feedrecentchanges' => array( 'class' => 'ApiFeedRecentChanges' ),
+               );
+
+               $moduleManager = $this->getModuleManager();
+               $moduleManager->addModules( $fooModules, 'foo' );
+               $moduleManager->addModules( $barModules, 'bar' );
+
+               $groups = $moduleManager->getGroups();
+               $this->assertArrayEquals( array( 'foo', 'bar' ), $groups );
+       }
+
+}
index 38beb87..13da33c 100644 (file)
@@ -10,12 +10,15 @@ class PrefixUniquenessTest extends MediaWikiTestCase {
        public function testPrefixes() {
                $main = new ApiMain( new FauxRequest() );
                $query = new ApiQuery( $main, 'foo', 'bar' );
-               $modules = $query->getModuleManager()->getNamesWithClasses();
+               $moduleManager = $query->getModuleManager();
+
+               $modules = $moduleManager->getNames();
                $prefixes = array();
 
-               foreach ( $modules as $name => $class ) {
-                       /** @var ApiQueryBase $module */
-                       $module = new $class( $query, $name );
+               foreach ( $modules as $name ) {
+                       $module = $moduleManager->getModule( $name );
+                       $class = get_class( $module );
+
                        $prefix = $module->getModulePrefix();
                        if ( isset( $prefixes[$prefix] ) ) {
                                $this->fail( "Module prefix '{$prefix}' is shared between {$class} and {$prefixes[$prefix]}" );
index 9216ac9..2fd3ce9 100644 (file)
                                '</table>'
                );
                $table.tablesorter();
-               assert.equal( 0,
-                       $table.find( '#A2' ).prop( 'headerIndex' ),
-                       'A2 should be a sort header'
+               assert.equal( $table.find( '#A2' ).prop( 'headerIndex' ),
+                       0,
+                       'A2 should not be a sort header'
                );
-               assert.equal( 1, // should be 2
-                       $table.find( '#C1' ).prop( 'headerIndex' ),
+               assert.equal( $table.find( '#C1' ).prop( 'headerIndex' ),
+                       1,
                        'C1 should be a sort header, but will sort the wrong column'
                );
        } );
                        '</tbody></table>' );
 
                        $table.tablesorter();
-                       assert.equal( 2, $table.find( 'tr:eq(1) th:eq(1)').prop('headerIndex'), 'Incorrect index of sort header' );
+                       assert.equal( $table.find( 'tr:eq(1) th:eq(1)').prop('headerIndex'),
+                               2,
+                               'Incorrect index of sort header' );
                }
        );
 
index 4e26bdc..dcab387 100644 (file)
@@ -17,8 +17,7 @@
                        'Mozilla/5.0 (Macintosh; I; Intel Mac OS X 10_6_7; ru-ru) AppleWebKit/534.31+ (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1',
                        // Opera 11+
                        'Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.8.131 Version/11.10',
-                       // Internet Explorer 6+
-                       'Mozilla/5.0 (compatible; MSIE 6.0; Windows NT 5.1)',
+                       // Internet Explorer 7+
                        'Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.0; en-US)',
                        'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; Media Center PC 4.0; SLCC1; .NET CLR 3.0.04320)',
                        'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)',
                        'Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17'
                ],
                // Supported: Uncompatible, serve basic content
-               gradeB: [
-                       // Internet Explorer < 6
+               gradeC: [
+                       // Internet Explorer < 7
                        'Mozilla/2.0 (compatible; MSIE 3.03; Windows 3.1)',
                        'Mozilla/4.0 (compatible; MSIE 4.01; Windows 95)',
                        'Mozilla/4.0 (compatible; MSIE 5.0; Windows 98;)',
                        'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
+                       'Mozilla/5.0 (compatible; MSIE 6.0; Windows NT 5.1)',
                        // Firefox < 3.6
                        'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.2) Gecko/20060308 Firefox/1.5.0.2',
                        'Mozilla/5.0 (X11; U; Linux i686; nl; rv:1.8.1.1) Gecko/20070311 Firefox/2.0.0.1',
                );
        } );
 
-       QUnit.test( 'isCompatible( Grade B )', testcases.gradeB.length, function ( assert ) {
-               $.each( testcases.gradeB, function ( i, ua ) {
+       QUnit.test( 'isCompatible( Grade C )', testcases.gradeC.length, function ( assert ) {
+               $.each( testcases.gradeC, function ( i, ua ) {
                                assert.strictEqual( isCompatible( ua ), false, ua );
                        }
                );