https://www.mediawiki.org/wiki/Special:Code/MediaWiki/112991

Revision: 112991
Author:   krinkle
Date:     2012-03-04 23:56:25 +0000 (Sun, 04 Mar 2012)
Log Message:
-----------
[JSGrammar] Various minor tips, tricks and clean up.
* mediawiki.language.js:
-- Implement mw.language.getData and setData. This avoids having to repeat the 
"if data[langCode] === undefined" code pattern all over the place (which in 
practice often results in the check not being programmed or forgotten (such as 
in mw.lang.convertGrammar)).
   setData will initialize the object on-demand when needed.
   getData will return 'undefined' if the object doesn't exist (whereas 
mw.langauge.data[someCode].get would throw an exception if the object doesn't 
exist)
-- Checking for $.isArray instead of thruthy-ness in convertPlural() and 
gender(). When isolated a truth check could be sufficient (it would fail when 
given a non-array thruthy value, but people simply shouldn't do that). However 
since the second check compares.length === 0 it makes sense to be sure it's an 
array first.
-- Create 'var language' as local object (for shortcut and slight performance 
benefit), later exposing into mw.language
-- Remove redundant truthy check for 'mw.language.convertPlural', this is 
defined the block below
-- Few comment fixes (var types, integer vs. Number in javascript)
-- Applying JS conventions

* ResourceLoaderLanguageModule
-- Rename module from 'language' to 'mediawiki.language.data'
-- Simplify ResourceLoaderLanguageModule::getScript
-- Add more elaborate FIXME note in 
ResourceLoaderLanguageModule::getModifiedTime. I haven't figured out how to 
properly cache and (more importantly) detect a change and purge the cache 
automatically for a PHP global in a ResourceLoader JS module

Modified Paths:
--------------
    branches/jsgrammar/includes/AutoLoader.php
    branches/jsgrammar/resources/Resources.php
    branches/jsgrammar/resources/mediawiki.language/mediawiki.language.js
    branches/jsgrammar/tests/qunit/QUnitTestResources.php

Added Paths:
-----------
    
branches/jsgrammar/includes/resourceloader/ResourceLoaderLanguageDataModule.php

Removed Paths:
-------------
    branches/jsgrammar/includes/resourceloader/ResourceLoaderLanguageModule.php

Modified: branches/jsgrammar/includes/AutoLoader.php
===================================================================
--- branches/jsgrammar/includes/AutoLoader.php  2012-03-04 23:51:41 UTC (rev 
112990)
+++ branches/jsgrammar/includes/AutoLoader.php  2012-03-04 23:56:25 UTC (rev 
112991)
@@ -732,7 +732,7 @@
        'ResourceLoaderUserModule' => 
'includes/resourceloader/ResourceLoaderUserModule.php',
        'ResourceLoaderUserOptionsModule' => 
'includes/resourceloader/ResourceLoaderUserOptionsModule.php',
        'ResourceLoaderUserTokensModule' => 
'includes/resourceloader/ResourceLoaderUserTokensModule.php',
-       'ResourceLoaderLanguageModule' => 
'includes/resourceloader/ResourceLoaderLanguageModule.php',
+       'ResourceLoaderLanguageDataModule' => 
'includes/resourceloader/ResourceLoaderLanguageDataModule.php',
        'ResourceLoaderWikiModule' => 
'includes/resourceloader/ResourceLoaderWikiModule.php',
 
        # includes/revisiondelete

Copied: 
branches/jsgrammar/includes/resourceloader/ResourceLoaderLanguageDataModule.php 
(from rev 112977, 
branches/jsgrammar/includes/resourceloader/ResourceLoaderLanguageModule.php)
===================================================================
--- 
branches/jsgrammar/includes/resourceloader/ResourceLoaderLanguageDataModule.php 
                            (rev 0)
+++ 
branches/jsgrammar/includes/resourceloader/ResourceLoaderLanguageDataModule.php 
    2012-03-04 23:56:25 UTC (rev 112991)
@@ -0,0 +1,86 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Santhosh Thottingal
+ * @author Timo Tijhof
+ */
+
+/**
+ * ResourceLoader module for populating language specific data.
+ */
+class ResourceLoaderLanguageDataModule extends ResourceLoaderModule {
+
+       /**
+        * Get the grammer forms for the site content language.
+        *
+        * @return array
+        */
+       protected function getSiteLangGrammarForms() {
+               global $wgContLang;
+               return $wgContLang->getGrammarForms();
+       }
+
+       /**
+        * @param $context ResourceLoaderContext
+        * @return string Javascript code
+        */
+       public function getScript( ResourceLoaderContext $context ) {
+               global $wgContLang;
+
+               return Xml::encodeJsCall( 'mw.language.setData', array(
+                       $wgContLang->getCode(),
+                       $this->getSiteLangGrammarForms()
+               ) );
+       }
+
+       /**
+        * @param $context ResourceLoaderContext
+        * @return array|int|Mixed
+        */
+       public function getModifiedTime( ResourceLoaderContext $context ) {
+               global $wgCacheEpoch;
+
+               /**
+                * @todo FIXME: This needs to change whenever the array created 
by
+                * $wgContLang->getGrammarForms() changes. Which gets its data 
from
+                * $wgGrammarForms, which (for standard installations) comes 
from LocalSettings
+                * and $wgCacheEpoch would cover that. However there's two 
three problems:
+                *
+                * 1) $wgCacheEpoch is not meant for this use.
+                * 2) If $wgInvalidateCacheOnLocalSettingsChange is set to 
false,
+                *    $wgCacheEpoch will not be raised if LocalSettings is 
modified (see #1).
+                * 3) $wgGrammarForms can be set from anywhere. For example on 
WMF it is set
+                *    by the WikimediaMessages extension. Other farms might set 
it form
+                *    their 'CommonSettings.php'-like file or something (see 
#1).
+                *
+                * Possible solutions:
+                * - Store grammarforms in the language object cache instead of 
directly
+                *   from the global everytime. Then use 
$wgContLang->getLastModified().
+                * - Somehow monitor the value of $wgGrammarForms.
+                */
+
+               return $wgCacheEpoch;
+       }
+
+       /**
+        * @return array
+        */
+       public function getDependencies() {
+               return array( 'mediawiki.language' );
+       }
+}

Deleted: 
branches/jsgrammar/includes/resourceloader/ResourceLoaderLanguageModule.php
===================================================================
--- branches/jsgrammar/includes/resourceloader/ResourceLoaderLanguageModule.php 
2012-03-04 23:51:41 UTC (rev 112990)
+++ branches/jsgrammar/includes/resourceloader/ResourceLoaderLanguageModule.php 
2012-03-04 23:56:25 UTC (rev 112991)
@@ -1,78 +0,0 @@
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @author Santhosh Thottingal
- * @author Timo Tijhof
- */
-
-/**
- * ResourceLoader module for generating language specific scripts/css.
- */
-class ResourceLoaderLanguageModule extends ResourceLoaderModule {
-
-       /**
-        * Get the grammer forms for the site content language.
-        *
-        * @return Array
-        */
-       protected function getSiteLangGrammarForms() {
-               global $wgContLang;
-               return $wgContLang->getGrammarForms();
-       }
-       /**
-        * @param $context ResourceLoaderContext
-        * @return string Javascript code
-        */
-       public function getScript( ResourceLoaderContext $context ) {
-               global $wgContLang;
-               $code = Xml::encodeJsVar( $wgContLang->getCode() );
-               $forms = Xml::encodeJsVar( $this->getSiteLangGrammarForms() );
-
-               $js =
-<<<JAVASCRIPT
-var langCode = $code,
-langData = mw.language.data;
-if ( langData[langCode] === undefined ) {
-       langData[langCode] = new mw.Map();
-}
-langData[langCode].set( "grammarForms", $forms );
-JAVASCRIPT;
-
-               return $js;
-       }
-       /**
-        * @param $context ResourceLoaderContext
-        * @return array|int|Mixed
-        */
-       public function getModifiedTime( ResourceLoaderContext $context ) {
-               global $wgCacheEpoch;
-               /*
-               global $wgContLang, $wgCacheEpoch;
-               return max( $wgCacheEpoch, $wgContLang->getLastModified() );
-               */
-
-               return $wgCacheEpoch;
-       }
-       /**
-        * @return array
-        */
-       public function getDependencies() {
-               return array( 'mediawiki.language' );
-       }
-}
-

Modified: branches/jsgrammar/resources/Resources.php
===================================================================
--- branches/jsgrammar/resources/Resources.php  2012-03-04 23:51:41 UTC (rev 
112990)
+++ branches/jsgrammar/resources/Resources.php  2012-03-04 23:56:25 UTC (rev 
112991)
@@ -12,8 +12,8 @@
        'user.options' => array( 'class' => 'ResourceLoaderUserOptionsModule' ),
        'user.cssprefs' => array( 'class' => 'ResourceLoaderUserCSSPrefsModule' 
),
        'user.tokens' => array( 'class' => 'ResourceLoaderUserTokensModule' ),
-       'language' => array( 'class' => 'ResourceLoaderLanguageModule' ),
        'filepage' => array( 'class' => 'ResourceLoaderFilePageModule' ),
+       'mediawiki.language.data' => array( 'class' => 
'ResourceLoaderLanguageDataModule' ),
 
        /* Skins */
 

Modified: branches/jsgrammar/resources/mediawiki.language/mediawiki.language.js
===================================================================
--- branches/jsgrammar/resources/mediawiki.language/mediawiki.language.js       
2012-03-04 23:51:41 UTC (rev 112990)
+++ branches/jsgrammar/resources/mediawiki.language/mediawiki.language.js       
2012-03-04 23:56:25 UTC (rev 112991)
@@ -5,48 +5,78 @@
  * Language.php in MediaWiki. This object contains methods for loading and
  * transforming message text.
  */
-( function( $, mw ) {
+( function ( $, mw ) {
 
-mw.language = {
+var language = {
        /**
-       * @var data {Object} Language related data
-       * Keyed by language, contains instances of mw.Map
-       * @example Set data
-       * <code>
-       * var langCode = 'nl';
-       * var langData = mw.language.data;
-       * if ( langData[langCode] === undefined ) {
-       *     langData[langCode] = new mw.Map();
-       * }
-       * langData[langCode].set( .. ); // Will override, extend or create the 
data
-       * </code>
-       * @example Get data
-       * <code>
-       * var grammarForms = mw.language.data[langCode].get( 'grammarForms' );
-       * </code>
-       */
+        * @var data {Object} Language related data (keyed by language,
+        * contains instances of mw.Map).
+        * @example Set data
+        * <code>
+        *     // Override, extend or create the language data object of 'nl'
+        *     mw.language.setData( 'nl', 'myKey', 'My value' );
+        * </code>
+        * @example Get GrammarForms data for language 'nl':
+        * <code>
+        *     var grammarForms = mw.language.getData( 'nl', 'grammarForms' );
+        * </code>
+        */
        data: {},
+
        /**
+        * Convenience method for retreiving language data by language code and 
data key,
+        * covering for the potential inexistance of a data object for this 
langiage.
+        * @param langCode {String} 
+        * @param dataKey {String}
+        * @return {mixed} Value stored in the mw.Map (or undefined if there is 
no map for
+          the specified langCode).
+        */
+       getData: function ( langCode, dataKey ) {
+               var langData = language.data;
+               if ( langData[langCode] instanceof mw.Map ) {
+                       return langData[langCode].get( dataKey );
+               }
+               return undefined;
+       },
+
+       /**
+        * Convenience method for setting language data by language code and 
data key.
+        * Creates a data object if there isn't one for the specified language 
already.
+        * @param langCode {String} 
+        * @param dataKey {String}
+        * @param value {mixed}
+        */
+       setData: function ( langCode, dataKey, value ) {
+               var langData = language.data;
+               if ( !( langData[langCode] instanceof mw.Map ) ) {
+                       langData[langCode] = new mw.Map();
+               }
+               langData[langCode].set( dataKey, value );
+       },
+
+       /**
         * Process the PLURAL template substitution
         *
-        * @param {object} template Template object
+        * @param template {Object} Template object
         * @format template
-        *      {
-        *              'title': [title of template],
-        *              'parameters': [template parameters]
-        *      }
+        *     {
+        *         title: [title of template],
+        *         parameters: [template parameters]
+        *     }
         * @example {{Template:title|params}}
         */
-       procPLURAL: function( template ) {
-               if ( template.title && template.parameters && 
mw.language.convertPlural ) {
+       procPLURAL: function ( template ) {
+               var count;
+
+       if ( template.title && template.parameters ) {
                        // Check if we have forms to replace
                        if ( template.parameters.length === 0 ) {
                                return '';
                        }
                        // Restore the count into a Number ( if it got 
converted earlier )
-                       var count = mw.language.convertNumber( template.title, 
true );
+                       count = language.convertNumber( template.title, true );
                        // Do convertPlural call
-                       return mw.language.convertPlural( parseInt( count, 10 
), template.parameters );
+                       return language.convertPlural( parseInt( count, 10 ), 
template.parameters );
                }
                // Could not process plural return first form or nothing
                if ( template.parameters[0] ) {
@@ -54,25 +84,27 @@
                }
                return '';
        },
+
        /**
         * Plural form transformations, needed for some languages.
         *
-        * @param count integer Non-localized quantifier
-        * @param forms array List of plural forms
-        * @return string Correct form for quantifier in this language
+        * @param count {Number} Non-localized quantifier
+        * @param forms {Array} List of plural forms
+        * @return {String} Correct form for quantifier in this language
         */
-       convertPlural: function( count, forms ){
-               if ( !forms || forms.length === 0 ) {
+       convertPlural: function ( count, forms ){
+               if ( !$.isArray( forms ) || forms.length === 0 ) {
                        return '';
                }
-               return ( parseInt( count, 10 ) == 1 ) ? forms[0] : forms[1];
+               return ( parseInt( count, 10 ) === 1 ) ? forms[0] : forms[1];
        },
+
        /**
         * Pads an array to a specific length by copying the last one element.
         *
-        * @param forms array Number of forms given to convertPlural
-        * @param count integer Number of forms required
-        * @return array Padded array of forms
+        * @param forms {Array} List of forms given to convertPlural
+        * @param count {Number} Number of forms required
+        * @return {Array} Padded array of forms
         */
        preConvertPlural: function( forms, count ) {
                while ( forms.length < count ) {
@@ -80,32 +112,35 @@
                }
                return forms;
        },
+
        /**
         * Converts a number using digitTransformTable.
         *
-        * @param {num} number Value to be converted
-        * @param {boolean} integer Convert the return value to an integer
+        * @param num {Number} Value to be converted
+        * @param integer {Boolean} Convert the return value to an integer
         */
        convertNumber: function( num, integer ) {
-               if ( !mw.language.digitTransformTable ) {
+               var transformTable, tmp, i, numberString, convertedNumber;
+
+               if ( !language.digitTransformTable ) {
                        return num;
                }
                // Set the target Transform table:
-               var transformTable = mw.language.digitTransformTable;
+               transformTable = language.digitTransformTable;
                // Check if the "restore" to Latin number flag is set:
                if ( integer ) {
-                       if ( parseInt( num, 10 ) == num ) {
+                       if ( parseInt( num, 10 ) === num ) {
                                return num;
                        }
-                       var tmp = [];
-                       for ( var i in transformTable ) {
+                       tmp = [];
+                       for ( i in transformTable ) {
                                tmp[ transformTable[ i ] ] = i;
                        }
                        transformTable = tmp;
                }
-               var numberString =  '' + num;
-               var convertedNumber = '';
-               for ( var i = 0; i < numberString.length; i++ ) {
+               numberString = String( num );
+               convertedNumber = '';
+               for ( i = 0; i < numberString.length; i++ ) {
                        if ( transformTable[ numberString[i] ] ) {
                                convertedNumber += 
transformTable[numberString[i]];
                        } else {
@@ -114,6 +149,7 @@
                }
                return integer ? parseInt( convertedNumber, 10 ) : 
convertedNumber;
        },
+
        /**
         * Provides an alternative text depending on specified gender.
         * Usage {{gender:[gender|user object]|masculine|feminine|neutral}}.
@@ -121,16 +157,17 @@
         *
         * These details may be overriden per language.
         *
-        * @param gender string male, female, or anything else for neutral.
-        * @param forms array List of gender forms
+        * @param gender {String} Male, female, or anything else for neutral.
+        * @param forms {Array} List of gender forms
         *
-        * @return string
+        * @return {String}
         */
-       gender: function( gender, forms ) {
-               if ( !forms || forms.length === 0 ) {
+
+       gender: function ( gender, forms ) {
+               if ( !$.isArray( forms ) || forms.length === 0 ) {
                        return '';
                }
-               forms = mw.language.preConvertPlural( forms, 2 );
+               forms = language.preConvertPlural( forms, 2 );
                if ( gender === 'male' ) {
                        return forms[0];
                }
@@ -139,24 +176,31 @@
                }
                return ( forms.length === 3 ) ? forms[2] : forms[0];
        },
+       
        /**
         * Grammatical transformations, needed for inflected languages.
         * Invoked by putting {{grammar:form|word}} in a message.
-        * The rules can be defined in wgGrammarForms global or grammar
+        * The rules can be defined in $wgGrammarForms global or grammar
         * forms can be computed dynamically by overriding this method per 
language
         *
-        * @param word string
-        * @param form string
-        * @return string
+        * @param word {String}
+        * @param form {String}
+        * @return {String}
         */
-       convertGrammar: function( word, form ) {
-               var grammarForms = mw.language.data[mw.config.get( 
'wgContentLanguage' )].get( 'grammarForms' );
+       convertGrammar: function ( word, form ) {
+               var grammarForms = language.getData( mw.config.get( 
'wgContentLanguage' ), 'grammarForms' );
                if ( grammarForms && grammarForms[form] ) {
                        return grammarForms[form][word] || word;
                }
                return word;
        },
-       // Digit Transform Table, populated by language classes where applicable
+
+       /**
+        * @var {Object} Digit Transform Table, populated by language classes 
where applicable.
+        */
        digitTransformTable: null
 };
-} )( jQuery, mediaWiki );
+
+mw.language = language;
+
+}( jQuery, mediaWiki ) );

Modified: branches/jsgrammar/tests/qunit/QUnitTestResources.php
===================================================================
--- branches/jsgrammar/tests/qunit/QUnitTestResources.php       2012-03-04 
23:51:41 UTC (rev 112990)
+++ branches/jsgrammar/tests/qunit/QUnitTestResources.php       2012-03-04 
23:56:25 UTC (rev 112991)
@@ -25,8 +25,8 @@
                        
'tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js',
                        
'tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js',
                        
'tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.js',
-                       
"tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js",
-                       
"tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js",
+                       
'tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js',
+                       
'tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js',
                ),
                'dependencies' => array(
                        'jquery.autoEllipsis',
@@ -43,7 +43,7 @@
                        'jquery.tablesorter',
                        'jquery.textSelection',
                        'mediawiki',
-                       'language',
+                       'mediawiki.language.data',
                        'mediawiki.Title',
                        'mediawiki.user',
                        'mediawiki.util',


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to