r68531 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r68530‎ | r68531 | r68532 >
Date:21:08, 24 June 2010
Author:dale
Status:deferred
Tags:
Comment:
* moved components into separate folder
* updated mwEmbed.js pointers in test files
Modified paths:
  • /branches/MwEmbedStandAlone/components (added) (history)
  • /branches/MwEmbedStandAlone/components/README (added) (history)
  • /branches/MwEmbedStandAlone/components/mw.Api.js (added) (history)
  • /branches/MwEmbedStandAlone/components/mw.Language.js (added) (history)
  • /branches/MwEmbedStandAlone/components/mw.Parser.js (added) (history)
  • /branches/MwEmbedStandAlone/languages/README (modified) (history)
  • /branches/MwEmbedStandAlone/languages/mw.Language.js (deleted) (history)
  • /branches/MwEmbedStandAlone/languages/mw.Parser.js (deleted) (history)
  • /branches/MwEmbedStandAlone/loader.js (modified) (history)
  • /branches/MwEmbedStandAlone/modules/AddMedia/tests/Add_Media_Wizard.html (modified) (history)
  • /branches/MwEmbedStandAlone/modules/AddMedia/tests/Firefogg_GUI.html (modified) (history)
  • /branches/MwEmbedStandAlone/modules/ApiProxy/tests/testApiProxy.html (modified) (history)
  • /branches/MwEmbedStandAlone/modules/EmbedPlayer/tests/Player_Audio.html (modified) (history)
  • /branches/MwEmbedStandAlone/modules/EmbedPlayer/tests/Player_Themable.html (modified) (history)
  • /branches/MwEmbedStandAlone/modules/EmbedPlayer/tests/Player_Timed_Text.html (deleted) (history)
  • /branches/MwEmbedStandAlone/modules/Sequencer/tests/Sequence_Editor.html (modified) (history)
  • /branches/MwEmbedStandAlone/modules/TimedText/tests (added) (history)
  • /branches/MwEmbedStandAlone/modules/TimedText/tests/Player_Timed_Text.html (added) (history)
  • /branches/MwEmbedStandAlone/mwEmbed.js (modified) (history)

Diff [purge]

Index: branches/MwEmbedStandAlone/loader.js
@@ -20,7 +20,8 @@
2121 */
2222 var mwCoreComponentList = [
2323 'mw.Parser',
24 - 'mw.Language'
 24+ 'mw.Language',
 25+ 'mw.Api'
2526 ];
2627
2728
@@ -116,8 +117,9 @@
117118 "mwEmbed" : "mwEmbed.js",
118119 "window.jQuery" : "libraries/jquery/jquery-1.4.2.js",
119120
120 - "mw.Language" : "languages/mw.Language.js",
121 - "mw.Parser" : "languages/mw.Parser.js",
 121+ "mw.Language" : "components/mw.Language.js",
 122+ "mw.Parser" : "components/mw.Parser.js",
 123+ "mw.Api" : "components/mw.Api.js",
122124
123125 "JSON" : "libraries/json/json2.js",
124126
Index: branches/MwEmbedStandAlone/components/mw.Language.js
@@ -0,0 +1,1118 @@
 2+/**
 3+* Core Language mw.Language object
 4+*
 5+* Localized Language support attempts to mirror some of the functionality of Language.php in MediaWiki
 6+* It contains methods for loading and transforming msg text
 7+
 8+*/
 9+
 10+( function( mw ) {
 11+
 12+ // Setup the global mw.Language var:
 13+ mw.Language = { };
 14+
 15+ /**
 16+ * Setup the lang object
 17+ */
 18+ var messageCache = { };
 19+ var gRuleSet = { };
 20+
 21+ /**
 22+ * mw.addMessages function
 23+ * Loads a set of json messages into the messegeCache object.
 24+ *
 25+ * @param {JSON} msgSet The set of msgs to be loaded
 26+ */
 27+ mw.addMessages = function( msgSet ) {
 28+ for ( var i in msgSet ) {
 29+ messageCache[ i ] = msgSet[i];
 30+ }
 31+ }
 32+ // By default set the current class missing messages flag to default.
 33+ mw.currentClassMissingMessages = false;
 34+
 35+ /**
 36+ * mw.addMessagesKey function
 37+ * Adds a messageKey to be pulled in remotely.
 38+ *
 39+ * NOTE the script-loader should replace addMessageKeys with localized addMessages calls
 40+ *
 41+ * If addMessagesKey is called then we are running in raw file debug mode.
 42+ * it populates the messegeKeyQueue and loads the values in a separate request callback
 43+ *
 44+ * @param {Array} msgSet The set of msgs to be loaded
 45+ */
 46+ mw.addMessageKeys = function( msgSet ) {
 47+ // Check if any msg key from this class is missing
 48+ for( var i in msgSet ){
 49+ if( ! messageCache[ i ] ) {
 50+ // Set the missing messages flag ( script-loader is probably off)
 51+ mw.currentClassMissingMessages = true;
 52+ return false;
 53+ }
 54+ }
 55+ return true;
 56+ }
 57+
 58+ /**
 59+ * Special function to register that all of the module messages need to be loaded.
 60+ */
 61+ mw.includeAllModuleMessages = function (){
 62+ mw.currentClassMissingMessages = true;
 63+ }
 64+
 65+ /**
 66+ * Load messages for a given named javascript class.
 67+ * This worked in conjunction with the scriptLoader
 68+ * @param {string} className Name of class file to be loaded
 69+ * @param {function} callback Function to be called once class messages are loaded.
 70+ */
 71+ mw.loadResourceMessages = function( className, callback ) {
 72+ // Check if wgScriptLoaderPath is set ( else guess the path relative to mwEmbed)
 73+ if ( typeof wgScriptLoaderLocation == 'undefined' || ! wgScriptLoaderLocation ){
 74+ wgScriptLoaderLocation = mw.getMwEmbedPath() + 'ResourceLoader.php';
 75+ }
 76+ // Run the addMessages script-loader call
 77+ mw.getScript( wgScriptLoaderLocation + '?class=' + className + '&format=messages', callback);
 78+ }
 79+
 80+
 81+ /**
 82+ * Returns a transformed msg string
 83+ *
 84+ * it take a msg key and array of replacement values of form
 85+ * $1, $2 and does relevant messageKey transformation returning
 86+ * the user msg.
 87+ *
 88+ * @param {String} messageKey The msg key as set by mw.addMessages
 89+ * @param {Mixed} args A string|jQuery Object or array of string|jQuery Objects
 90+ *
 91+ * extra parameters are appended to the args array as numbered replacements
 92+ *
 93+ * @return string
 94+ */
 95+ mw.getMsg = function( messageKey , args ) {
 96+
 97+ // Check for missing message key
 98+ if ( ! messageCache[ messageKey ] ){
 99+ return '[' + messageKey + ']';
 100+ }
 101+ // Check if we need to do args replacements:
 102+ if( typeof args != 'undefined' ) {
 103+
 104+ // Make arg into an array if its not already an array
 105+ if ( typeof args == 'string'
 106+ || typeof args == 'number'
 107+ || args instanceof jQuery )
 108+ {
 109+ args = [ args ];
 110+ }
 111+
 112+ // Put any extra arguments into the args array
 113+ var extraArgs = $j.makeArray( arguments );
 114+ for(var i=2; i < extraArgs.length; i ++ ) {
 115+ args.push( extraArgs[ i ] );
 116+ }
 117+ }
 118+ // Fast check message text return ( no arguments and no parsing needed )
 119+ if( ( !args || args.length == 0 )
 120+ && messageCache[ messageKey ].indexOf( '{{' ) === -1
 121+ && messageCache[ messageKey ].indexOf( '[' ) === -1
 122+ ) {
 123+ return messageCache[ messageKey ];
 124+ }
 125+
 126+ // Else Setup the messageSwap object:
 127+ var messageSwap = new mw.Language.messageSwapObject( messageCache[ messageKey ], args );
 128+
 129+ // Return the jQuery object or message string
 130+ return messageSwap.getMsg();
 131+ }
 132+
 133+ /**
 134+ * A message Swap Object
 135+ * Swap object manages message type swapping and returns jQuery or text output
 136+ *
 137+ * @param {String} message The text of the message
 138+ * @param {array} arguments A set of swap arguments
 139+ */
 140+
 141+ mw.Language.messageSwapObject = function( message, arguments ){
 142+ this.init( message, arguments );
 143+ }
 144+
 145+ mw.Language.messageSwapObject.prototype= {
 146+ /* constructor */
 147+ init: function( message, arguments ){
 148+ this.message = message;
 149+ this.arguments = arguments;
 150+
 151+ // Set the includesjQueryArgs flag to false
 152+ includesjQueryArgs: false;
 153+ },
 154+
 155+ // Return the transformed message text or jQuery object
 156+ getMsg: function(){
 157+ // Get message with string swap
 158+ this.replaceStringArgs();
 159+
 160+ // Check if we need to parse the string
 161+ if( this.message.indexOf( '{{' ) === -1
 162+ && this.message.indexOf( '[' ) === -1
 163+ && ! this.includesjQueryArgs )
 164+ {
 165+ // replaceStringArgs is all we need, return the msg
 166+ return this.message
 167+ }
 168+
 169+ // Else Send the messageText through the parser
 170+ var pObj = new mw.Parser( this.message );
 171+
 172+ // Get template and link transformed text:
 173+ this.message = pObj.getHTML();
 174+
 175+ // if jQuery arguments is false return message string
 176+ if(! this.includesjQueryArgs ){
 177+ //Do string link substitution
 178+ return this.message;
 179+ }
 180+
 181+ // jQuery arguments exist swap and return jQuery object
 182+ return this.getJQueryArgsReplace();
 183+
 184+ },
 185+
 186+ /**
 187+ * Swap in an array of values for $1, $2, $n for a given msg key
 188+ *
 189+ * @param string messageKey The msg key to lookup
 190+ * @param {Array} args An array of string or jQuery objects to be swapped in
 191+ * @return string
 192+ */
 193+ replaceStringArgs : function() {
 194+ if( ! this.arguments ) {
 195+ return ;
 196+ }
 197+ // Replace Values
 198+ for ( var v = 0; v < this.arguments.length; v++ ) {
 199+ if( typeof this.arguments[v] == 'undefined' ) {
 200+ continue;
 201+ }
 202+ var replaceValue = this.arguments[ v ];
 203+
 204+ // Convert number if applicable
 205+ if( parseInt( replaceValue ) == replaceValue ) {
 206+ replaceValue = mw.Language.convertNumber( replaceValue );
 207+ }
 208+
 209+ // Message test replace arguments start at 1 instead of zero:
 210+ var argumentRegExp = new RegExp( '\\$' + ( parseInt( v ) + 1 ), 'g' );
 211+
 212+ // Check if we got passed in a jQuery object:
 213+ if( replaceValue instanceof jQuery) {
 214+ // Set the jQuery msg flag
 215+ this.includesjQueryArgs = true;
 216+ // Swap in a jQuery span place holder:
 217+ this.message = this.message.replace( argumentRegExp,
 218+ '<span id="' + JQUERY_SWAP_STRING + v +'"></span>' );
 219+ } else {
 220+ // Assume replaceValue is a string
 221+ this.message = this.message.replace( argumentRegExp, replaceValue );
 222+ }
 223+ }
 224+ },
 225+
 226+ /**
 227+ * Return a jquery element with resolved swapped arguments.
 228+ * return {Element}
 229+ */
 230+ getJQueryArgsReplace: function() {
 231+ var $jQueryMessage = false;
 232+ mw.log( 'msgReplaceJQueryArgs' );
 233+ for ( var v = 0; v < this.arguments.length; v++ ) {
 234+ if( typeof this.arguments[v] == 'undefined' ) {
 235+ continue;
 236+ }
 237+ var $replaceValue = this.arguments[ v ];
 238+ // Only look for jQuery replacements
 239+ if( $replaceValue instanceof jQuery) {
 240+ // Setup the jqueryMessage if not set
 241+ if( !$jQueryMessage ){
 242+ // Setup the message as html to search for jquery swap points
 243+ $jQueryMessage = $j( '<span />' ).html( this.message );
 244+ }
 245+ mw.log(" current jQueryMessage::: " + $jQueryMessage.html() );
 246+ // Find swap target
 247+ var $swapTarget = $jQueryMessage.find( '#' + JQUERY_SWAP_STRING + v );
 248+ // Now we try and find the jQuerySwap points and replace with jQuery object preserving bindings.
 249+ if( ! $swapTarget.length ){
 250+ mw.log( "Error could not find jQuery Swap target: " + v + ' by id: '+ JQUERY_SWAP_STRING + v
 251+ + ' In string: ' + this.message ) ;
 252+ continue;
 253+ }
 254+
 255+ if( $swapTarget.html() != '' ) {
 256+ $replaceValue.html( $swapTarget.html() );
 257+ }
 258+
 259+ // Swap for $swapTarget for $replaceValue swap target * preserving the jQuery binding )
 260+ $swapTarget.replaceWith( $replaceValue );
 261+ }
 262+ }
 263+ // Return the jQuery object ( if no jQuery substitution occurred we return false )
 264+ return $jQueryMessage;
 265+ }
 266+ }
 267+
 268+ /**
 269+ * Get msg content without transformation
 270+ *
 271+ * @returns string The msg key without transforming it
 272+ */
 273+ mw.Language.msgNoTrans = function( key ) {
 274+ if ( messageCache[ key ] )
 275+ return messageCache[ key ]
 276+
 277+ // Missing key placeholder
 278+ return '&lt;' + key + '&gt;';
 279+ }
 280+
 281+ /**
 282+ * Add Supported Magic Words to parser
 283+ */
 284+ // Set the setupflag to false:
 285+ mw.Language.doneSetup = false;
 286+ mw.Language.magicSetup = function() {
 287+ if ( !mw.Language.doneSetup ) {
 288+ mw.addTemplateTransform ( {
 289+ 'PLURAL' : mw.Language.procPLURAL,
 290+ 'GENDER' : mw.Language.procGENDER
 291+ } )
 292+
 293+ mw.Language.doneSetup = true;
 294+ }
 295+
 296+ }
 297+
 298+ /**
 299+ * List of all languages mediaWiki supports ( Avoid an api call to get this same info )
 300+ * http://commons.wikimedia.org/w/api.php?action=query&meta=siteinfo&siprop=languages&format=jsonfm
 301+ */
 302+ mw.Language.names = {
 303+ "aa" : "Qaf\u00e1r af",
 304+ "ab" : "\u0410\u04a7\u0441\u0443\u0430",
 305+ "ace" : "Ac\u00e8h",
 306+ "af" : "Afrikaans",
 307+ "ak" : "Akan",
 308+ "aln" : "Geg\u00eb",
 309+ "als" : "Alemannisch",
 310+ "am" : "\u12a0\u121b\u122d\u129b",
 311+ "an" : "Aragon\u00e9s",
 312+ "ang" : "Anglo-Saxon",
 313+ "ar" : "\u0627\u0644\u0639\u0631\u0628\u064a\u0629",
 314+ "arc" : "\u0710\u072a\u0721\u071d\u0710",
 315+ "arn" : "Mapudungun",
 316+ "arz" : "\u0645\u0635\u0631\u0649",
 317+ "as" : "\u0985\u09b8\u09ae\u09c0\u09af\u09bc\u09be",
 318+ "ast" : "Asturianu",
 319+ "av" : "\u0410\u0432\u0430\u0440",
 320+ "avk" : "Kotava",
 321+ "ay" : "Aymar aru",
 322+ "az" : "Az\u0259rbaycan",
 323+ "ba" : "\u0411\u0430\u0448\u04a1\u043e\u0440\u0442",
 324+ "bar" : "Boarisch",
 325+ "bat-smg" : "\u017demait\u0117\u0161ka",
 326+ "bcc" : "\u0628\u0644\u0648\u0686\u06cc \u0645\u06a9\u0631\u0627\u0646\u06cc",
 327+ "bcl" : "Bikol Central",
 328+ "be" : "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f",
 329+ "be-tarask" : "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430)",
 330+ "be-x-old" : "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430)",
 331+ "bg" : "\u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438",
 332+ "bh" : "\u092d\u094b\u091c\u092a\u0941\u0930\u0940",
 333+ "bi" : "Bislama",
 334+ "bm" : "Bamanankan",
 335+ "bn" : "\u09ac\u09be\u0982\u09b2\u09be",
 336+ "bo" : "\u0f56\u0f7c\u0f51\u0f0b\u0f61\u0f72\u0f42",
 337+ "bpy" : "\u0987\u09ae\u09be\u09b0 \u09a0\u09be\u09b0\/\u09ac\u09bf\u09b7\u09cd\u09a3\u09c1\u09aa\u09cd\u09b0\u09bf\u09af\u09bc\u09be \u09ae\u09a3\u09bf\u09aa\u09c1\u09b0\u09c0",
 338+ "bqi" : "\u0628\u062e\u062a\u064a\u0627\u0631\u064a",
 339+ "br" : "Brezhoneg",
 340+ "bs" : "Bosanski",
 341+ "bug" : "\u1a05\u1a14 \u1a15\u1a18\u1a01\u1a17",
 342+ "bxr" : "\u0411\u0443\u0440\u044f\u0430\u0434",
 343+ "ca" : "Catal\u00e0",
 344+ "cbk-zam" : "Chavacano de Zamboanga",
 345+ "cdo" : "M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304",
 346+ "ce" : "\u041d\u043e\u0445\u0447\u0438\u0439\u043d",
 347+ "ceb" : "Cebuano",
 348+ "ch" : "Chamoru",
 349+ "cho" : "Choctaw",
 350+ "chr" : "\u13e3\u13b3\u13a9",
 351+ "chy" : "Tsets\u00eahest\u00e2hese",
 352+ "ckb" : "Soran\u00ee \/ \u06a9\u0648\u0631\u062f\u06cc",
 353+ "ckb-latn" : "\u202aSoran\u00ee (lat\u00een\u00ee)\u202c",
 354+ "ckb-arab" : "\u202b\u06a9\u0648\u0631\u062f\u06cc (\u0639\u06d5\u0631\u06d5\u0628\u06cc)\u202c",
 355+ "co" : "Corsu",
 356+ "cr" : "N\u0113hiyaw\u0113win \/ \u14c0\u1426\u1403\u152d\u140d\u140f\u1423",
 357+ "crh" : "Q\u0131r\u0131mtatarca",
 358+ "crh-latn" : "\u202aQ\u0131r\u0131mtatarca (Latin)\u202c",
 359+ "crh-cyrl" : "\u202a\u041a\u044a\u044b\u0440\u044b\u043c\u0442\u0430\u0442\u0430\u0440\u0434\u0436\u0430 (\u041a\u0438\u0440\u0438\u043b\u043b)\u202c",
 360+ "cs" : "\u010cesky",
 361+ "csb" : "Kasz\u00ebbsczi",
 362+ "cu" : "\u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f",
 363+ "cv" : "\u0427\u04d1\u0432\u0430\u0448\u043b\u0430",
 364+ "cy" : "Cymraeg",
 365+ "da" : "Dansk",
 366+ "de" : "Deutsch",
 367+ "de-at" : "\u00d6sterreichisches Deutsch",
 368+ "de-ch" : "Schweizer Hochdeutsch",
 369+ "de-formal" : "Deutsch (Sie-Form)",
 370+ "diq" : "Zazaki",
 371+ "dk" : "Dansk (deprecated:da)",
 372+ "dsb" : "Dolnoserbski",
 373+ "dv" : "\u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0",
 374+ "dz" : "\u0f47\u0f7c\u0f44\u0f0b\u0f41",
 375+ "ee" : "E\u028begbe",
 376+ "el" : "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac",
 377+ "eml" : "Emili\u00e0n e rumagn\u00f2l",
 378+ "en" : "English",
 379+ "en-gb" : "British English",
 380+ "eo" : "Esperanto",
 381+ "es" : "Espa\u00f1ol",
 382+ "et" : "Eesti",
 383+ "eu" : "Euskara",
 384+ "ext" : "Estreme\u00f1u",
 385+ "fa" : "\u0641\u0627\u0631\u0633\u06cc",
 386+ "ff" : "Fulfulde",
 387+ "fi" : "Suomi",
 388+ "fiu-vro" : "V\u00f5ro",
 389+ "fj" : "Na Vosa Vakaviti",
 390+ "fo" : "F\u00f8royskt",
 391+ "fr" : "Fran\u00e7ais",
 392+ "frc" : "Fran\u00e7ais cadien",
 393+ "frp" : "Arpetan",
 394+ "fur" : "Furlan",
 395+ "fy" : "Frysk",
 396+ "ga" : "Gaeilge",
 397+ "gag" : "Gagauz",
 398+ "gan" : "\u8d1b\u8a9e",
 399+ "gan-hans" : "\u8d63\u8bed(\u7b80\u4f53)",
 400+ "gan-hant" : "\u8d1b\u8a9e(\u7e41\u9ad4)",
 401+ "gd" : "G\u00e0idhlig",
 402+ "gl" : "Galego",
 403+ "glk" : "\u06af\u06cc\u0644\u06a9\u06cc",
 404+ "gn" : "Ava\u00f1e'\u1ebd",
 405+ "got" : "\ud800\udf32\ud800\udf3f\ud800\udf44\ud800\udf39\ud800\udf43\ud800\udf3a",
 406+ "grc" : "\u1f08\u03c1\u03c7\u03b1\u03af\u03b1 \u1f11\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u1f74",
 407+ "gsw" : "Alemannisch",
 408+ "gu" : "\u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0",
 409+ "gv" : "Gaelg",
 410+ "ha" : "\u0647\u064e\u0648\u064f\u0633\u064e",
 411+ "hak" : "Hak-k\u00e2-fa",
 412+ "haw" : "Hawai`i",
 413+ "he" : "\u05e2\u05d1\u05e8\u05d9\u05ea",
 414+ "hi" : "\u0939\u093f\u0928\u094d\u0926\u0940",
 415+ "hif" : "Fiji Hindi",
 416+ "hif-deva" : "\u092b\u093c\u0940\u091c\u0940 \u0939\u093f\u0928\u094d\u0926\u0940",
 417+ "hif-latn" : "Fiji Hindi",
 418+ "hil" : "Ilonggo",
 419+ "ho" : "Hiri Motu",
 420+ "hr" : "Hrvatski",
 421+ "hsb" : "Hornjoserbsce",
 422+ "ht" : "Krey\u00f2l ayisyen",
 423+ "hu" : "Magyar",
 424+ "hy" : "\u0540\u0561\u0575\u0565\u0580\u0565\u0576",
 425+ "hz" : "Otsiherero",
 426+ "ia" : "Interlingua",
 427+ "id" : "Bahasa Indonesia",
 428+ "ie" : "Interlingue",
 429+ "ig" : "Igbo",
 430+ "ii" : "\ua187\ua259",
 431+ "ik" : "I\u00f1upiak",
 432+ "ike-cans" : "\u1403\u14c4\u1483\u144e\u1450\u1466",
 433+ "ike-latn" : "inuktitut",
 434+ "ilo" : "Ilokano",
 435+ "inh" : "\u0413\u0406\u0430\u043b\u0433\u0406\u0430\u0439 \u011eal\u011faj",
 436+ "io" : "Ido",
 437+ "is" : "\u00cdslenska",
 438+ "it" : "Italiano",
 439+ "iu" : "\u1403\u14c4\u1483\u144e\u1450\u1466\/inuktitut",
 440+ "ja" : "\u65e5\u672c\u8a9e",
 441+ "jbo" : "Lojban",
 442+ "jut" : "Jysk",
 443+ "jv" : "Basa Jawa",
 444+ "ka" : "\u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8",
 445+ "kaa" : "Qaraqalpaqsha",
 446+ "kab" : "Taqbaylit",
 447+ "kg" : "Kongo",
 448+ "ki" : "G\u0129k\u0169y\u0169",
 449+ "kiu" : "Kurmanc\u00ee",
 450+ "kj" : "Kwanyama",
 451+ "kk" : "\u049a\u0430\u0437\u0430\u049b\u0448\u0430",
 452+ "kk-arab" : "\u202b\u0642\u0627\u0632\u0627\u0642\u0634\u0627 (\u062a\u0674\u0648\u062a\u06d5)\u202c",
 453+ "kk-cyrl" : "\u202a\u049a\u0430\u0437\u0430\u049b\u0448\u0430 (\u043a\u0438\u0440\u0438\u043b)\u202c",
 454+ "kk-latn" : "\u202aQazaq\u015fa (lat\u0131n)\u202c",
 455+ "kk-cn" : "\u202b\u0642\u0627\u0632\u0627\u0642\u0634\u0627 (\u062c\u06c7\u0646\u06af\u0648)\u202c",
 456+ "kk-kz" : "\u202a\u049a\u0430\u0437\u0430\u049b\u0448\u0430 (\u049a\u0430\u0437\u0430\u049b\u0441\u0442\u0430\u043d)\u202c",
 457+ "kk-tr" : "\u202aQazaq\u015fa (T\u00fcrk\u00efya)\u202c",
 458+ "kl" : "Kalaallisut",
 459+ "km" : "\u1797\u17b6\u179f\u17b6\u1781\u17d2\u1798\u17c2\u179a",
 460+ "kn" : "\u0c95\u0ca8\u0ccd\u0ca8\u0ca1",
 461+ "ko" : "\ud55c\uad6d\uc5b4",
 462+ "ko-kp" : "\ud55c\uad6d\uc5b4 (\uc870\uc120)",
 463+ "kr" : "Kanuri",
 464+ "kri" : "Krio",
 465+ "krj" : "Kinaray-a",
 466+ "ks" : "\u0915\u0936\u094d\u092e\u0940\u0930\u0940 - (\u0643\u0634\u0645\u064a\u0631\u064a)",
 467+ "ksh" : "Ripoarisch",
 468+ "ku" : "Kurd\u00ee \/ \u0643\u0648\u0631\u062f\u06cc",
 469+ "ku-latn" : "\u202aKurd\u00ee (lat\u00een\u00ee)\u202c",
 470+ "ku-arab" : "\u202b\u0643\u0648\u0631\u062f\u064a (\u0639\u06d5\u0631\u06d5\u0628\u06cc)\u202c",
 471+ "kv" : "\u041a\u043e\u043c\u0438",
 472+ "kw" : "Kernowek",
 473+ "ky" : "\u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430",
 474+ "la" : "Latina",
 475+ "lad" : "Ladino",
 476+ "lb" : "L\u00ebtzebuergesch",
 477+ "lbe" : "\u041b\u0430\u043a\u043a\u0443",
 478+ "lez" : "\u041b\u0435\u0437\u0433\u0438",
 479+ "lfn" : "Lingua Franca Nova",
 480+ "lg" : "Luganda",
 481+ "li" : "Limburgs",
 482+ "lij" : "L\u00edguru",
 483+ "lmo" : "Lumbaart",
 484+ "ln" : "Ling\u00e1la",
 485+ "lo" : "\u0ea5\u0eb2\u0ea7",
 486+ "loz" : "Silozi",
 487+ "lt" : "Lietuvi\u0173",
 488+ "lv" : "Latvie\u0161u",
 489+ "lzh" : "\u6587\u8a00",
 490+ "mai" : "\u092e\u0948\u0925\u093f\u0932\u0940",
 491+ "map-bms" : "Basa Banyumasan",
 492+ "mdf" : "\u041c\u043e\u043a\u0448\u0435\u043d\u044c",
 493+ "mg" : "Malagasy",
 494+ "mh" : "Ebon",
 495+ "mhr" : "\u041e\u043b\u044b\u043a \u041c\u0430\u0440\u0438\u0439",
 496+ "mi" : "M\u0101ori",
 497+ "mk" : "\u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438",
 498+ "ml" : "\u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02",
 499+ "mn" : "\u041c\u043e\u043d\u0433\u043e\u043b",
 500+ "mo" : "\u041c\u043e\u043b\u0434\u043e\u0432\u0435\u043d\u044f\u0441\u043a\u044d",
 501+ "mr" : "\u092e\u0930\u093e\u0920\u0940",
 502+ "ms" : "Bahasa Melayu",
 503+ "mt" : "Malti",
 504+ "mus" : "Mvskoke",
 505+ "mwl" : "Mirand\u00e9s",
 506+ "my" : "\u1019\u103c\u1014\u103a\u1019\u102c\u1018\u102c\u101e\u102c",
 507+ "myv" : "\u042d\u0440\u0437\u044f\u043d\u044c",
 508+ "mzn" : "\u0645\u064e\u0632\u0650\u0631\u0648\u0646\u064a",
 509+ "na" : "Dorerin Naoero",
 510+ "nah" : "N\u0101huatl",
 511+ "nan" : "B\u00e2n-l\u00e2m-g\u00fa",
 512+ "nap" : "Nnapulitano",
 513+ "nb" : "\u202aNorsk (bokm\u00e5l)\u202c",
 514+ "nds" : "Plattd\u00fc\u00fctsch",
 515+ "nds-nl" : "Nedersaksisch",
 516+ "ne" : "\u0928\u0947\u092a\u093e\u0932\u0940",
 517+ "new" : "\u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e",
 518+ "ng" : "Oshiwambo",
 519+ "niu" : "Niu\u0113",
 520+ "nl" : "Nederlands",
 521+ "nn" : "\u202aNorsk (nynorsk)\u202c",
 522+ "no" : "\u202aNorsk (bokm\u00e5l)\u202c",
 523+ "nov" : "Novial",
 524+ "nrm" : "Nouormand",
 525+ "nso" : "Sesotho sa Leboa",
 526+ "nv" : "Din\u00e9 bizaad",
 527+ "ny" : "Chi-Chewa",
 528+ "oc" : "Occitan",
 529+ "om" : "Oromoo",
 530+ "or" : "\u0b13\u0b21\u0b3c\u0b3f\u0b06",
 531+ "os" : "\u0418\u0440\u043e\u043d\u0430\u0443",
 532+ "pa" : "\u0a2a\u0a70\u0a1c\u0a3e\u0a2c\u0a40",
 533+ "pag" : "Pangasinan",
 534+ "pam" : "Kapampangan",
 535+ "pap" : "Papiamentu",
 536+ "pcd" : "Picard",
 537+ "pdc" : "Deitsch",
 538+ "pdt" : "Plautdietsch",
 539+ "pfl" : "Pf\u00e4lzisch",
 540+ "pi" : "\u092a\u093e\u093f\u0934",
 541+ "pih" : "Norfuk \/ Pitkern",
 542+ "pl" : "Polski",
 543+ "pms" : "Piemont\u00e8is",
 544+ "pnb" : "\u067e\u0646\u062c\u0627\u0628\u06cc",
 545+ "pnt" : "\u03a0\u03bf\u03bd\u03c4\u03b9\u03b1\u03ba\u03ac",
 546+ "ps" : "\u067e\u069a\u062a\u0648",
 547+ "pt" : "Portugu\u00eas",
 548+ "pt-br" : "Portugu\u00eas do Brasil",
 549+ "qu" : "Runa Simi",
 550+ "rif" : "Tarifit",
 551+ "rm" : "Rumantsch",
 552+ "rmy" : "Romani",
 553+ "rn" : "Kirundi",
 554+ "ro" : "Rom\u00e2n\u0103",
 555+ "roa-rup" : "Arm\u00e3neashce",
 556+ "roa-tara" : "Tarand\u00edne",
 557+ "ru" : "\u0420\u0443\u0441\u0441\u043a\u0438\u0439",
 558+ "ruq" : "Vl\u0103he\u015fte",
 559+ "ruq-cyrl" : "\u0412\u043b\u0430\u0445\u0435\u0441\u0442\u0435",
 560+ "ruq-latn" : "Vl\u0103he\u015fte",
 561+ "rw" : "Kinyarwanda",
 562+ "sa" : "\u0938\u0902\u0938\u094d\u0915\u0943\u0924",
 563+ "sah" : "\u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430",
 564+ "sc" : "Sardu",
 565+ "scn" : "Sicilianu",
 566+ "sco" : "Scots",
 567+ "sd" : "\u0633\u0646\u068c\u064a",
 568+ "sdc" : "Sassaresu",
 569+ "se" : "S\u00e1megiella",
 570+ "sei" : "Cmique Itom",
 571+ "sg" : "S\u00e4ng\u00f6",
 572+ "sh" : "Srpskohrvatski \/ \u0421\u0440\u043f\u0441\u043a\u043e\u0445\u0440\u0432\u0430\u0442\u0441\u043a\u0438",
 573+ "shi" : "Ta\u0161l\u1e25iyt",
 574+ "si" : "\u0dc3\u0dd2\u0d82\u0dc4\u0dbd",
 575+ "simple" : "Simple English",
 576+ "sk" : "Sloven\u010dina",
 577+ "sl" : "Sloven\u0161\u010dina",
 578+ "sli" : "Schl\u00e4sch",
 579+ "sm" : "Gagana Samoa",
 580+ "sma" : "\u00c5arjelsaemien",
 581+ "sn" : "chiShona",
 582+ "so" : "Soomaaliga",
 583+ "sq" : "Shqip",
 584+ "sr" : "\u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski",
 585+ "sr-ec" : "\u0421\u0440\u043f\u0441\u043a\u0438 (\u045b\u0438\u0440\u0438\u043b\u0438\u0446\u0430)",
 586+ "sr-el" : "Srpski (latinica)",
 587+ "srn" : "Sranantongo",
 588+ "ss" : "SiSwati",
 589+ "st" : "Sesotho",
 590+ "stq" : "Seeltersk",
 591+ "su" : "Basa Sunda",
 592+ "sv" : "Svenska",
 593+ "sw" : "Kiswahili",
 594+ "szl" : "\u015al\u016fnski",
 595+ "ta" : "\u0ba4\u0bae\u0bbf\u0bb4\u0bcd",
 596+ "tcy" : "\u0ca4\u0cc1\u0cb3\u0cc1",
 597+ "te" : "\u0c24\u0c46\u0c32\u0c41\u0c17\u0c41",
 598+ "tet" : "Tetun",
 599+ "tg" : "\u0422\u043e\u04b7\u0438\u043a\u04e3",
 600+ "tg-cyrl" : "\u0422\u043e\u04b7\u0438\u043a\u04e3",
 601+ "tg-latn" : "tojik\u012b",
 602+ "th" : "\u0e44\u0e17\u0e22",
 603+ "ti" : "\u1275\u130d\u122d\u129b",
 604+ "tk" : "T\u00fcrkmen\u00e7e",
 605+ "tl" : "Tagalog",
 606+ "tn" : "Setswana",
 607+ "to" : "lea faka-Tonga",
 608+ "tokipona" : "Toki Pona",
 609+ "tp" : "Toki Pona (deprecated:tokipona)",
 610+ "tpi" : "Tok Pisin",
 611+ "tr" : "T\u00fcrk\u00e7e",
 612+ "ts" : "Xitsonga",
 613+ "tt" : "\u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a",
 614+ "tt-cyrl" : "\u0422\u0430\u0442\u0430\u0440\u0447\u0430",
 615+ "tt-latn" : "Tatar\u00e7a",
 616+ "tum" : "chiTumbuka",
 617+ "tw" : "Twi",
 618+ "ty" : "Reo M\u0101`ohi",
 619+ "tyv" : "\u0422\u044b\u0432\u0430 \u0434\u044b\u043b",
 620+ "udm" : "\u0423\u0434\u043c\u0443\u0440\u0442",
 621+ "ug" : "Uyghurche\u200e \/ \u0626\u06c7\u064a\u063a\u06c7\u0631\u0686\u06d5",
 622+ "ug-arab" : "\u0626\u06c7\u064a\u063a\u06c7\u0631\u0686\u06d5",
 623+ "ug-latn" : "Uyghurche\u200e",
 624+ "uk" : "\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430",
 625+ "ur" : "\u0627\u0631\u062f\u0648",
 626+ "uz" : "O'zbek",
 627+ "ve" : "Tshivenda",
 628+ "vec" : "V\u00e8neto",
 629+ "vep" : "Vepsan kel'",
 630+ "vi" : "Ti\u1ebfng Vi\u1ec7t",
 631+ "vls" : "West-Vlams",
 632+ "vo" : "Volap\u00fck",
 633+ "vro" : "V\u00f5ro",
 634+ "wa" : "Walon",
 635+ "war" : "Winaray",
 636+ "wo" : "Wolof",
 637+ "wuu" : "\u5434\u8bed",
 638+ "xal" : "\u0425\u0430\u043b\u044c\u043c\u0433",
 639+ "xh" : "isiXhosa",
 640+ "xmf" : "\u10db\u10d0\u10e0\u10d2\u10d0\u10da\u10e3\u10e0\u10d8",
 641+ "yi" : "\u05d9\u05d9\u05b4\u05d3\u05d9\u05e9",
 642+ "yo" : "Yor\u00f9b\u00e1",
 643+ "yue" : "\u7cb5\u8a9e",
 644+ "za" : "Vahcuengh",
 645+ "zea" : "Ze\u00eauws",
 646+ "zh" : "\u4e2d\u6587",
 647+ "zh-classical" : "\u6587\u8a00",
 648+ "zh-cn" : "\u202a\u4e2d\u6587(\u4e2d\u56fd\u5927\u9646)\u202c",
 649+ "zh-hans" : "\u202a\u4e2d\u6587(\u7b80\u4f53)\u202c",
 650+ "zh-hant" : "\u202a\u4e2d\u6587(\u7e41\u9ad4)\u202c",
 651+ "zh-hk" : "\u202a\u4e2d\u6587(\u9999\u6e2f)\u202c",
 652+ "zh-min-nan" : "B\u00e2n-l\u00e2m-g\u00fa",
 653+ "zh-mo" : "\u202a\u4e2d\u6587(\u6fb3\u9580)\u202c",
 654+ "zh-my" : "\u202a\u4e2d\u6587(\u9a6c\u6765\u897f\u4e9a)\u202c",
 655+ "zh-sg" : "\u202a\u4e2d\u6587(\u65b0\u52a0\u5761)\u202c",
 656+ "zh-tw" : "\u202a\u4e2d\u6587(\u53f0\u7063)\u202c",
 657+ "zh-yue" : "\u7cb5\u8a9e",
 658+ "zu" : "isiZulu"
 659+ };
 660+
 661+ // Language classes ( has a file in /languages/classes/Language{code}.js )
 662+ // ( for languages that override default transforms )
 663+ mw.Language.transformClass = ['am', 'ar', 'bat_smg', 'be_tarak', 'be', 'bh',
 664+ 'bs', 'cs', 'cu', 'cy', 'dsb', 'fr', 'ga', 'gd', 'gv', 'he', 'hi',
 665+ 'hr', 'hsb', 'hy', 'ksh', 'ln', 'lt', 'lv', 'mg', 'mk', 'mo', 'mt',
 666+ 'nso', 'pl', 'pt_br', 'ro', 'ru', 'se', 'sh', 'sk', 'sl', 'sma',
 667+ 'sr_ec', 'sr_el', 'sr', 'ti', 'tl', 'uk', 'wa'
 668+ ];
 669+
 670+ // Language fallbacks listed from language -> fallback language
 671+ mw.Language.fallbackTransformMap = {
 672+ 'mwl' : 'pt',
 673+ 'ace' : 'id',
 674+ 'hsb' : 'de',
 675+ 'frr' : 'de',
 676+ 'pms' : 'it',
 677+ 'dsb' : 'de',
 678+ 'gan' : 'gan-hant',
 679+ 'lzz' : 'tr',
 680+ 'ksh' : 'de',
 681+ 'kl' : 'da',
 682+ 'fur' : 'it',
 683+ 'zh-hk' : 'zh-hant',
 684+ 'kk' : 'kk-cyrl',
 685+ 'zh-my' : 'zh-sg',
 686+ 'nah' : 'es',
 687+ 'sr' : 'sr-ec',
 688+ 'ckb-latn' : 'ckb-arab',
 689+ 'mo' : 'ro',
 690+ 'ay' : 'es',
 691+ 'gl' : 'pt',
 692+ 'gag' : 'tr',
 693+ 'mzn' : 'fa',
 694+ 'ruq-cyrl' : 'mk',
 695+ 'kk-arab' : 'kk-cyrl',
 696+ 'pfl' : 'de',
 697+ 'zh-yue' : 'yue',
 698+ 'ug' : 'ug-latn',
 699+ 'ltg' : 'lv',
 700+ 'nds' : 'de',
 701+ 'sli' : 'de',
 702+ 'mhr' : 'ru',
 703+ 'sah' : 'ru',
 704+ 'ff' : 'fr',
 705+ 'ab' : 'ru',
 706+ 'ko-kp' : 'ko',
 707+ 'sg' : 'fr',
 708+ 'zh-tw' : 'zh-hant',
 709+ 'map-bms' : 'jv',
 710+ 'av' : 'ru',
 711+ 'nds-nl' : 'nl',
 712+ 'pt-br' : 'pt',
 713+ 'ce' : 'ru',
 714+ 'vep' : 'et',
 715+ 'wuu' : 'zh-hans',
 716+ 'pdt' : 'de',
 717+ 'krc' : 'ru',
 718+ 'gan-hant' : 'zh-hant',
 719+ 'bqi' : 'fa',
 720+ 'as' : 'bn',
 721+ 'bm' : 'fr',
 722+ 'gn' : 'es',
 723+ 'tt' : 'ru',
 724+ 'zh-hant' : 'zh-hans',
 725+ 'hif' : 'hif-latn',
 726+ 'zh' : 'zh-hans',
 727+ 'kaa' : 'kk-latn',
 728+ 'lij' : 'it',
 729+ 'vot' : 'fi',
 730+ 'ii' : 'zh-cn',
 731+ 'ku-arab' : 'ckb-arab',
 732+ 'xmf' : 'ka',
 733+ 'vmf' : 'de',
 734+ 'zh-min-nan' : 'nan',
 735+ 'bcc' : 'fa',
 736+ 'an' : 'es',
 737+ 'rgn' : 'it',
 738+ 'qu' : 'es',
 739+ 'nb' : 'no',
 740+ 'bar' : 'de',
 741+ 'lbe' : 'ru',
 742+ 'su' : 'id',
 743+ 'pcd' : 'fr',
 744+ 'glk' : 'fa',
 745+ 'lb' : 'de',
 746+ 'kk-kz' : 'kk-cyrl',
 747+ 'kk-tr' : 'kk-latn',
 748+ 'inh' : 'ru',
 749+ 'mai' : 'hi',
 750+ 'tp' : 'tokipona',
 751+ 'kk-latn' : 'kk-cyrl',
 752+ 'ba' : 'ru',
 753+ 'nap' : 'it',
 754+ 'ruq' : 'ruq-latn',
 755+ 'tt-cyrl' : 'ru',
 756+ 'lad' : 'es',
 757+ 'dk' : 'da',
 758+ 'de-ch' : 'de',
 759+ 'be-x-old' : 'be-tarask',
 760+ 'za' : 'zh-hans',
 761+ 'kk-cn' : 'kk-arab',
 762+ 'shi' : 'ar',
 763+ 'crh' : 'crh-latn',
 764+ 'yi' : 'he',
 765+ 'pdc' : 'de',
 766+ 'eml' : 'it',
 767+ 'uk' : 'ru',
 768+ 'kv' : 'ru',
 769+ 'koi' : 'ru',
 770+ 'cv' : 'ru',
 771+ 'zh-cn' : 'zh-hans',
 772+ 'de-at' : 'de',
 773+ 'jut' : 'da',
 774+ 'vec' : 'it',
 775+ 'zh-mo' : 'zh-hk',
 776+ 'fiu-vro' : 'vro',
 777+ 'frp' : 'fr',
 778+ 'mg' : 'fr',
 779+ 'ruq-latn' : 'ro',
 780+ 'sa' : 'hi',
 781+ 'lmo' : 'it',
 782+ 'kiu' : 'tr',
 783+ 'tcy' : 'kn',
 784+ 'srn' : 'nl',
 785+ 'jv' : 'id',
 786+ 'vls' : 'nl',
 787+ 'zea' : 'nl',
 788+ 'ty' : 'fr',
 789+ 'szl' : 'pl',
 790+ 'rmy' : 'ro',
 791+ 'wo' : 'fr',
 792+ 'vro' : 'et',
 793+ 'udm' : 'ru',
 794+ 'bpy' : 'bn',
 795+ 'mrj' : 'ru',
 796+ 'ckb' : 'ckb-arab',
 797+ 'xal' : 'ru',
 798+ 'de-formal' : 'de',
 799+ 'myv' : 'ru',
 800+ 'ku' : 'ku-latn',
 801+ 'crh-cyrl' : 'ru',
 802+ 'gsw' : 'de',
 803+ 'rue' : 'uk',
 804+ 'iu' : 'ike-cans',
 805+ 'stq' : 'de',
 806+ 'gan-hans' : 'zh-hans',
 807+ 'scn' : 'it',
 808+ 'arn' : 'es',
 809+ 'ht' : 'fr',
 810+ 'zh-sg' : 'zh-hans',
 811+ 'bat-smg' : 'lt',
 812+ 'aln' : 'sq',
 813+ 'tg' : 'tg-cyrl',
 814+ 'li' : 'nl',
 815+ 'simple' : 'en',
 816+ 'os' : 'ru',
 817+ 'ln' : 'fr',
 818+ 'als' : 'gsw',
 819+ 'zh-classical' : 'lzh',
 820+ 'arz' : 'ar',
 821+ 'wa' : 'fr'
 822+ };
 823+
 824+ /**
 825+ * Plural form transformations, needed for some languages.
 826+ * For example, there are 3 form of plural in Russian and Polish,
 827+ * depending on "count mod 10". See [[w:Plural]]
 828+ * For English it is pretty simple.
 829+ *
 830+ * Invoked by putting {{plural:count|wordform1|wordform2}}
 831+ * or {{plural:count|wordform1|wordform2|wordform3}}
 832+ *
 833+ * Example: {{plural:{{NUMBEROFARTICLES}}|article|articles}}
 834+ *
 835+ * @param count Integer: non-localized number
 836+ * @param forms Array: different plural forms
 837+ * @return string Correct form of plural for count in this language
 838+ */
 839+
 840+ /**
 841+ * Base gender transform function
 842+ */
 843+ mw.Language.gender = function( gender, forms ) {
 844+ if ( ! forms.length ) {
 845+ return '';
 846+ }
 847+ forms = mw.Language.preConvertPlural( forms, 2 );
 848+ if ( gender === 'male' ) return forms[0];
 849+ if ( gender === 'female' ) return forms[1];
 850+ return ( forms[2] ) ? forms[2] : forms[0];
 851+ };
 852+
 853+ /**
 854+ * Process the PLURAL template substitution
 855+ * @param {Object} template Template object
 856+ *
 857+ * {{Template:argument|params}}
 858+ *
 859+ * Template object should include:
 860+ * [arg] The argument sent to the template
 861+ * [params] The template parameters
 862+ */
 863+ mw.Language.procPLURAL = function( templateObject ) {
 864+ // Setup shortcuts
 865+ // ( gRuleSet is loaded from script-loader to contains local ruleset )
 866+ var rs = gRuleSet[ 'PLURAL' ];
 867+
 868+ if( templateObject.arg && templateObject.param && mw.Language.convertPlural) {
 869+ // Check if we have forms to replace
 870+ if ( templateObject.param.length == 0 ) {
 871+ return '';
 872+ }
 873+ // Restore the count into a Number ( if it got converted earlier )
 874+ var count = mw.Language.convertNumber( templateObject.arg, true );
 875+
 876+ // Do convertPlural call
 877+ return mw.Language.convertPlural( parseInt( count ), templateObject.param );
 878+
 879+ }
 880+ // Could not process plural return first form or nothing
 881+ if( templateObject.param[0] ) {
 882+ return templateObject.param[0];
 883+ }
 884+ return '';
 885+ };
 886+
 887+ // NOTE:: add gender support here
 888+ mw.Language.procGENDER = function( templateObject ){
 889+ return 'gender-not-supported-in-js-yet';
 890+ }
 891+ /*
 892+ * Base convertPlural function:
 893+ */
 894+ mw.Language.convertPlural = function( count, forms ){
 895+ if ( !forms || forms.length == 0 ) {
 896+ return '';
 897+ }
 898+ return ( parseInt( count ) == 1 ) ? forms[0] : forms[1];
 899+ };
 900+ /**
 901+ * Checks that convertPlural was given an array and pads it to requested
 902+ * amount of forms by copying the last one.
 903+ *
 904+ * @param {Array} forms Forms given to convertPlural
 905+ * @param {Integer} count How many forms should there be at least
 906+ * @return {Array} Padded array of forms or an exception if not an array
 907+ */
 908+ mw.Language.preConvertPlural = function( forms, count ) {
 909+ while ( forms.length < count ) {
 910+ forms.push( forms[ forms.length-1 ] );
 911+ }
 912+ return forms;
 913+ };
 914+
 915+ /**
 916+ * Init the digitTransformTable ( populated by language classes where applicable )
 917+ */
 918+ mw.Language.digitTransformTable = null;
 919+
 920+ /**
 921+ * Convert a number using the digitTransformTable
 922+ * @param Number number to be converted
 923+ * @param Bollean typeInt if we should return a number of type int
 924+ */
 925+ mw.Language.convertNumber = function( number, typeInt ) {
 926+ if( !mw.Language.digitTransformTable )
 927+ return number;
 928+
 929+ // Set the target Transform table:
 930+ var transformTable = mw.Language.digitTransformTable;
 931+
 932+ // Check if the "restore" to latin number flag is set:
 933+ if( typeInt ) {
 934+ if( parseInt( number ) == number )
 935+ return number;
 936+ var tmp = [];
 937+ for( var i in transformTable ) {
 938+ tmp[ transformTable[ i ] ] = i;
 939+ }
 940+ transformTable = tmp;
 941+ }
 942+
 943+ var numberString = '' + number;
 944+ var convertedNumber = '';
 945+ for( var i =0; i < numberString.length; i++) {
 946+ if( transformTable[ numberString[i] ] ) {
 947+ convertedNumber += transformTable[ numberString[i] ];
 948+ }else{
 949+ convertedNumber += numberString[i];
 950+ }
 951+ }
 952+ return ( typeInt )? parseInt( convertedNumber) : convertedNumber;
 953+ }
 954+
 955+ /**
 956+ * Checks if a language key is valid ( is part of languageCodeList )
 957+ * @param {String} langKey Language key to be checked
 958+ * @return true if valid language, false if not
 959+ */
 960+ mw.isValidLang = function( langKey ) {
 961+ return ( mw.Language.names[ langKey ] )? true : false;
 962+ }
 963+
 964+ /**
 965+ * Get a language transform key
 966+ * returns default "en" fallback if none found
 967+ * @param String langKey The language key to be checked
 968+ */
 969+ mw.getLangTransformKey = function( langKey ) {
 970+ if( mw.Language.fallbackTransformMap[ langKey ] ) {
 971+ langKey = mw.Language.fallbackTransformMap[ langKey ];
 972+ }
 973+ // Make sure the langKey has a transformClass:
 974+ for( var i = 0; i < mw.Language.transformClass.length ; i++ ) {
 975+ if( langKey == mw.Language.transformClass[i] ){
 976+ return langKey
 977+ }
 978+ }
 979+ // By default return the base 'en' class
 980+ return 'en';
 981+ }
 982+
 983+ /**
 984+ * getRemoteMsg loads remote msg strings
 985+ *
 986+ * @param {Mixed} msgSet the set of msg to load remotely
 987+ * @param function callback the callback to issue once string is ready
 988+ */
 989+ mw.getRemoteMsg = function( msgSet, callback ) {
 990+ var ammessages = '';
 991+ if ( typeof msgSet == 'object' ) {
 992+ for ( var i in msgSet ) {
 993+ if( !messageCache[ i ] ) {
 994+ ammessages += msgSet[i] + '|';
 995+ }
 996+ }
 997+ } else if ( typeof msgSet == 'string' ) {
 998+ if( !messageCache[ i ] ) {
 999+ ammessages += msgSet;
 1000+ }
 1001+ }
 1002+ if ( ammessages == '' ) {
 1003+ mw.log( 'no remote msgs to get' );
 1004+ callback();
 1005+ return false;
 1006+ }
 1007+ var request = {
 1008+ 'meta': 'allmessages',
 1009+ 'ammessages': ammessages
 1010+ }
 1011+ mw.getJSON( request, function( data ) {
 1012+ if ( data.query.allmessages ) {
 1013+ var msgs = data.query.allmessages;
 1014+ for ( var i in msgs ) {
 1015+ var ld = { };
 1016+ ld[ msgs[i]['name'] ] = msgs[i]['*'];
 1017+ mw.addMessages( ld );
 1018+ }
 1019+ }
 1020+ callback();
 1021+ } );
 1022+ }
 1023+
 1024+ /**
 1025+ * Format a size in bytes for output, using an appropriate
 1026+ * unit (B, KB, MB or GB) according to the magnitude in question
 1027+ *
 1028+ * @param size Size to format
 1029+ * @return string Plain text (not HTML)
 1030+ */
 1031+ mw.Language.formatSize = function ( size ) {
 1032+ // For small sizes no decimal places are necessary
 1033+ var round = 0;
 1034+ var msg = '';
 1035+ if ( size > 1024 ) {
 1036+ size = size / 1024;
 1037+ if ( size > 1024 ) {
 1038+ size = size / 1024;
 1039+ // For MB and bigger two decimal places are smarter
 1040+ round = 2;
 1041+ if ( size > 1024 ) {
 1042+ size = size / 1024;
 1043+ msg = 'mwe-size-gigabytes';
 1044+ } else {
 1045+ msg = 'mwe-size-megabytes';
 1046+ }
 1047+ } else {
 1048+ msg = 'mwe-size-kilobytes';
 1049+ }
 1050+ } else {
 1051+ msg = 'mwe-size-bytes';
 1052+ }
 1053+ // JavaScript does not let you choose the precision when rounding
 1054+ var p = Math.pow( 10, round );
 1055+ size = Math.round( size * p ) / p;
 1056+ return gM( msg , size );
 1057+ };
 1058+
 1059+ /**
 1060+ * Format a number
 1061+ * @param {Number} num Number to be formated
 1062+ * NOTE: add il8n support to lanuages/class/Language{langCode}.js
 1063+ */
 1064+ mw.Language.formatNumber = function( num ) {
 1065+ /*
 1066+ * addSeparatorsNF
 1067+ * @param Str: The number to be formatted, as a string or number.
 1068+ * @param outD: The decimal character for the output, such as ',' for the number 100,2
 1069+ * @param sep: The separator character for the output, such as ',' for the number 1,000.2
 1070+ */
 1071+ function addSeparatorsNF( nStr, outD, sep ) {
 1072+ nStr += '';
 1073+ var dpos = nStr.indexOf( '.' );
 1074+ var nStrEnd = '';
 1075+ if ( dpos != -1 ) {
 1076+ nStrEnd = outD + nStr.substring( dpos + 1, nStr.length );
 1077+ nStr = nStr.substring( 0, dpos );
 1078+ }
 1079+ var rgx = /(\d+)(\d{3})/;
 1080+ while ( rgx.test( nStr ) ) {
 1081+ nStr = nStr.replace( rgx, '$1' + sep + '$2' );
 1082+ }
 1083+ return nStr + nStrEnd;
 1084+ }
 1085+ // @@todo read language code and give periods or comas:
 1086+ return addSeparatorsNF( num, '.', ',' );
 1087+ }
 1088+
 1089+}) ( window.mw );
 1090+
 1091+
 1092+// Load in js2 stopgap global msgs into proper location:
 1093+if ( typeof gMsg != 'undefined' ) {
 1094+ mw.addMessages( gMsg )
 1095+}
 1096+
 1097+// Set global gM shortcut:
 1098+window[ 'gM' ] = mw.getMsg;
 1099+
 1100+
 1101+/**
 1102+* Add the core mvEmbed Messages ( will be localized by script server )
 1103+*/
 1104+mw.addMessages( {
 1105+ "mwe-loading_txt" : "Loading ...",
 1106+ "mwe-size-gigabytes" : "$1 GB",
 1107+ "mwe-size-megabytes" : "$1 MB",
 1108+ "mwe-size-kilobytes" : "$1 K",
 1109+ "mwe-size-bytes" : "$1 B",
 1110+ "mwe-error_load_lib" : "Error: JavaScript $1 was not retrievable or does not define $2",
 1111+ "mwe-apiproxy-setup" : "Setting up API proxy",
 1112+ "mwe-load-drag-item" : "Loading dragged item",
 1113+ "mwe-ok" : "OK",
 1114+ "mwe-cancel" : "Cancel",
 1115+ "mwe-enable-gadget" : "Enable multimedia beta ( mwEmbed ) for all pages",
 1116+ "mwe-enable-gadget-done" : "multimedia beta gadget has been enabled",
 1117+ "mwe-must-login-gadget" : "To enable gadget you must <a target=\"_new\" href=\"$1\">login</a>",
 1118+ "mwe-test-plural" : "I ran {{PLURAL:$1|$1 test|$1 tests}}"
 1119+} );
\ No newline at end of file
Property changes on: branches/MwEmbedStandAlone/components/mw.Language.js
___________________________________________________________________
Name: svn:mergeinfo
11120 + /branches/REL1_15/phase3/js2/mwEmbed/php/languages/mw.Language.js:51646
/branches/sqlite/js2/mwEmbed/php/languages/mw.Language.js:58211-58321
Index: branches/MwEmbedStandAlone/components/mw.Api.js
@@ -0,0 +1,370 @@
 2+/**
 3+* API Helper functions
 4+*/
 5+
 6+( function( mw ) {
 7+ // xxx note we should namespace the following helper functions into Api class.
 8+ mw.Api = {};
 9+
 10+ /**
 11+ *
 12+ * Helper function to get revision text for a given title
 13+ *
 14+ * Assumes "follow redirects"
 15+ *
 16+ * $j.getTitleText( [apiUrl], title, callback )
 17+ *
 18+ * @param {String} url or title key
 19+ * @parma {Mixed} title or callback function
 20+ * @param {Function} callback Function or NULL
 21+ *
 22+ * @return callback is called with:
 23+ * {Boolean} false if no page found
 24+ * {String} text of wiki page
 25+ */
 26+ mw.getTitleText = function( apiUrl, title, callback ) {
 27+ // Check if optional apiURL was not included
 28+ if( !callback ) {
 29+ title = apiUrl;
 30+ callback = title;
 31+ apiUrl = mw.getLocalApiUrl();
 32+ }
 33+ var request = {
 34+ // Normalize the File NS (ie sometimes its present in apiTitleKey other times not
 35+ 'titles' : title,
 36+ 'prop' : 'revisions',
 37+ 'rvprop' : 'content'
 38+ };
 39+
 40+ mw.getJSON( apiUrl , request, function( data ) {
 41+ if( !data || !data.query || !data.query.pages ) {
 42+ callback( false );
 43+ }
 44+ var pages = data.query.pages;
 45+ for(var i in pages) {
 46+ page = pages[ i ];
 47+ if( page[ 'revisions' ] && page[ 'revisions' ][0]['*'] ) {
 48+ callback( page[ 'revisions' ][0]['*'] );
 49+ }
 50+ }
 51+ } );
 52+ }
 53+
 54+ /**
 55+ * Issues the wikitext parse call
 56+ *
 57+ * @param {String} wikitext Wiki Text to be parsed by mediaWiki api call
 58+ * @param {String} title Context title of the content to be parsed
 59+ * @param {Function} callback Function called with api parser output
 60+ */
 61+ mw.parseWikiText = function( wikitext, title, callback ) {
 62+ mw.log("mw.parseWikiText text length: " + wikitext.length + ' title context: ' + title );
 63+ mw.load( 'JSON', function(){
 64+ $j.ajax({
 65+ type: 'POST',
 66+ url: mw.getLocalApiUrl(),
 67+ // Give the wiki 60 seconds to parse the wiki-text
 68+ timeout : 60000,
 69+ data: {
 70+ 'action': 'parse',
 71+ 'format': 'json',
 72+ 'title' : title,
 73+ 'text': wikitext
 74+ },
 75+ dataType: 'text',
 76+ success: function( data ) {
 77+ var jsonData = JSON.parse( data ) ;
 78+ // xxx should handle other failures
 79+ callback( jsonData.parse.text['*'] );
 80+ },
 81+ error: function( XMLHttpRequest, textStatus, errorThrown ){
 82+ // xxx should better handle failures
 83+ mw.log( "Error: mw.parseWikiText:" + textStatus );
 84+ callback( "Error: failed to parse wikitext " );
 85+ }
 86+ });
 87+ });
 88+ }
 89+
 90+ /**
 91+ * mediaWiki JSON a wrapper for jQuery getJSON:
 92+ * ( could also be named mw.apiRequest )
 93+ *
 94+ * The mwEmbed version lets you skip the url part
 95+ * mw.getJSON( [url], data, callback, [timeoutCallback] );
 96+ *
 97+ * Lets you assume:
 98+ * url is optional
 99+ * ( If the first argument is not a string we assume a local mediaWiki api request )
 100+ * callback parameter is not needed for the request data
 101+ * url param 'action'=>'query' is assumed ( if not set to something else in the "data" param
 102+ * format is set to "json" automatically
 103+ * automatically issues request over "POST" if the request api post type
 104+ * automatically will setup apiProxy where request is cross domain
 105+ *
 106+ * @param {Mixed} url or data request
 107+ * @param {Mixed} data or callback
 108+ * @param {Function} callbcak function called on success
 109+ * @param {Function} callbackTimeout - optional function called on timeout
 110+ * Setting timeout callback also avoids default timed-out dialog for proxy requests
 111+ */
 112+ mw.getJSON = function() {
 113+ // Process the arguments:
 114+
 115+ // Set up the url
 116+ var url = false;
 117+ url = ( typeof arguments[0] == 'string' ) ? arguments[0] : mw.getLocalApiUrl();
 118+
 119+ // Set up the data:
 120+ var data = null;
 121+ data = ( typeof arguments[0] == 'object' ) ? arguments[0] : null;
 122+ if( !data && typeof arguments[1] == 'object' ) {
 123+ data = arguments[1];
 124+ }
 125+
 126+ // Setup the callback
 127+ var callback = false;
 128+ callback = ( typeof arguments[1] == 'function') ? arguments[1] : false;
 129+ var cbinx = 1;
 130+ if( ! callback && ( typeof arguments[2] == 'function') ) {
 131+ callback = arguments[2];
 132+ cbinx = 2;
 133+ }
 134+
 135+ // Setup the timeoutCallback ( function after callback index )
 136+ var timeoutCallback = false;
 137+ timeoutCallback = ( typeof arguments[ cbinx + 1 ] == 'function' ) ? arguments[ cbinx + 1 ] : false;
 138+
 139+ // Make sure we got a url:
 140+ if( !url ) {
 141+ mw.log( 'Error: no api url for api request' );
 142+ return false;
 143+ }
 144+
 145+ // Add default action if unset:
 146+ if( !data['action'] ) {
 147+ data['action'] = 'query';
 148+ }
 149+
 150+ // Add default format if not set:
 151+ if( !data['format'] ) {
 152+ data['format'] = 'json';
 153+ }
 154+
 155+ // Setup callback wrapper for timeout
 156+ var requestTimeOutFlag = false;
 157+ var ranCallback = false;
 158+
 159+ /**
 160+ * local callback function to control timeout
 161+ * @param {Object} data Result data
 162+ */
 163+ var myCallback = function( data ){
 164+ if( ! requestTimeOutFlag ){
 165+ ranCallback = true;
 166+ callback( data );
 167+ }
 168+ }
 169+ // Set the local timeout call based on defaultRequestTimeout
 170+ setTimeout( function( ) {
 171+ if( ! ranCallback ) {
 172+ requestTimeOutFlag = true;
 173+ mw.log( "Error:: request timed out: " + url );
 174+ if( timeoutCallback ){
 175+ timeoutCallback();
 176+ }
 177+ }
 178+ }, mw.getConfig( 'defaultRequestTimeout' ) * 1000 );
 179+
 180+ mw.log("run getJSON: " + mw.replaceUrlParams( url, data ) );
 181+
 182+ // Check if the request requires a "post"
 183+ if( mw.checkRequestPost( data ) ) {
 184+
 185+ // Check if we need to setup a proxy
 186+ if( ! mw.isLocalDomain( url ) ) {
 187+
 188+ //Set local scope ranCallback to true
 189+ // ( ApiProxy handles timeouts internally )
 190+ ranCallback = true;
 191+
 192+ // Load the proxy and issue the request
 193+ mw.load( 'ApiProxy', function( ) {
 194+ mw.ApiProxy.doRequest( url, data, callback, timeoutCallback);
 195+ } );
 196+
 197+ } else {
 198+
 199+ // Do the request an ajax post
 200+ $j.post( url, data, myCallback, 'json');
 201+ }
 202+ return ;
 203+ }
 204+
 205+ // If cross domain setup a callback:
 206+ if( ! mw.isLocalDomain( url ) ) {
 207+ if( url.indexOf( 'callback=' ) == -1 || data[ 'callback' ] == -1 ) {
 208+ // jQuery specific jsonp format: ( second ? is replaced with the callback )
 209+ url += ( url.indexOf('?') == -1 ) ? '?callback=?' : '&callback=?';
 210+ }
 211+ }
 212+ // Pass off the jQuery getJSON request:
 213+ $j.getJSON( url, data, myCallback );
 214+ }
 215+
 216+ /**
 217+ * Checks if a mw request data requires a post request or not
 218+ * @param {Object}
 219+ * @return {Boolean}
 220+ * true if the request requires a post request
 221+ * false if the request does not
 222+ */
 223+ mw.checkRequestPost = function ( data ) {
 224+ if( $j.inArray( data['action'], mw.getConfig( 'apiPostActions' ) ) != -1 ) {
 225+ return true;
 226+ }
 227+ if( data['prop'] == 'info' && data['intoken'] ) {
 228+ return true;
 229+ }
 230+ if( data['meta'] == 'userinfo' ) {
 231+ return true;
 232+ }
 233+ return false;
 234+ }
 235+
 236+ /**
 237+ * Check if the url is a request for the local domain
 238+ * relative paths are "local" domain
 239+ * @param {String} url Url for local domain
 240+ * @return {Boolean}
 241+ * true if url domain is local or relative
 242+ * false if the domain is
 243+ */
 244+ mw.isLocalDomain = function( url ) {
 245+ if( mw.parseUri( document.URL ).host == mw.parseUri( url ).host
 246+ || url.indexOf( '://' ) == -1 )
 247+ {
 248+ return true;
 249+ }
 250+ return false;
 251+ }
 252+
 253+ /**
 254+ * Api helper to grab an edit token
 255+ *
 256+ * @param {String} [apiUrl] Optional target API URL (uses default local api if unset)
 257+ * @param {String} title The wiki page title you want to edit
 258+ * @param {callback} callback Function to pass the token to.
 259+ * issues callback with "false" if token not retrieved
 260+ */
 261+ mw.getToken = function( apiUrl, title, callback ) {
 262+ // Make the apiUrl be optional:
 263+ if( typeof title == 'function' ) {
 264+ callback = title;
 265+ title = apiUrl;
 266+ apiUrl = mw.getLocalApiUrl();
 267+ }
 268+
 269+ mw.log( 'mw:getToken' );
 270+
 271+ var request = {
 272+ 'prop': 'info',
 273+ 'intoken': 'edit',
 274+ 'titles': title
 275+ };
 276+ mw.getJSON( apiUrl, request, function( data ) {
 277+ for ( var i in data.query.pages ) {
 278+ if ( data.query.pages[i]['edittoken'] ) {
 279+ callback ( data.query.pages[i]['edittoken'] );
 280+ return ;
 281+ }
 282+ }
 283+ // No token found:
 284+ callback ( false );
 285+ } );
 286+ }
 287+
 288+ /**
 289+ * Api helper to grab the username
 290+ * @param {String} [apiUrl] Optional target API url (uses default local api if unset)
 291+ * @param {Function} callback Function to callback with username or false if not found
 292+ * @param {Boolean} fresh A fresh check is issued.
 293+ */
 294+ // Stub feature apiUserNameCache to avoid multiple calls
 295+ // ( a more general api framework should be developed )
 296+ var apiUserNameCache = {};
 297+ mw.getUserName = function( apiUrl, callback, fresh ){
 298+ if( typeof apiUrl == 'function' ){
 299+ var callback = apiUrl;
 300+ var apiUrl = mw.getLocalApiUrl();
 301+ }
 302+
 303+ // If apiUrl is local check wgUserName global
 304+ // before issuing the api request.
 305+ if( mw.isLocalDomain( apiUrl ) ){
 306+ if( typeof wgUserName != 'undefined' && wgUserName !== null ) {
 307+ callback( wgUserName )
 308+ // In case someone called this function without a callback
 309+ return wgUserName;
 310+ }
 311+ }
 312+ if( ! fresh && apiUserNameCache[ apiUrl ] ) {
 313+ callback( apiUserNameCache[ apiUrl ] );
 314+ return ;
 315+ }
 316+
 317+ // Setup the api request
 318+ var request = {
 319+ 'action':'query',
 320+ 'meta':'userinfo'
 321+ }
 322+
 323+ // Do request
 324+ mw.getJSON( apiUrl, request, function( data ) {
 325+ if( !data || !data.query || !data.query.userinfo || !data.query.userinfo.name ){
 326+ // Could not get user name user is not-logged in
 327+ mw.log( " No userName in response " );
 328+ callback( false );
 329+ return ;
 330+ }
 331+ // Check for "not logged in" id == 0
 332+ if( data.query.userinfo.id == 0 ){
 333+ callback( false );
 334+ return ;
 335+ }
 336+ apiUserNameCache[ apiUrl ] = data.query.userinfo.name;
 337+ // Else return the username:
 338+ callback( data.query.userinfo.name );
 339+ }, function(){
 340+ // Timeout also results in callback( false ) ( no user found)
 341+ callback( false );
 342+ } );
 343+ }
 344+
 345+ /**
 346+ * Get the api url for a given content provider key
 347+ * @return {Mixed}
 348+ * url for the provider
 349+ * local wiki api if no apiProvider is set
 350+ */
 351+ mw.getApiProviderURL = function( providerId ) {
 352+ if( mw.getConfig( providerId + '_apiurl') ) {
 353+ return mw.getConfig( providerId + '_apiurl');
 354+ }
 355+ return mw.getLocalApiUrl();
 356+ };
 357+
 358+ /**
 359+ * Get Api URL from mediaWiki page defined variables
 360+ * @return {Mixed}
 361+ * api url
 362+ * false
 363+ */
 364+ mw.getLocalApiUrl = function() {
 365+ if ( typeof wgServer != 'undefined' && typeof wgScriptPath != 'undefined' ) {
 366+ return wgServer + wgScriptPath + '/api.php';
 367+ }
 368+ return false;
 369+ };
 370+
 371+}) ( window.mw );
\ No newline at end of file
Property changes on: branches/MwEmbedStandAlone/components/mw.Api.js
___________________________________________________________________
Name: svn:eol-style
1372 + native
Index: branches/MwEmbedStandAlone/components/mw.Parser.js
@@ -0,0 +1,323 @@
 2+/**
 3+* Mediawiki language text parser
 4+*/
 5+
 6+// Setup swap string constants
 7+var JQUERY_SWAP_STRING = 'ZjQuerySwapZ';
 8+var LINK_SWAP_STRING = 'ZreplaceZ';
 9+
 10+( function( mw ) {
 11+
 12+ // The parser magic global
 13+ var pMagicSet = { };
 14+
 15+ /**
 16+ * addTemplateTransform to the parser
 17+ *
 18+ * Lets you add a set template key to be transformed by a callback function
 19+ *
 20+ * @param {Object} magicSet key:callback
 21+ */
 22+ mw.addTemplateTransform = function( magicSet ) {
 23+ for ( var i in magicSet ) {
 24+ pMagicSet[ i ] = magicSet[i];
 25+ }
 26+ };
 27+
 28+ /**
 29+ * MediaWiki wikitext "Parser" constructor
 30+ *
 31+ * @param {String} wikiText the wikitext to be parsed
 32+ * @return {Object} parserObj returns a parser object that has methods for getting at
 33+ * things you would want
 34+ */
 35+ mw.Parser = function( wikiText, options) {
 36+ // return the parserObj
 37+ this.init( wikiText, options ) ;
 38+ };
 39+
 40+ mw.Parser.prototype = {
 41+
 42+ // the parser output string container
 43+ pOut: false,
 44+
 45+ init: function( wikiText, parserOptions ) {
 46+ this.wikiText = wikiText;
 47+ },
 48+
 49+ // Update the text value
 50+ updateText : function( wikiText ) {
 51+ this.wikiText = wikiText;
 52+
 53+ // invalidate the output ( will force a re-parse )
 54+ this.pOut = false;
 55+ },
 56+
 57+ /**
 58+ * Quickly recursive / parse out templates:
 59+ */
 60+ parse: function() {
 61+ function recurseTokenizeNodes ( text ) {
 62+ var node = { };
 63+ // Inspect each char
 64+ for ( var a = 0; a < text.length; a++ ) {
 65+ if ( text[a] == '{' && text[a + 1] == '{' ) {
 66+ a = a + 2;
 67+ node['parent'] = node;
 68+ if ( !node['child'] ) {
 69+ node['child'] = new Array();
 70+ }
 71+
 72+ node['child'].push( recurseTokenizeNodes( text.substr( a ) ) );
 73+ } else if ( text[a] == '}' && text[a + 1] == '}' ) {
 74+ a++;
 75+ if ( !node['parent'] ) {
 76+ return node;
 77+ }
 78+ node = node['parent'];
 79+ }
 80+ if ( !node['text'] ) {
 81+ node['text'] = '';
 82+ }
 83+ // Don't put }} closures into output:
 84+ if ( text[a] && text[a] != '}' ) {
 85+ node['text'] += text[a];
 86+ }
 87+ }
 88+ return node;
 89+ }
 90+
 91+ /**
 92+ * Parse template text as template name and named params
 93+ * @param {String} templateString Template String to be parsed
 94+ */
 95+ function parseTmplTxt( templateString ) {
 96+ var templateObject = { };
 97+
 98+ // Get template name:
 99+ templateName = templateString.split( '\|' ).shift() ;
 100+ templateName = templateName.split( '\{' ).shift() ;
 101+ templateName = templateName.replace( /^\s+|\s+$/g, "" ); //trim
 102+
 103+ // Check for arguments:
 104+ if ( templateName.split( ':' ).length == 1 ) {
 105+ templateObject["name"] = templateName;
 106+ } else {
 107+ templateObject["name"] = templateName.split( ':' ).shift();
 108+ templateObject["arg"] = templateName.split( ':' ).pop();
 109+ }
 110+
 111+ var paramSet = templateString.split( '\|' );
 112+ paramSet.splice( 0, 1 );
 113+ if ( paramSet.length ) {
 114+ templateObject.param = new Array();
 115+ for ( var pInx in paramSet ) {
 116+ var paramString = paramSet[ pInx ];
 117+ // check for empty param
 118+ if ( paramString == '' ) {
 119+ templateObject.param[ pInx ] = '';
 120+ continue;
 121+ }
 122+ for ( var b = 0 ; b < paramString.length ; b++ ) {
 123+ if ( paramString[b] == '=' && b > 0 && b < paramString.length && paramString[b - 1] != '\\' ) {
 124+ // named param
 125+ templateObject.param[ paramString.split( '=' ).shift() ] = paramString.split( '=' ).pop();
 126+ } else {
 127+ // indexed param
 128+ templateObject.param[ pInx ] = paramString;
 129+ }
 130+ }
 131+ }
 132+ }
 133+ return templateObject;
 134+ }
 135+
 136+ /**
 137+ * Get the Magic text from a template node
 138+ */
 139+ function getMagicTxtFromTempNode( node ) {
 140+ node.templateObject = parseTmplTxt ( node.text );
 141+ // Do magic swap if template key found in pMagicSet
 142+ if ( node.templateObject.name in pMagicSet ) {
 143+ var nodeText = pMagicSet[ node.templateObject.name ]( node.templateObject );
 144+ return nodeText;
 145+ } else {
 146+ // don't swap just return text
 147+ return node.text;
 148+ }
 149+ }
 150+
 151+ /**
 152+ * swap links of form [ ] for html a links or jquery helper spans
 153+ * NOTE: this could be integrated into the tokenizer but for now
 154+ * is a staged process.
 155+ *
 156+ * @param text to swapped
 157+ */
 158+ function linkSwapText( text ) {
 159+ //mw.log( "linkSwapText::" + text );
 160+ var re = new RegExp( /\[([^\s]+[\s]+[^\]]*)\]/g );
 161+ var matchSet = text.match( re );
 162+
 163+ if( !matchSet ){
 164+ return text;
 165+ }
 166+
 167+ text = text.replace( re , LINK_SWAP_STRING );
 168+
 169+ for( var i=0; i < matchSet.length; i++ ) {
 170+ // Strip the leading [ and trailing ]
 171+ var matchParts = matchSet[i].substr(1, matchSet[i].length-2);
 172+
 173+ // Check for special jQuery type swap and replace inner JQUERY_SWAP_STRING not value
 174+ if( matchParts.indexOf( JQUERY_SWAP_STRING ) !== -1 ) {
 175+ // parse the link as html
 176+ var $matchParts = $j('<span>' + matchParts + '</span>' );
 177+
 178+ $jQuerySpan = $matchParts.find('#' +JQUERY_SWAP_STRING + i );
 179+
 180+ var linkText = $matchParts.text();
 181+ //mw.log(" going to swap in linktext: " + linkText );
 182+ $jQuerySpan.text( linkText );
 183+
 184+ text = text.replace( LINK_SWAP_STRING, $j('<span />' ).append( $jQuerySpan ).html() );
 185+ } else {
 186+ // do text string replace
 187+ matchParts = matchParts.split(/ /);
 188+ var link = matchParts[0];
 189+ matchParts.shift();
 190+ var linkText = matchParts.join(' ');
 191+
 192+ text = text.replace( LINK_SWAP_STRING, '<a href="' + link + '">' + linkText + '</a>' );
 193+ }
 194+ }
 195+ return text;
 196+ }
 197+
 198+ /**
 199+ * recurse_magic_swap
 200+ *
 201+ * Go last child first swap upward:
 202+ */
 203+ var pNode = null;
 204+ function recurse_magic_swap( node ) {
 205+ if ( !pNode )
 206+ pNode = node;
 207+
 208+ if ( node['child'] ) {
 209+ // swap all the kids:
 210+ for ( var i in node['child'] ) {
 211+ var nodeText = recurse_magic_swap( node['child'][i] );
 212+ // swap it into current
 213+ if ( node.text ) {
 214+ node.text = node.text.replace( node['child'][i].text, nodeText );
 215+ }
 216+ // swap into parent
 217+ pNode.text = pNode.text.replace( node['child'][i].text, nodeText );
 218+ }
 219+ // Get the updated node text
 220+ var nodeText = getMagicTxtFromTempNode( node );
 221+ pNode.text = pNode.text.replace( node.text , nodeText );
 222+ // return the node text
 223+ return node.text;
 224+ } else {
 225+ return getMagicTxtFromTempNode( node );
 226+ }
 227+ }
 228+
 229+ // Parse out the template node structure:
 230+ this.pNode = recurseTokenizeNodes ( this.wikiText );
 231+
 232+ // Strip out the parent from the root
 233+ this.pNode['parent'] = null;
 234+
 235+ // Do the recursive magic swap text:
 236+ this.pOut = recurse_magic_swap( this.pNode );
 237+
 238+ // Do link swap
 239+ this.pOut = linkSwapText( this.pOut );
 240+ },
 241+
 242+ /**
 243+ * templates
 244+ *
 245+ * Get a requested template from the wikitext (if available)
 246+ * @param templateName
 247+ */
 248+ templates: function( templateName ) {
 249+ this.parse();
 250+ var tmplSet = new Array();
 251+ function getMatchingTmpl( node ) {
 252+ if ( node['child'] ) {
 253+ for ( var i in node['child'] ) {
 254+ getMatchingTmpl( node['child'] );
 255+ }
 256+ }
 257+ if ( templateName && node.templateObject ) {
 258+ if ( node.templateObject['name'] == templateName )
 259+ tmplSet.push( node.templateObject );
 260+ } else if ( node.templateObject ) {
 261+ tmplSet.push( node.templateObject );
 262+ }
 263+ }
 264+ getMatchingTmpl( this.pNode );
 265+ return tmplSet;
 266+ },
 267+
 268+ /**
 269+ * getTemplateVars
 270+ * returns a set of template values in a given wikitext page
 271+ *
 272+ * NOTE: should be integrated with the usability wikitext parser
 273+ */
 274+ getTemplateVars: function() {
 275+ //mw.log('matching against: ' + wikiText);
 276+ templateVars = new Array();
 277+ var tempVars = wikiText.match(/\{\{\{([^\}]*)\}\}\}/gi);
 278+
 279+ // Clean up results:
 280+ for(var i=0; i < tempVars.length; i++) {
 281+ //match
 282+ var tvar = tempVars[i].replace('{{{','').replace('}}}','');
 283+
 284+ // Strip anything after a |
 285+ if(tvar.indexOf('|') != -1) {
 286+ tvar = tvar.substr(0, tvar.indexOf('|'));
 287+ }
 288+
 289+ // Check for duplicates:
 290+ var do_add=true;
 291+ for(var j=0; j < templateVars.length; j++) {
 292+ if( templateVars[j] == tvar)
 293+ do_add=false;
 294+ }
 295+
 296+ // Add the template vars to the output obj
 297+ if(do_add)
 298+ templateVars.push( tvar );
 299+ }
 300+ return templateVars;
 301+ },
 302+
 303+ /**
 304+ * Returns the transformed wikitext
 305+ *
 306+ * Build output from swappable index
 307+ * (all transforms must be expanded in parse stage and linearly rebuilt)
 308+ * Alternatively we could build output using a place-holder & replace system
 309+ * (this lets us be slightly more sloppy with ordering and indexes, but probably slower)
 310+ *
 311+ * Ideal: we build a 'wiki DOM'
 312+ * When editing you update the data structure directly
 313+ * Then in output time you just go DOM->html-ish output without re-parsing anything
 314+ */
 315+ getHTML: function() {
 316+ // wikiText updates should invalidate pOut
 317+ if ( ! this.pOut ) {
 318+ this.parse();
 319+ }
 320+ return this.pOut;
 321+ }
 322+ };
 323+
 324+}) ( window.mw );
\ No newline at end of file
Property changes on: branches/MwEmbedStandAlone/components/mw.Parser.js
___________________________________________________________________
Name: svn:mergeinfo
1325 + /branches/REL1_15/phase3/js2/mwEmbed/php/languages/mw.Parser.js:51646
/branches/sqlite/js2/mwEmbed/php/languages/mw.Parser.js:58211-58321
Name: svn:eol-style
2326 + native
Name: svn:executable
3327 + *
Index: branches/MwEmbedStandAlone/components/README
@@ -0,0 +1,3 @@
 2+Components are parts of the core mwEmbed package that have been separated into different files for easy maintainability.
 3+
 4+Default included Components are listed in the main loader.js file.
\ No newline at end of file
Index: branches/MwEmbedStandAlone/languages/mw.Language.js
@@ -1,1118 +0,0 @@
2 -/**
3 -* Core Language mw.Language object
4 -*
5 -* Localized Language support attempts to mirror some of the functionality of Language.php in MediaWiki
6 -* It contains methods for loading and transforming msg text
7 -
8 -*/
9 -
10 -( function( mw ) {
11 -
12 - // Setup the global mw.Language var:
13 - mw.Language = { };
14 -
15 - /**
16 - * Setup the lang object
17 - */
18 - var messageCache = { };
19 - var gRuleSet = { };
20 -
21 - /**
22 - * mw.addMessages function
23 - * Loads a set of json messages into the messegeCache object.
24 - *
25 - * @param {JSON} msgSet The set of msgs to be loaded
26 - */
27 - mw.addMessages = function( msgSet ) {
28 - for ( var i in msgSet ) {
29 - messageCache[ i ] = msgSet[i];
30 - }
31 - }
32 - // By default set the current class missing messages flag to default.
33 - mw.currentClassMissingMessages = false;
34 -
35 - /**
36 - * mw.addMessagesKey function
37 - * Adds a messageKey to be pulled in remotely.
38 - *
39 - * NOTE the script-loader should replace addMessageKeys with localized addMessages calls
40 - *
41 - * If addMessagesKey is called then we are running in raw file debug mode.
42 - * it populates the messegeKeyQueue and loads the values in a separate request callback
43 - *
44 - * @param {Array} msgSet The set of msgs to be loaded
45 - */
46 - mw.addMessageKeys = function( msgSet ) {
47 - // Check if any msg key from this class is missing
48 - for( var i in msgSet ){
49 - if( ! messageCache[ i ] ) {
50 - // Set the missing messages flag ( script-loader is probably off)
51 - mw.currentClassMissingMessages = true;
52 - return false;
53 - }
54 - }
55 - return true;
56 - }
57 -
58 - /**
59 - * Special function to register that all of the module messages need to be loaded.
60 - */
61 - mw.includeAllModuleMessages = function (){
62 - mw.currentClassMissingMessages = true;
63 - }
64 -
65 - /**
66 - * Load messages for a given named javascript class.
67 - * This worked in conjunction with the scriptLoader
68 - * @param {string} className Name of class file to be loaded
69 - * @param {function} callback Function to be called once class messages are loaded.
70 - */
71 - mw.loadResourceMessages = function( className, callback ) {
72 - // Check if wgScriptLoaderPath is set ( else guess the path relative to mwEmbed)
73 - if ( typeof wgScriptLoaderLocation == 'undefined' || ! wgScriptLoaderLocation ){
74 - wgScriptLoaderLocation = mw.getMwEmbedPath() + 'ResourceLoader.php';
75 - }
76 - // Run the addMessages script-loader call
77 - mw.getScript( wgScriptLoaderLocation + '?class=' + className + '&format=messages', callback);
78 - }
79 -
80 -
81 - /**
82 - * Returns a transformed msg string
83 - *
84 - * it take a msg key and array of replacement values of form
85 - * $1, $2 and does relevant messageKey transformation returning
86 - * the user msg.
87 - *
88 - * @param {String} messageKey The msg key as set by mw.addMessages
89 - * @param {Mixed} args A string|jQuery Object or array of string|jQuery Objects
90 - *
91 - * extra parameters are appended to the args array as numbered replacements
92 - *
93 - * @return string
94 - */
95 - mw.getMsg = function( messageKey , args ) {
96 -
97 - // Check for missing message key
98 - if ( ! messageCache[ messageKey ] ){
99 - return '[' + messageKey + ']';
100 - }
101 - // Check if we need to do args replacements:
102 - if( typeof args != 'undefined' ) {
103 -
104 - // Make arg into an array if its not already an array
105 - if ( typeof args == 'string'
106 - || typeof args == 'number'
107 - || args instanceof jQuery )
108 - {
109 - args = [ args ];
110 - }
111 -
112 - // Put any extra arguments into the args array
113 - var extraArgs = $j.makeArray( arguments );
114 - for(var i=2; i < extraArgs.length; i ++ ) {
115 - args.push( extraArgs[ i ] );
116 - }
117 - }
118 - // Fast check message text return ( no arguments and no parsing needed )
119 - if( ( !args || args.length == 0 )
120 - && messageCache[ messageKey ].indexOf( '{{' ) === -1
121 - && messageCache[ messageKey ].indexOf( '[' ) === -1
122 - ) {
123 - return messageCache[ messageKey ];
124 - }
125 -
126 - // Else Setup the messageSwap object:
127 - var messageSwap = new mw.Language.messageSwapObject( messageCache[ messageKey ], args );
128 -
129 - // Return the jQuery object or message string
130 - return messageSwap.getMsg();
131 - }
132 -
133 - /**
134 - * A message Swap Object
135 - * Swap object manages message type swapping and returns jQuery or text output
136 - *
137 - * @param {String} message The text of the message
138 - * @param {array} arguments A set of swap arguments
139 - */
140 -
141 - mw.Language.messageSwapObject = function( message, arguments ){
142 - this.init( message, arguments );
143 - }
144 -
145 - mw.Language.messageSwapObject.prototype= {
146 - /* constructor */
147 - init: function( message, arguments ){
148 - this.message = message;
149 - this.arguments = arguments;
150 -
151 - // Set the includesjQueryArgs flag to false
152 - includesjQueryArgs: false;
153 - },
154 -
155 - // Return the transformed message text or jQuery object
156 - getMsg: function(){
157 - // Get message with string swap
158 - this.replaceStringArgs();
159 -
160 - // Check if we need to parse the string
161 - if( this.message.indexOf( '{{' ) === -1
162 - && this.message.indexOf( '[' ) === -1
163 - && ! this.includesjQueryArgs )
164 - {
165 - // replaceStringArgs is all we need, return the msg
166 - return this.message
167 - }
168 -
169 - // Else Send the messageText through the parser
170 - var pObj = new mw.Parser( this.message );
171 -
172 - // Get template and link transformed text:
173 - this.message = pObj.getHTML();
174 -
175 - // if jQuery arguments is false return message string
176 - if(! this.includesjQueryArgs ){
177 - //Do string link substitution
178 - return this.message;
179 - }
180 -
181 - // jQuery arguments exist swap and return jQuery object
182 - return this.getJQueryArgsReplace();
183 -
184 - },
185 -
186 - /**
187 - * Swap in an array of values for $1, $2, $n for a given msg key
188 - *
189 - * @param string messageKey The msg key to lookup
190 - * @param {Array} args An array of string or jQuery objects to be swapped in
191 - * @return string
192 - */
193 - replaceStringArgs : function() {
194 - if( ! this.arguments ) {
195 - return ;
196 - }
197 - // Replace Values
198 - for ( var v = 0; v < this.arguments.length; v++ ) {
199 - if( typeof this.arguments[v] == 'undefined' ) {
200 - continue;
201 - }
202 - var replaceValue = this.arguments[ v ];
203 -
204 - // Convert number if applicable
205 - if( parseInt( replaceValue ) == replaceValue ) {
206 - replaceValue = mw.Language.convertNumber( replaceValue );
207 - }
208 -
209 - // Message test replace arguments start at 1 instead of zero:
210 - var argumentRegExp = new RegExp( '\\$' + ( parseInt( v ) + 1 ), 'g' );
211 -
212 - // Check if we got passed in a jQuery object:
213 - if( replaceValue instanceof jQuery) {
214 - // Set the jQuery msg flag
215 - this.includesjQueryArgs = true;
216 - // Swap in a jQuery span place holder:
217 - this.message = this.message.replace( argumentRegExp,
218 - '<span id="' + JQUERY_SWAP_STRING + v +'"></span>' );
219 - } else {
220 - // Assume replaceValue is a string
221 - this.message = this.message.replace( argumentRegExp, replaceValue );
222 - }
223 - }
224 - },
225 -
226 - /**
227 - * Return a jquery element with resolved swapped arguments.
228 - * return {Element}
229 - */
230 - getJQueryArgsReplace: function() {
231 - var $jQueryMessage = false;
232 - mw.log( 'msgReplaceJQueryArgs' );
233 - for ( var v = 0; v < this.arguments.length; v++ ) {
234 - if( typeof this.arguments[v] == 'undefined' ) {
235 - continue;
236 - }
237 - var $replaceValue = this.arguments[ v ];
238 - // Only look for jQuery replacements
239 - if( $replaceValue instanceof jQuery) {
240 - // Setup the jqueryMessage if not set
241 - if( !$jQueryMessage ){
242 - // Setup the message as html to search for jquery swap points
243 - $jQueryMessage = $j( '<span />' ).html( this.message );
244 - }
245 - mw.log(" current jQueryMessage::: " + $jQueryMessage.html() );
246 - // Find swap target
247 - var $swapTarget = $jQueryMessage.find( '#' + JQUERY_SWAP_STRING + v );
248 - // Now we try and find the jQuerySwap points and replace with jQuery object preserving bindings.
249 - if( ! $swapTarget.length ){
250 - mw.log( "Error could not find jQuery Swap target: " + v + ' by id: '+ JQUERY_SWAP_STRING + v
251 - + ' In string: ' + this.message ) ;
252 - continue;
253 - }
254 -
255 - if( $swapTarget.html() != '' ) {
256 - $replaceValue.html( $swapTarget.html() );
257 - }
258 -
259 - // Swap for $swapTarget for $replaceValue swap target * preserving the jQuery binding )
260 - $swapTarget.replaceWith( $replaceValue );
261 - }
262 - }
263 - // Return the jQuery object ( if no jQuery substitution occurred we return false )
264 - return $jQueryMessage;
265 - }
266 - }
267 -
268 - /**
269 - * Get msg content without transformation
270 - *
271 - * @returns string The msg key without transforming it
272 - */
273 - mw.Language.msgNoTrans = function( key ) {
274 - if ( messageCache[ key ] )
275 - return messageCache[ key ]
276 -
277 - // Missing key placeholder
278 - return '&lt;' + key + '&gt;';
279 - }
280 -
281 - /**
282 - * Add Supported Magic Words to parser
283 - */
284 - // Set the setupflag to false:
285 - mw.Language.doneSetup = false;
286 - mw.Language.magicSetup = function() {
287 - if ( !mw.Language.doneSetup ) {
288 - mw.addTemplateTransform ( {
289 - 'PLURAL' : mw.Language.procPLURAL,
290 - 'GENDER' : mw.Language.procGENDER
291 - } )
292 -
293 - mw.Language.doneSetup = true;
294 - }
295 -
296 - }
297 -
298 - /**
299 - * List of all languages mediaWiki supports ( Avoid an api call to get this same info )
300 - * http://commons.wikimedia.org/w/api.php?action=query&meta=siteinfo&siprop=languages&format=jsonfm
301 - */
302 - mw.Language.names = {
303 - "aa" : "Qaf\u00e1r af",
304 - "ab" : "\u0410\u04a7\u0441\u0443\u0430",
305 - "ace" : "Ac\u00e8h",
306 - "af" : "Afrikaans",
307 - "ak" : "Akan",
308 - "aln" : "Geg\u00eb",
309 - "als" : "Alemannisch",
310 - "am" : "\u12a0\u121b\u122d\u129b",
311 - "an" : "Aragon\u00e9s",
312 - "ang" : "Anglo-Saxon",
313 - "ar" : "\u0627\u0644\u0639\u0631\u0628\u064a\u0629",
314 - "arc" : "\u0710\u072a\u0721\u071d\u0710",
315 - "arn" : "Mapudungun",
316 - "arz" : "\u0645\u0635\u0631\u0649",
317 - "as" : "\u0985\u09b8\u09ae\u09c0\u09af\u09bc\u09be",
318 - "ast" : "Asturianu",
319 - "av" : "\u0410\u0432\u0430\u0440",
320 - "avk" : "Kotava",
321 - "ay" : "Aymar aru",
322 - "az" : "Az\u0259rbaycan",
323 - "ba" : "\u0411\u0430\u0448\u04a1\u043e\u0440\u0442",
324 - "bar" : "Boarisch",
325 - "bat-smg" : "\u017demait\u0117\u0161ka",
326 - "bcc" : "\u0628\u0644\u0648\u0686\u06cc \u0645\u06a9\u0631\u0627\u0646\u06cc",
327 - "bcl" : "Bikol Central",
328 - "be" : "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f",
329 - "be-tarask" : "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430)",
330 - "be-x-old" : "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430)",
331 - "bg" : "\u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438",
332 - "bh" : "\u092d\u094b\u091c\u092a\u0941\u0930\u0940",
333 - "bi" : "Bislama",
334 - "bm" : "Bamanankan",
335 - "bn" : "\u09ac\u09be\u0982\u09b2\u09be",
336 - "bo" : "\u0f56\u0f7c\u0f51\u0f0b\u0f61\u0f72\u0f42",
337 - "bpy" : "\u0987\u09ae\u09be\u09b0 \u09a0\u09be\u09b0\/\u09ac\u09bf\u09b7\u09cd\u09a3\u09c1\u09aa\u09cd\u09b0\u09bf\u09af\u09bc\u09be \u09ae\u09a3\u09bf\u09aa\u09c1\u09b0\u09c0",
338 - "bqi" : "\u0628\u062e\u062a\u064a\u0627\u0631\u064a",
339 - "br" : "Brezhoneg",
340 - "bs" : "Bosanski",
341 - "bug" : "\u1a05\u1a14 \u1a15\u1a18\u1a01\u1a17",
342 - "bxr" : "\u0411\u0443\u0440\u044f\u0430\u0434",
343 - "ca" : "Catal\u00e0",
344 - "cbk-zam" : "Chavacano de Zamboanga",
345 - "cdo" : "M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304",
346 - "ce" : "\u041d\u043e\u0445\u0447\u0438\u0439\u043d",
347 - "ceb" : "Cebuano",
348 - "ch" : "Chamoru",
349 - "cho" : "Choctaw",
350 - "chr" : "\u13e3\u13b3\u13a9",
351 - "chy" : "Tsets\u00eahest\u00e2hese",
352 - "ckb" : "Soran\u00ee \/ \u06a9\u0648\u0631\u062f\u06cc",
353 - "ckb-latn" : "\u202aSoran\u00ee (lat\u00een\u00ee)\u202c",
354 - "ckb-arab" : "\u202b\u06a9\u0648\u0631\u062f\u06cc (\u0639\u06d5\u0631\u06d5\u0628\u06cc)\u202c",
355 - "co" : "Corsu",
356 - "cr" : "N\u0113hiyaw\u0113win \/ \u14c0\u1426\u1403\u152d\u140d\u140f\u1423",
357 - "crh" : "Q\u0131r\u0131mtatarca",
358 - "crh-latn" : "\u202aQ\u0131r\u0131mtatarca (Latin)\u202c",
359 - "crh-cyrl" : "\u202a\u041a\u044a\u044b\u0440\u044b\u043c\u0442\u0430\u0442\u0430\u0440\u0434\u0436\u0430 (\u041a\u0438\u0440\u0438\u043b\u043b)\u202c",
360 - "cs" : "\u010cesky",
361 - "csb" : "Kasz\u00ebbsczi",
362 - "cu" : "\u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f",
363 - "cv" : "\u0427\u04d1\u0432\u0430\u0448\u043b\u0430",
364 - "cy" : "Cymraeg",
365 - "da" : "Dansk",
366 - "de" : "Deutsch",
367 - "de-at" : "\u00d6sterreichisches Deutsch",
368 - "de-ch" : "Schweizer Hochdeutsch",
369 - "de-formal" : "Deutsch (Sie-Form)",
370 - "diq" : "Zazaki",
371 - "dk" : "Dansk (deprecated:da)",
372 - "dsb" : "Dolnoserbski",
373 - "dv" : "\u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0",
374 - "dz" : "\u0f47\u0f7c\u0f44\u0f0b\u0f41",
375 - "ee" : "E\u028begbe",
376 - "el" : "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac",
377 - "eml" : "Emili\u00e0n e rumagn\u00f2l",
378 - "en" : "English",
379 - "en-gb" : "British English",
380 - "eo" : "Esperanto",
381 - "es" : "Espa\u00f1ol",
382 - "et" : "Eesti",
383 - "eu" : "Euskara",
384 - "ext" : "Estreme\u00f1u",
385 - "fa" : "\u0641\u0627\u0631\u0633\u06cc",
386 - "ff" : "Fulfulde",
387 - "fi" : "Suomi",
388 - "fiu-vro" : "V\u00f5ro",
389 - "fj" : "Na Vosa Vakaviti",
390 - "fo" : "F\u00f8royskt",
391 - "fr" : "Fran\u00e7ais",
392 - "frc" : "Fran\u00e7ais cadien",
393 - "frp" : "Arpetan",
394 - "fur" : "Furlan",
395 - "fy" : "Frysk",
396 - "ga" : "Gaeilge",
397 - "gag" : "Gagauz",
398 - "gan" : "\u8d1b\u8a9e",
399 - "gan-hans" : "\u8d63\u8bed(\u7b80\u4f53)",
400 - "gan-hant" : "\u8d1b\u8a9e(\u7e41\u9ad4)",
401 - "gd" : "G\u00e0idhlig",
402 - "gl" : "Galego",
403 - "glk" : "\u06af\u06cc\u0644\u06a9\u06cc",
404 - "gn" : "Ava\u00f1e'\u1ebd",
405 - "got" : "\ud800\udf32\ud800\udf3f\ud800\udf44\ud800\udf39\ud800\udf43\ud800\udf3a",
406 - "grc" : "\u1f08\u03c1\u03c7\u03b1\u03af\u03b1 \u1f11\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u1f74",
407 - "gsw" : "Alemannisch",
408 - "gu" : "\u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0",
409 - "gv" : "Gaelg",
410 - "ha" : "\u0647\u064e\u0648\u064f\u0633\u064e",
411 - "hak" : "Hak-k\u00e2-fa",
412 - "haw" : "Hawai`i",
413 - "he" : "\u05e2\u05d1\u05e8\u05d9\u05ea",
414 - "hi" : "\u0939\u093f\u0928\u094d\u0926\u0940",
415 - "hif" : "Fiji Hindi",
416 - "hif-deva" : "\u092b\u093c\u0940\u091c\u0940 \u0939\u093f\u0928\u094d\u0926\u0940",
417 - "hif-latn" : "Fiji Hindi",
418 - "hil" : "Ilonggo",
419 - "ho" : "Hiri Motu",
420 - "hr" : "Hrvatski",
421 - "hsb" : "Hornjoserbsce",
422 - "ht" : "Krey\u00f2l ayisyen",
423 - "hu" : "Magyar",
424 - "hy" : "\u0540\u0561\u0575\u0565\u0580\u0565\u0576",
425 - "hz" : "Otsiherero",
426 - "ia" : "Interlingua",
427 - "id" : "Bahasa Indonesia",
428 - "ie" : "Interlingue",
429 - "ig" : "Igbo",
430 - "ii" : "\ua187\ua259",
431 - "ik" : "I\u00f1upiak",
432 - "ike-cans" : "\u1403\u14c4\u1483\u144e\u1450\u1466",
433 - "ike-latn" : "inuktitut",
434 - "ilo" : "Ilokano",
435 - "inh" : "\u0413\u0406\u0430\u043b\u0433\u0406\u0430\u0439 \u011eal\u011faj",
436 - "io" : "Ido",
437 - "is" : "\u00cdslenska",
438 - "it" : "Italiano",
439 - "iu" : "\u1403\u14c4\u1483\u144e\u1450\u1466\/inuktitut",
440 - "ja" : "\u65e5\u672c\u8a9e",
441 - "jbo" : "Lojban",
442 - "jut" : "Jysk",
443 - "jv" : "Basa Jawa",
444 - "ka" : "\u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8",
445 - "kaa" : "Qaraqalpaqsha",
446 - "kab" : "Taqbaylit",
447 - "kg" : "Kongo",
448 - "ki" : "G\u0129k\u0169y\u0169",
449 - "kiu" : "Kurmanc\u00ee",
450 - "kj" : "Kwanyama",
451 - "kk" : "\u049a\u0430\u0437\u0430\u049b\u0448\u0430",
452 - "kk-arab" : "\u202b\u0642\u0627\u0632\u0627\u0642\u0634\u0627 (\u062a\u0674\u0648\u062a\u06d5)\u202c",
453 - "kk-cyrl" : "\u202a\u049a\u0430\u0437\u0430\u049b\u0448\u0430 (\u043a\u0438\u0440\u0438\u043b)\u202c",
454 - "kk-latn" : "\u202aQazaq\u015fa (lat\u0131n)\u202c",
455 - "kk-cn" : "\u202b\u0642\u0627\u0632\u0627\u0642\u0634\u0627 (\u062c\u06c7\u0646\u06af\u0648)\u202c",
456 - "kk-kz" : "\u202a\u049a\u0430\u0437\u0430\u049b\u0448\u0430 (\u049a\u0430\u0437\u0430\u049b\u0441\u0442\u0430\u043d)\u202c",
457 - "kk-tr" : "\u202aQazaq\u015fa (T\u00fcrk\u00efya)\u202c",
458 - "kl" : "Kalaallisut",
459 - "km" : "\u1797\u17b6\u179f\u17b6\u1781\u17d2\u1798\u17c2\u179a",
460 - "kn" : "\u0c95\u0ca8\u0ccd\u0ca8\u0ca1",
461 - "ko" : "\ud55c\uad6d\uc5b4",
462 - "ko-kp" : "\ud55c\uad6d\uc5b4 (\uc870\uc120)",
463 - "kr" : "Kanuri",
464 - "kri" : "Krio",
465 - "krj" : "Kinaray-a",
466 - "ks" : "\u0915\u0936\u094d\u092e\u0940\u0930\u0940 - (\u0643\u0634\u0645\u064a\u0631\u064a)",
467 - "ksh" : "Ripoarisch",
468 - "ku" : "Kurd\u00ee \/ \u0643\u0648\u0631\u062f\u06cc",
469 - "ku-latn" : "\u202aKurd\u00ee (lat\u00een\u00ee)\u202c",
470 - "ku-arab" : "\u202b\u0643\u0648\u0631\u062f\u064a (\u0639\u06d5\u0631\u06d5\u0628\u06cc)\u202c",
471 - "kv" : "\u041a\u043e\u043c\u0438",
472 - "kw" : "Kernowek",
473 - "ky" : "\u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430",
474 - "la" : "Latina",
475 - "lad" : "Ladino",
476 - "lb" : "L\u00ebtzebuergesch",
477 - "lbe" : "\u041b\u0430\u043a\u043a\u0443",
478 - "lez" : "\u041b\u0435\u0437\u0433\u0438",
479 - "lfn" : "Lingua Franca Nova",
480 - "lg" : "Luganda",
481 - "li" : "Limburgs",
482 - "lij" : "L\u00edguru",
483 - "lmo" : "Lumbaart",
484 - "ln" : "Ling\u00e1la",
485 - "lo" : "\u0ea5\u0eb2\u0ea7",
486 - "loz" : "Silozi",
487 - "lt" : "Lietuvi\u0173",
488 - "lv" : "Latvie\u0161u",
489 - "lzh" : "\u6587\u8a00",
490 - "mai" : "\u092e\u0948\u0925\u093f\u0932\u0940",
491 - "map-bms" : "Basa Banyumasan",
492 - "mdf" : "\u041c\u043e\u043a\u0448\u0435\u043d\u044c",
493 - "mg" : "Malagasy",
494 - "mh" : "Ebon",
495 - "mhr" : "\u041e\u043b\u044b\u043a \u041c\u0430\u0440\u0438\u0439",
496 - "mi" : "M\u0101ori",
497 - "mk" : "\u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438",
498 - "ml" : "\u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02",
499 - "mn" : "\u041c\u043e\u043d\u0433\u043e\u043b",
500 - "mo" : "\u041c\u043e\u043b\u0434\u043e\u0432\u0435\u043d\u044f\u0441\u043a\u044d",
501 - "mr" : "\u092e\u0930\u093e\u0920\u0940",
502 - "ms" : "Bahasa Melayu",
503 - "mt" : "Malti",
504 - "mus" : "Mvskoke",
505 - "mwl" : "Mirand\u00e9s",
506 - "my" : "\u1019\u103c\u1014\u103a\u1019\u102c\u1018\u102c\u101e\u102c",
507 - "myv" : "\u042d\u0440\u0437\u044f\u043d\u044c",
508 - "mzn" : "\u0645\u064e\u0632\u0650\u0631\u0648\u0646\u064a",
509 - "na" : "Dorerin Naoero",
510 - "nah" : "N\u0101huatl",
511 - "nan" : "B\u00e2n-l\u00e2m-g\u00fa",
512 - "nap" : "Nnapulitano",
513 - "nb" : "\u202aNorsk (bokm\u00e5l)\u202c",
514 - "nds" : "Plattd\u00fc\u00fctsch",
515 - "nds-nl" : "Nedersaksisch",
516 - "ne" : "\u0928\u0947\u092a\u093e\u0932\u0940",
517 - "new" : "\u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e",
518 - "ng" : "Oshiwambo",
519 - "niu" : "Niu\u0113",
520 - "nl" : "Nederlands",
521 - "nn" : "\u202aNorsk (nynorsk)\u202c",
522 - "no" : "\u202aNorsk (bokm\u00e5l)\u202c",
523 - "nov" : "Novial",
524 - "nrm" : "Nouormand",
525 - "nso" : "Sesotho sa Leboa",
526 - "nv" : "Din\u00e9 bizaad",
527 - "ny" : "Chi-Chewa",
528 - "oc" : "Occitan",
529 - "om" : "Oromoo",
530 - "or" : "\u0b13\u0b21\u0b3c\u0b3f\u0b06",
531 - "os" : "\u0418\u0440\u043e\u043d\u0430\u0443",
532 - "pa" : "\u0a2a\u0a70\u0a1c\u0a3e\u0a2c\u0a40",
533 - "pag" : "Pangasinan",
534 - "pam" : "Kapampangan",
535 - "pap" : "Papiamentu",
536 - "pcd" : "Picard",
537 - "pdc" : "Deitsch",
538 - "pdt" : "Plautdietsch",
539 - "pfl" : "Pf\u00e4lzisch",
540 - "pi" : "\u092a\u093e\u093f\u0934",
541 - "pih" : "Norfuk \/ Pitkern",
542 - "pl" : "Polski",
543 - "pms" : "Piemont\u00e8is",
544 - "pnb" : "\u067e\u0646\u062c\u0627\u0628\u06cc",
545 - "pnt" : "\u03a0\u03bf\u03bd\u03c4\u03b9\u03b1\u03ba\u03ac",
546 - "ps" : "\u067e\u069a\u062a\u0648",
547 - "pt" : "Portugu\u00eas",
548 - "pt-br" : "Portugu\u00eas do Brasil",
549 - "qu" : "Runa Simi",
550 - "rif" : "Tarifit",
551 - "rm" : "Rumantsch",
552 - "rmy" : "Romani",
553 - "rn" : "Kirundi",
554 - "ro" : "Rom\u00e2n\u0103",
555 - "roa-rup" : "Arm\u00e3neashce",
556 - "roa-tara" : "Tarand\u00edne",
557 - "ru" : "\u0420\u0443\u0441\u0441\u043a\u0438\u0439",
558 - "ruq" : "Vl\u0103he\u015fte",
559 - "ruq-cyrl" : "\u0412\u043b\u0430\u0445\u0435\u0441\u0442\u0435",
560 - "ruq-latn" : "Vl\u0103he\u015fte",
561 - "rw" : "Kinyarwanda",
562 - "sa" : "\u0938\u0902\u0938\u094d\u0915\u0943\u0924",
563 - "sah" : "\u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430",
564 - "sc" : "Sardu",
565 - "scn" : "Sicilianu",
566 - "sco" : "Scots",
567 - "sd" : "\u0633\u0646\u068c\u064a",
568 - "sdc" : "Sassaresu",
569 - "se" : "S\u00e1megiella",
570 - "sei" : "Cmique Itom",
571 - "sg" : "S\u00e4ng\u00f6",
572 - "sh" : "Srpskohrvatski \/ \u0421\u0440\u043f\u0441\u043a\u043e\u0445\u0440\u0432\u0430\u0442\u0441\u043a\u0438",
573 - "shi" : "Ta\u0161l\u1e25iyt",
574 - "si" : "\u0dc3\u0dd2\u0d82\u0dc4\u0dbd",
575 - "simple" : "Simple English",
576 - "sk" : "Sloven\u010dina",
577 - "sl" : "Sloven\u0161\u010dina",
578 - "sli" : "Schl\u00e4sch",
579 - "sm" : "Gagana Samoa",
580 - "sma" : "\u00c5arjelsaemien",
581 - "sn" : "chiShona",
582 - "so" : "Soomaaliga",
583 - "sq" : "Shqip",
584 - "sr" : "\u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski",
585 - "sr-ec" : "\u0421\u0440\u043f\u0441\u043a\u0438 (\u045b\u0438\u0440\u0438\u043b\u0438\u0446\u0430)",
586 - "sr-el" : "Srpski (latinica)",
587 - "srn" : "Sranantongo",
588 - "ss" : "SiSwati",
589 - "st" : "Sesotho",
590 - "stq" : "Seeltersk",
591 - "su" : "Basa Sunda",
592 - "sv" : "Svenska",
593 - "sw" : "Kiswahili",
594 - "szl" : "\u015al\u016fnski",
595 - "ta" : "\u0ba4\u0bae\u0bbf\u0bb4\u0bcd",
596 - "tcy" : "\u0ca4\u0cc1\u0cb3\u0cc1",
597 - "te" : "\u0c24\u0c46\u0c32\u0c41\u0c17\u0c41",
598 - "tet" : "Tetun",
599 - "tg" : "\u0422\u043e\u04b7\u0438\u043a\u04e3",
600 - "tg-cyrl" : "\u0422\u043e\u04b7\u0438\u043a\u04e3",
601 - "tg-latn" : "tojik\u012b",
602 - "th" : "\u0e44\u0e17\u0e22",
603 - "ti" : "\u1275\u130d\u122d\u129b",
604 - "tk" : "T\u00fcrkmen\u00e7e",
605 - "tl" : "Tagalog",
606 - "tn" : "Setswana",
607 - "to" : "lea faka-Tonga",
608 - "tokipona" : "Toki Pona",
609 - "tp" : "Toki Pona (deprecated:tokipona)",
610 - "tpi" : "Tok Pisin",
611 - "tr" : "T\u00fcrk\u00e7e",
612 - "ts" : "Xitsonga",
613 - "tt" : "\u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a",
614 - "tt-cyrl" : "\u0422\u0430\u0442\u0430\u0440\u0447\u0430",
615 - "tt-latn" : "Tatar\u00e7a",
616 - "tum" : "chiTumbuka",
617 - "tw" : "Twi",
618 - "ty" : "Reo M\u0101`ohi",
619 - "tyv" : "\u0422\u044b\u0432\u0430 \u0434\u044b\u043b",
620 - "udm" : "\u0423\u0434\u043c\u0443\u0440\u0442",
621 - "ug" : "Uyghurche\u200e \/ \u0626\u06c7\u064a\u063a\u06c7\u0631\u0686\u06d5",
622 - "ug-arab" : "\u0626\u06c7\u064a\u063a\u06c7\u0631\u0686\u06d5",
623 - "ug-latn" : "Uyghurche\u200e",
624 - "uk" : "\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430",
625 - "ur" : "\u0627\u0631\u062f\u0648",
626 - "uz" : "O'zbek",
627 - "ve" : "Tshivenda",
628 - "vec" : "V\u00e8neto",
629 - "vep" : "Vepsan kel'",
630 - "vi" : "Ti\u1ebfng Vi\u1ec7t",
631 - "vls" : "West-Vlams",
632 - "vo" : "Volap\u00fck",
633 - "vro" : "V\u00f5ro",
634 - "wa" : "Walon",
635 - "war" : "Winaray",
636 - "wo" : "Wolof",
637 - "wuu" : "\u5434\u8bed",
638 - "xal" : "\u0425\u0430\u043b\u044c\u043c\u0433",
639 - "xh" : "isiXhosa",
640 - "xmf" : "\u10db\u10d0\u10e0\u10d2\u10d0\u10da\u10e3\u10e0\u10d8",
641 - "yi" : "\u05d9\u05d9\u05b4\u05d3\u05d9\u05e9",
642 - "yo" : "Yor\u00f9b\u00e1",
643 - "yue" : "\u7cb5\u8a9e",
644 - "za" : "Vahcuengh",
645 - "zea" : "Ze\u00eauws",
646 - "zh" : "\u4e2d\u6587",
647 - "zh-classical" : "\u6587\u8a00",
648 - "zh-cn" : "\u202a\u4e2d\u6587(\u4e2d\u56fd\u5927\u9646)\u202c",
649 - "zh-hans" : "\u202a\u4e2d\u6587(\u7b80\u4f53)\u202c",
650 - "zh-hant" : "\u202a\u4e2d\u6587(\u7e41\u9ad4)\u202c",
651 - "zh-hk" : "\u202a\u4e2d\u6587(\u9999\u6e2f)\u202c",
652 - "zh-min-nan" : "B\u00e2n-l\u00e2m-g\u00fa",
653 - "zh-mo" : "\u202a\u4e2d\u6587(\u6fb3\u9580)\u202c",
654 - "zh-my" : "\u202a\u4e2d\u6587(\u9a6c\u6765\u897f\u4e9a)\u202c",
655 - "zh-sg" : "\u202a\u4e2d\u6587(\u65b0\u52a0\u5761)\u202c",
656 - "zh-tw" : "\u202a\u4e2d\u6587(\u53f0\u7063)\u202c",
657 - "zh-yue" : "\u7cb5\u8a9e",
658 - "zu" : "isiZulu"
659 - };
660 -
661 - // Language classes ( has a file in /languages/classes/Language{code}.js )
662 - // ( for languages that override default transforms )
663 - mw.Language.transformClass = ['am', 'ar', 'bat_smg', 'be_tarak', 'be', 'bh',
664 - 'bs', 'cs', 'cu', 'cy', 'dsb', 'fr', 'ga', 'gd', 'gv', 'he', 'hi',
665 - 'hr', 'hsb', 'hy', 'ksh', 'ln', 'lt', 'lv', 'mg', 'mk', 'mo', 'mt',
666 - 'nso', 'pl', 'pt_br', 'ro', 'ru', 'se', 'sh', 'sk', 'sl', 'sma',
667 - 'sr_ec', 'sr_el', 'sr', 'ti', 'tl', 'uk', 'wa'
668 - ];
669 -
670 - // Language fallbacks listed from language -> fallback language
671 - mw.Language.fallbackTransformMap = {
672 - 'mwl' : 'pt',
673 - 'ace' : 'id',
674 - 'hsb' : 'de',
675 - 'frr' : 'de',
676 - 'pms' : 'it',
677 - 'dsb' : 'de',
678 - 'gan' : 'gan-hant',
679 - 'lzz' : 'tr',
680 - 'ksh' : 'de',
681 - 'kl' : 'da',
682 - 'fur' : 'it',
683 - 'zh-hk' : 'zh-hant',
684 - 'kk' : 'kk-cyrl',
685 - 'zh-my' : 'zh-sg',
686 - 'nah' : 'es',
687 - 'sr' : 'sr-ec',
688 - 'ckb-latn' : 'ckb-arab',
689 - 'mo' : 'ro',
690 - 'ay' : 'es',
691 - 'gl' : 'pt',
692 - 'gag' : 'tr',
693 - 'mzn' : 'fa',
694 - 'ruq-cyrl' : 'mk',
695 - 'kk-arab' : 'kk-cyrl',
696 - 'pfl' : 'de',
697 - 'zh-yue' : 'yue',
698 - 'ug' : 'ug-latn',
699 - 'ltg' : 'lv',
700 - 'nds' : 'de',
701 - 'sli' : 'de',
702 - 'mhr' : 'ru',
703 - 'sah' : 'ru',
704 - 'ff' : 'fr',
705 - 'ab' : 'ru',
706 - 'ko-kp' : 'ko',
707 - 'sg' : 'fr',
708 - 'zh-tw' : 'zh-hant',
709 - 'map-bms' : 'jv',
710 - 'av' : 'ru',
711 - 'nds-nl' : 'nl',
712 - 'pt-br' : 'pt',
713 - 'ce' : 'ru',
714 - 'vep' : 'et',
715 - 'wuu' : 'zh-hans',
716 - 'pdt' : 'de',
717 - 'krc' : 'ru',
718 - 'gan-hant' : 'zh-hant',
719 - 'bqi' : 'fa',
720 - 'as' : 'bn',
721 - 'bm' : 'fr',
722 - 'gn' : 'es',
723 - 'tt' : 'ru',
724 - 'zh-hant' : 'zh-hans',
725 - 'hif' : 'hif-latn',
726 - 'zh' : 'zh-hans',
727 - 'kaa' : 'kk-latn',
728 - 'lij' : 'it',
729 - 'vot' : 'fi',
730 - 'ii' : 'zh-cn',
731 - 'ku-arab' : 'ckb-arab',
732 - 'xmf' : 'ka',
733 - 'vmf' : 'de',
734 - 'zh-min-nan' : 'nan',
735 - 'bcc' : 'fa',
736 - 'an' : 'es',
737 - 'rgn' : 'it',
738 - 'qu' : 'es',
739 - 'nb' : 'no',
740 - 'bar' : 'de',
741 - 'lbe' : 'ru',
742 - 'su' : 'id',
743 - 'pcd' : 'fr',
744 - 'glk' : 'fa',
745 - 'lb' : 'de',
746 - 'kk-kz' : 'kk-cyrl',
747 - 'kk-tr' : 'kk-latn',
748 - 'inh' : 'ru',
749 - 'mai' : 'hi',
750 - 'tp' : 'tokipona',
751 - 'kk-latn' : 'kk-cyrl',
752 - 'ba' : 'ru',
753 - 'nap' : 'it',
754 - 'ruq' : 'ruq-latn',
755 - 'tt-cyrl' : 'ru',
756 - 'lad' : 'es',
757 - 'dk' : 'da',
758 - 'de-ch' : 'de',
759 - 'be-x-old' : 'be-tarask',
760 - 'za' : 'zh-hans',
761 - 'kk-cn' : 'kk-arab',
762 - 'shi' : 'ar',
763 - 'crh' : 'crh-latn',
764 - 'yi' : 'he',
765 - 'pdc' : 'de',
766 - 'eml' : 'it',
767 - 'uk' : 'ru',
768 - 'kv' : 'ru',
769 - 'koi' : 'ru',
770 - 'cv' : 'ru',
771 - 'zh-cn' : 'zh-hans',
772 - 'de-at' : 'de',
773 - 'jut' : 'da',
774 - 'vec' : 'it',
775 - 'zh-mo' : 'zh-hk',
776 - 'fiu-vro' : 'vro',
777 - 'frp' : 'fr',
778 - 'mg' : 'fr',
779 - 'ruq-latn' : 'ro',
780 - 'sa' : 'hi',
781 - 'lmo' : 'it',
782 - 'kiu' : 'tr',
783 - 'tcy' : 'kn',
784 - 'srn' : 'nl',
785 - 'jv' : 'id',
786 - 'vls' : 'nl',
787 - 'zea' : 'nl',
788 - 'ty' : 'fr',
789 - 'szl' : 'pl',
790 - 'rmy' : 'ro',
791 - 'wo' : 'fr',
792 - 'vro' : 'et',
793 - 'udm' : 'ru',
794 - 'bpy' : 'bn',
795 - 'mrj' : 'ru',
796 - 'ckb' : 'ckb-arab',
797 - 'xal' : 'ru',
798 - 'de-formal' : 'de',
799 - 'myv' : 'ru',
800 - 'ku' : 'ku-latn',
801 - 'crh-cyrl' : 'ru',
802 - 'gsw' : 'de',
803 - 'rue' : 'uk',
804 - 'iu' : 'ike-cans',
805 - 'stq' : 'de',
806 - 'gan-hans' : 'zh-hans',
807 - 'scn' : 'it',
808 - 'arn' : 'es',
809 - 'ht' : 'fr',
810 - 'zh-sg' : 'zh-hans',
811 - 'bat-smg' : 'lt',
812 - 'aln' : 'sq',
813 - 'tg' : 'tg-cyrl',
814 - 'li' : 'nl',
815 - 'simple' : 'en',
816 - 'os' : 'ru',
817 - 'ln' : 'fr',
818 - 'als' : 'gsw',
819 - 'zh-classical' : 'lzh',
820 - 'arz' : 'ar',
821 - 'wa' : 'fr'
822 - };
823 -
824 - /**
825 - * Plural form transformations, needed for some languages.
826 - * For example, there are 3 form of plural in Russian and Polish,
827 - * depending on "count mod 10". See [[w:Plural]]
828 - * For English it is pretty simple.
829 - *
830 - * Invoked by putting {{plural:count|wordform1|wordform2}}
831 - * or {{plural:count|wordform1|wordform2|wordform3}}
832 - *
833 - * Example: {{plural:{{NUMBEROFARTICLES}}|article|articles}}
834 - *
835 - * @param count Integer: non-localized number
836 - * @param forms Array: different plural forms
837 - * @return string Correct form of plural for count in this language
838 - */
839 -
840 - /**
841 - * Base gender transform function
842 - */
843 - mw.Language.gender = function( gender, forms ) {
844 - if ( ! forms.length ) {
845 - return '';
846 - }
847 - forms = mw.Language.preConvertPlural( forms, 2 );
848 - if ( gender === 'male' ) return forms[0];
849 - if ( gender === 'female' ) return forms[1];
850 - return ( forms[2] ) ? forms[2] : forms[0];
851 - };
852 -
853 - /**
854 - * Process the PLURAL template substitution
855 - * @param {Object} template Template object
856 - *
857 - * {{Template:argument|params}}
858 - *
859 - * Template object should include:
860 - * [arg] The argument sent to the template
861 - * [params] The template parameters
862 - */
863 - mw.Language.procPLURAL = function( templateObject ) {
864 - // Setup shortcuts
865 - // ( gRuleSet is loaded from script-loader to contains local ruleset )
866 - var rs = gRuleSet[ 'PLURAL' ];
867 -
868 - if( templateObject.arg && templateObject.param && mw.Language.convertPlural) {
869 - // Check if we have forms to replace
870 - if ( templateObject.param.length == 0 ) {
871 - return '';
872 - }
873 - // Restore the count into a Number ( if it got converted earlier )
874 - var count = mw.Language.convertNumber( templateObject.arg, true );
875 -
876 - // Do convertPlural call
877 - return mw.Language.convertPlural( parseInt( count ), templateObject.param );
878 -
879 - }
880 - // Could not process plural return first form or nothing
881 - if( templateObject.param[0] ) {
882 - return templateObject.param[0];
883 - }
884 - return '';
885 - };
886 -
887 - // NOTE:: add gender support here
888 - mw.Language.procGENDER = function( templateObject ){
889 - return 'gender-not-supported-in-js-yet';
890 - }
891 - /*
892 - * Base convertPlural function:
893 - */
894 - mw.Language.convertPlural = function( count, forms ){
895 - if ( !forms || forms.length == 0 ) {
896 - return '';
897 - }
898 - return ( parseInt( count ) == 1 ) ? forms[0] : forms[1];
899 - };
900 - /**
901 - * Checks that convertPlural was given an array and pads it to requested
902 - * amount of forms by copying the last one.
903 - *
904 - * @param {Array} forms Forms given to convertPlural
905 - * @param {Integer} count How many forms should there be at least
906 - * @return {Array} Padded array of forms or an exception if not an array
907 - */
908 - mw.Language.preConvertPlural = function( forms, count ) {
909 - while ( forms.length < count ) {
910 - forms.push( forms[ forms.length-1 ] );
911 - }
912 - return forms;
913 - };
914 -
915 - /**
916 - * Init the digitTransformTable ( populated by language classes where applicable )
917 - */
918 - mw.Language.digitTransformTable = null;
919 -
920 - /**
921 - * Convert a number using the digitTransformTable
922 - * @param Number number to be converted
923 - * @param Bollean typeInt if we should return a number of type int
924 - */
925 - mw.Language.convertNumber = function( number, typeInt ) {
926 - if( !mw.Language.digitTransformTable )
927 - return number;
928 -
929 - // Set the target Transform table:
930 - var transformTable = mw.Language.digitTransformTable;
931 -
932 - // Check if the "restore" to latin number flag is set:
933 - if( typeInt ) {
934 - if( parseInt( number ) == number )
935 - return number;
936 - var tmp = [];
937 - for( var i in transformTable ) {
938 - tmp[ transformTable[ i ] ] = i;
939 - }
940 - transformTable = tmp;
941 - }
942 -
943 - var numberString = '' + number;
944 - var convertedNumber = '';
945 - for( var i =0; i < numberString.length; i++) {
946 - if( transformTable[ numberString[i] ] ) {
947 - convertedNumber += transformTable[ numberString[i] ];
948 - }else{
949 - convertedNumber += numberString[i];
950 - }
951 - }
952 - return ( typeInt )? parseInt( convertedNumber) : convertedNumber;
953 - }
954 -
955 - /**
956 - * Checks if a language key is valid ( is part of languageCodeList )
957 - * @param {String} langKey Language key to be checked
958 - * @return true if valid language, false if not
959 - */
960 - mw.isValidLang = function( langKey ) {
961 - return ( mw.Language.names[ langKey ] )? true : false;
962 - }
963 -
964 - /**
965 - * Get a language transform key
966 - * returns default "en" fallback if none found
967 - * @param String langKey The language key to be checked
968 - */
969 - mw.getLangTransformKey = function( langKey ) {
970 - if( mw.Language.fallbackTransformMap[ langKey ] ) {
971 - langKey = mw.Language.fallbackTransformMap[ langKey ];
972 - }
973 - // Make sure the langKey has a transformClass:
974 - for( var i = 0; i < mw.Language.transformClass.length ; i++ ) {
975 - if( langKey == mw.Language.transformClass[i] ){
976 - return langKey
977 - }
978 - }
979 - // By default return the base 'en' class
980 - return 'en';
981 - }
982 -
983 - /**
984 - * getRemoteMsg loads remote msg strings
985 - *
986 - * @param {Mixed} msgSet the set of msg to load remotely
987 - * @param function callback the callback to issue once string is ready
988 - */
989 - mw.getRemoteMsg = function( msgSet, callback ) {
990 - var ammessages = '';
991 - if ( typeof msgSet == 'object' ) {
992 - for ( var i in msgSet ) {
993 - if( !messageCache[ i ] ) {
994 - ammessages += msgSet[i] + '|';
995 - }
996 - }
997 - } else if ( typeof msgSet == 'string' ) {
998 - if( !messageCache[ i ] ) {
999 - ammessages += msgSet;
1000 - }
1001 - }
1002 - if ( ammessages == '' ) {
1003 - mw.log( 'no remote msgs to get' );
1004 - callback();
1005 - return false;
1006 - }
1007 - var request = {
1008 - 'meta': 'allmessages',
1009 - 'ammessages': ammessages
1010 - }
1011 - mw.getJSON( request, function( data ) {
1012 - if ( data.query.allmessages ) {
1013 - var msgs = data.query.allmessages;
1014 - for ( var i in msgs ) {
1015 - var ld = { };
1016 - ld[ msgs[i]['name'] ] = msgs[i]['*'];
1017 - mw.addMessages( ld );
1018 - }
1019 - }
1020 - callback();
1021 - } );
1022 - }
1023 -
1024 - /**
1025 - * Format a size in bytes for output, using an appropriate
1026 - * unit (B, KB, MB or GB) according to the magnitude in question
1027 - *
1028 - * @param size Size to format
1029 - * @return string Plain text (not HTML)
1030 - */
1031 - mw.Language.formatSize = function ( size ) {
1032 - // For small sizes no decimal places are necessary
1033 - var round = 0;
1034 - var msg = '';
1035 - if ( size > 1024 ) {
1036 - size = size / 1024;
1037 - if ( size > 1024 ) {
1038 - size = size / 1024;
1039 - // For MB and bigger two decimal places are smarter
1040 - round = 2;
1041 - if ( size > 1024 ) {
1042 - size = size / 1024;
1043 - msg = 'mwe-size-gigabytes';
1044 - } else {
1045 - msg = 'mwe-size-megabytes';
1046 - }
1047 - } else {
1048 - msg = 'mwe-size-kilobytes';
1049 - }
1050 - } else {
1051 - msg = 'mwe-size-bytes';
1052 - }
1053 - // JavaScript does not let you choose the precision when rounding
1054 - var p = Math.pow( 10, round );
1055 - size = Math.round( size * p ) / p;
1056 - return gM( msg , size );
1057 - };
1058 -
1059 - /**
1060 - * Format a number
1061 - * @param {Number} num Number to be formated
1062 - * NOTE: add il8n support to lanuages/class/Language{langCode}.js
1063 - */
1064 - mw.Language.formatNumber = function( num ) {
1065 - /*
1066 - * addSeparatorsNF
1067 - * @param Str: The number to be formatted, as a string or number.
1068 - * @param outD: The decimal character for the output, such as ',' for the number 100,2
1069 - * @param sep: The separator character for the output, such as ',' for the number 1,000.2
1070 - */
1071 - function addSeparatorsNF( nStr, outD, sep ) {
1072 - nStr += '';
1073 - var dpos = nStr.indexOf( '.' );
1074 - var nStrEnd = '';
1075 - if ( dpos != -1 ) {
1076 - nStrEnd = outD + nStr.substring( dpos + 1, nStr.length );
1077 - nStr = nStr.substring( 0, dpos );
1078 - }
1079 - var rgx = /(\d+)(\d{3})/;
1080 - while ( rgx.test( nStr ) ) {
1081 - nStr = nStr.replace( rgx, '$1' + sep + '$2' );
1082 - }
1083 - return nStr + nStrEnd;
1084 - }
1085 - // @@todo read language code and give periods or comas:
1086 - return addSeparatorsNF( num, '.', ',' );
1087 - }
1088 -
1089 -}) ( window.mw );
1090 -
1091 -
1092 -// Load in js2 stopgap global msgs into proper location:
1093 -if ( typeof gMsg != 'undefined' ) {
1094 - mw.addMessages( gMsg )
1095 -}
1096 -
1097 -// Set global gM shortcut:
1098 -window[ 'gM' ] = mw.getMsg;
1099 -
1100 -
1101 -/**
1102 -* Add the core mvEmbed Messages ( will be localized by script server )
1103 -*/
1104 -mw.addMessages( {
1105 - "mwe-loading_txt" : "Loading ...",
1106 - "mwe-size-gigabytes" : "$1 GB",
1107 - "mwe-size-megabytes" : "$1 MB",
1108 - "mwe-size-kilobytes" : "$1 K",
1109 - "mwe-size-bytes" : "$1 B",
1110 - "mwe-error_load_lib" : "Error: JavaScript $1 was not retrievable or does not define $2",
1111 - "mwe-apiproxy-setup" : "Setting up API proxy",
1112 - "mwe-load-drag-item" : "Loading dragged item",
1113 - "mwe-ok" : "OK",
1114 - "mwe-cancel" : "Cancel",
1115 - "mwe-enable-gadget" : "Enable multimedia beta ( mwEmbed ) for all pages",
1116 - "mwe-enable-gadget-done" : "multimedia beta gadget has been enabled",
1117 - "mwe-must-login-gadget" : "To enable gadget you must <a target=\"_new\" href=\"$1\">login</a>",
1118 - "mwe-test-plural" : "I ran {{PLURAL:$1|$1 test|$1 tests}}"
1119 -} );
\ No newline at end of file
Index: branches/MwEmbedStandAlone/languages/mw.Parser.js
@@ -1,323 +0,0 @@
2 -/**
3 -* Mediawiki language text parser
4 -*/
5 -
6 -// Setup swap string constants
7 -var JQUERY_SWAP_STRING = 'ZjQuerySwapZ';
8 -var LINK_SWAP_STRING = 'ZreplaceZ';
9 -
10 -( function( mw ) {
11 -
12 - // The parser magic global
13 - var pMagicSet = { };
14 -
15 - /**
16 - * addTemplateTransform to the parser
17 - *
18 - * Lets you add a set template key to be transformed by a callback function
19 - *
20 - * @param {Object} magicSet key:callback
21 - */
22 - mw.addTemplateTransform = function( magicSet ) {
23 - for ( var i in magicSet ) {
24 - pMagicSet[ i ] = magicSet[i];
25 - }
26 - };
27 -
28 - /**
29 - * MediaWiki wikitext "Parser" constructor
30 - *
31 - * @param {String} wikiText the wikitext to be parsed
32 - * @return {Object} parserObj returns a parser object that has methods for getting at
33 - * things you would want
34 - */
35 - mw.Parser = function( wikiText, options) {
36 - // return the parserObj
37 - this.init( wikiText, options ) ;
38 - };
39 -
40 - mw.Parser.prototype = {
41 -
42 - // the parser output string container
43 - pOut: false,
44 -
45 - init: function( wikiText, parserOptions ) {
46 - this.wikiText = wikiText;
47 - },
48 -
49 - // Update the text value
50 - updateText : function( wikiText ) {
51 - this.wikiText = wikiText;
52 -
53 - // invalidate the output ( will force a re-parse )
54 - this.pOut = false;
55 - },
56 -
57 - /**
58 - * Quickly recursive / parse out templates:
59 - */
60 - parse: function() {
61 - function recurseTokenizeNodes ( text ) {
62 - var node = { };
63 - // Inspect each char
64 - for ( var a = 0; a < text.length; a++ ) {
65 - if ( text[a] == '{' && text[a + 1] == '{' ) {
66 - a = a + 2;
67 - node['parent'] = node;
68 - if ( !node['child'] ) {
69 - node['child'] = new Array();
70 - }
71 -
72 - node['child'].push( recurseTokenizeNodes( text.substr( a ) ) );
73 - } else if ( text[a] == '}' && text[a + 1] == '}' ) {
74 - a++;
75 - if ( !node['parent'] ) {
76 - return node;
77 - }
78 - node = node['parent'];
79 - }
80 - if ( !node['text'] ) {
81 - node['text'] = '';
82 - }
83 - // Don't put }} closures into output:
84 - if ( text[a] && text[a] != '}' ) {
85 - node['text'] += text[a];
86 - }
87 - }
88 - return node;
89 - }
90 -
91 - /**
92 - * Parse template text as template name and named params
93 - * @param {String} templateString Template String to be parsed
94 - */
95 - function parseTmplTxt( templateString ) {
96 - var templateObject = { };
97 -
98 - // Get template name:
99 - templateName = templateString.split( '\|' ).shift() ;
100 - templateName = templateName.split( '\{' ).shift() ;
101 - templateName = templateName.replace( /^\s+|\s+$/g, "" ); //trim
102 -
103 - // Check for arguments:
104 - if ( templateName.split( ':' ).length == 1 ) {
105 - templateObject["name"] = templateName;
106 - } else {
107 - templateObject["name"] = templateName.split( ':' ).shift();
108 - templateObject["arg"] = templateName.split( ':' ).pop();
109 - }
110 -
111 - var paramSet = templateString.split( '\|' );
112 - paramSet.splice( 0, 1 );
113 - if ( paramSet.length ) {
114 - templateObject.param = new Array();
115 - for ( var pInx in paramSet ) {
116 - var paramString = paramSet[ pInx ];
117 - // check for empty param
118 - if ( paramString == '' ) {
119 - templateObject.param[ pInx ] = '';
120 - continue;
121 - }
122 - for ( var b = 0 ; b < paramString.length ; b++ ) {
123 - if ( paramString[b] == '=' && b > 0 && b < paramString.length && paramString[b - 1] != '\\' ) {
124 - // named param
125 - templateObject.param[ paramString.split( '=' ).shift() ] = paramString.split( '=' ).pop();
126 - } else {
127 - // indexed param
128 - templateObject.param[ pInx ] = paramString;
129 - }
130 - }
131 - }
132 - }
133 - return templateObject;
134 - }
135 -
136 - /**
137 - * Get the Magic text from a template node
138 - */
139 - function getMagicTxtFromTempNode( node ) {
140 - node.templateObject = parseTmplTxt ( node.text );
141 - // Do magic swap if template key found in pMagicSet
142 - if ( node.templateObject.name in pMagicSet ) {
143 - var nodeText = pMagicSet[ node.templateObject.name ]( node.templateObject );
144 - return nodeText;
145 - } else {
146 - // don't swap just return text
147 - return node.text;
148 - }
149 - }
150 -
151 - /**
152 - * swap links of form [ ] for html a links or jquery helper spans
153 - * NOTE: this could be integrated into the tokenizer but for now
154 - * is a staged process.
155 - *
156 - * @param text to swapped
157 - */
158 - function linkSwapText( text ) {
159 - //mw.log( "linkSwapText::" + text );
160 - var re = new RegExp( /\[([^\s]+[\s]+[^\]]*)\]/g );
161 - var matchSet = text.match( re );
162 -
163 - if( !matchSet ){
164 - return text;
165 - }
166 -
167 - text = text.replace( re , LINK_SWAP_STRING );
168 -
169 - for( var i=0; i < matchSet.length; i++ ) {
170 - // Strip the leading [ and trailing ]
171 - var matchParts = matchSet[i].substr(1, matchSet[i].length-2);
172 -
173 - // Check for special jQuery type swap and replace inner JQUERY_SWAP_STRING not value
174 - if( matchParts.indexOf( JQUERY_SWAP_STRING ) !== -1 ) {
175 - // parse the link as html
176 - var $matchParts = $j('<span>' + matchParts + '</span>' );
177 -
178 - $jQuerySpan = $matchParts.find('#' +JQUERY_SWAP_STRING + i );
179 -
180 - var linkText = $matchParts.text();
181 - //mw.log(" going to swap in linktext: " + linkText );
182 - $jQuerySpan.text( linkText );
183 -
184 - text = text.replace( LINK_SWAP_STRING, $j('<span />' ).append( $jQuerySpan ).html() );
185 - } else {
186 - // do text string replace
187 - matchParts = matchParts.split(/ /);
188 - var link = matchParts[0];
189 - matchParts.shift();
190 - var linkText = matchParts.join(' ');
191 -
192 - text = text.replace( LINK_SWAP_STRING, '<a href="' + link + '">' + linkText + '</a>' );
193 - }
194 - }
195 - return text;
196 - }
197 -
198 - /**
199 - * recurse_magic_swap
200 - *
201 - * Go last child first swap upward:
202 - */
203 - var pNode = null;
204 - function recurse_magic_swap( node ) {
205 - if ( !pNode )
206 - pNode = node;
207 -
208 - if ( node['child'] ) {
209 - // swap all the kids:
210 - for ( var i in node['child'] ) {
211 - var nodeText = recurse_magic_swap( node['child'][i] );
212 - // swap it into current
213 - if ( node.text ) {
214 - node.text = node.text.replace( node['child'][i].text, nodeText );
215 - }
216 - // swap into parent
217 - pNode.text = pNode.text.replace( node['child'][i].text, nodeText );
218 - }
219 - // Get the updated node text
220 - var nodeText = getMagicTxtFromTempNode( node );
221 - pNode.text = pNode.text.replace( node.text , nodeText );
222 - // return the node text
223 - return node.text;
224 - } else {
225 - return getMagicTxtFromTempNode( node );
226 - }
227 - }
228 -
229 - // Parse out the template node structure:
230 - this.pNode = recurseTokenizeNodes ( this.wikiText );
231 -
232 - // Strip out the parent from the root
233 - this.pNode['parent'] = null;
234 -
235 - // Do the recursive magic swap text:
236 - this.pOut = recurse_magic_swap( this.pNode );
237 -
238 - // Do link swap
239 - this.pOut = linkSwapText( this.pOut );
240 - },
241 -
242 - /**
243 - * templates
244 - *
245 - * Get a requested template from the wikitext (if available)
246 - * @param templateName
247 - */
248 - templates: function( templateName ) {
249 - this.parse();
250 - var tmplSet = new Array();
251 - function getMatchingTmpl( node ) {
252 - if ( node['child'] ) {
253 - for ( var i in node['child'] ) {
254 - getMatchingTmpl( node['child'] );
255 - }
256 - }
257 - if ( templateName && node.templateObject ) {
258 - if ( node.templateObject['name'] == templateName )
259 - tmplSet.push( node.templateObject );
260 - } else if ( node.templateObject ) {
261 - tmplSet.push( node.templateObject );
262 - }
263 - }
264 - getMatchingTmpl( this.pNode );
265 - return tmplSet;
266 - },
267 -
268 - /**
269 - * getTemplateVars
270 - * returns a set of template values in a given wikitext page
271 - *
272 - * NOTE: should be integrated with the usability wikitext parser
273 - */
274 - getTemplateVars: function() {
275 - //mw.log('matching against: ' + wikiText);
276 - templateVars = new Array();
277 - var tempVars = wikiText.match(/\{\{\{([^\}]*)\}\}\}/gi);
278 -
279 - // Clean up results:
280 - for(var i=0; i < tempVars.length; i++) {
281 - //match
282 - var tvar = tempVars[i].replace('{{{','').replace('}}}','');
283 -
284 - // Strip anything after a |
285 - if(tvar.indexOf('|') != -1) {
286 - tvar = tvar.substr(0, tvar.indexOf('|'));
287 - }
288 -
289 - // Check for duplicates:
290 - var do_add=true;
291 - for(var j=0; j < templateVars.length; j++) {
292 - if( templateVars[j] == tvar)
293 - do_add=false;
294 - }
295 -
296 - // Add the template vars to the output obj
297 - if(do_add)
298 - templateVars.push( tvar );
299 - }
300 - return templateVars;
301 - },
302 -
303 - /**
304 - * Returns the transformed wikitext
305 - *
306 - * Build output from swappable index
307 - * (all transforms must be expanded in parse stage and linearly rebuilt)
308 - * Alternatively we could build output using a place-holder & replace system
309 - * (this lets us be slightly more sloppy with ordering and indexes, but probably slower)
310 - *
311 - * Ideal: we build a 'wiki DOM'
312 - * When editing you update the data structure directly
313 - * Then in output time you just go DOM->html-ish output without re-parsing anything
314 - */
315 - getHTML: function() {
316 - // wikiText updates should invalidate pOut
317 - if ( ! this.pOut ) {
318 - this.parse();
319 - }
320 - return this.pOut;
321 - }
322 - };
323 -
324 -}) ( window.mw );
\ No newline at end of file
Index: branches/MwEmbedStandAlone/languages/README
@@ -1,10 +1,3 @@
2 -Developers should not modify the contents of mwEmbed.i18n.php directly.
 2+These language classes have been ported from the php mediaWiki language classes.
33
4 -mwEmbed.i18n.php is updated by maintenance scripts.
5 -
6 -Two scripts write to this file:
7 -* mwEmbed/includes/maintenance/mergeJavascriptMsg.php
8 -Copies English messages from every mwEmbed javascript module
9 -
10 -* Translate wiki script
11 -Copies the translate wiki localised msgs into the file.
\ No newline at end of file
 4+For testing see JS2Support extension that compares javascript output to mediawiki output
Index: branches/MwEmbedStandAlone/modules/TimedText/tests/Player_Timed_Text.html
@@ -0,0 +1,182 @@
 2+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 3+"http://www.w3.org/TR/html4/loose.dtd">
 4+<html>
 5+<head>
 6+ <title>sample mv embed</title>
 7+ <!-- <script type="text/javascript" src="../../../mwEmbed.js?debug=true"></script> -->
 8+ <script type="text/javascript" src="../../../ResourceLoader.php?class=window.jQuery,mwEmbed&debug=true"></script>
 9+ <script type="text/javascript">
 10+ $j( document ).ready(function(){
 11+ $j('#inlineTracksTextArea').text(
 12+ $j.trim( $j('#inlineTracks').html() )
 13+ );
 14+ $j('#apiExampleTextArea').text(
 15+ $j.trim( $j('#apiExample').html() )
 16+ )
 17+ });
 18+
 19+ </script>
 20+</head>
 21+<body>
 22+<h3> mwEmbed Timed Text Examples:</h3>
 23+Click on the little lower right "CC" icon to expose the timed text
 24+ <table border="1" cellpadding="6" width="950">
 25+
 26+ <tr>
 27+ <td id="apiExample" valign="top" width="410">
 28+ <video
 29+ style="width:512px;height:288px"
 30+ durationHint="7:52"
 31+ apiTitleKey="Yochai_Benkler_-_On_Autonomy,_Control_and_Cultural_Experience.ogg"
 32+ apiProvider="commons"
 33+ class="kskin"></video>
 34+ <td valign="top">
 35+ Commons Video API based timedText discovery<br>
 36+
 37+ <textarea id="apiExampleTextArea" style="width:600px;height:180px"></textarea>
 38+ </td>
 39+ </tr>
 40+
 41+
 42+ <tr>
 43+ <td id="inlineTracks" valign="top" width="410">
 44+
 45+ <video style="width:544px;height:304px;"
 46+ poster="http://upload.wikimedia.org/wikipedia/commons/thumb/b/bd/Elephants_Dream.ogg/seek%3D13-Elephants_Dream.ogg.jpg"
 47+ duration="10:53"
 48+ linkback="http://www.elephantsdream.org/" >
 49+ <source type="video/ogg" src="http://upload.wikimedia.org/wikipedia/commons/b/bd/Elephants_Dream.ogg" ></source>
 50+ <source type="video/h264" src="http://www.archive.org/download/ElephantsDream/ed_1024_512kb.mp4"></source>
 51+
 52+
 53+ <!-- Subtitles -->
 54+
 55+ <track kind="subtitles" id="video_af" srclang="af"
 56+ src="media/elephants_dream/elephant.afrikaans.srt"></track>
 57+
 58+ <track kind="subtitles" id="video_ar" srclang="ar"
 59+ src="media/elephants_dream/elephant.arabic.srt"></track>
 60+
 61+ <track kind="subtitles" id="video_bn" srclang="bn"
 62+ src="media/elephants_dream/elephant.bangla.srt"></track>
 63+
 64+ <track kind="subtitles" id="video_br" srclang="br"
 65+ src="media/elephants_dream/elephant.breton.srt"></track>
 66+
 67+ <track kind="subtitles" id="video_bg" srclang="bg"
 68+ src="media/elephants_dream/elephant.bulgarian.srt"></track>
 69+
 70+ <track kind="subtitles" id="video_ca" srclang="ca"
 71+ src="media/elephants_dream/elephant.catalan-utf8.srt"></track>
 72+
 73+ <track kind="subtitles" id="video_zh" srclang="zh"
 74+ src="media/elephants_dream/elephant.chinese.srt"></track>
 75+
 76+ <track kind="subtitles" id="video_cz" srclang="cs"
 77+ src="media/elephants_dream/elephant.czech.srt"></track>
 78+
 79+ <track kind="subtitles" id="video_da" srclang="da"
 80+ src="media/elephants_dream/elephant.danish.srt"></track>
 81+
 82+ <track kind="subtitles" id="video_nl" srclang="nl"
 83+ src="media/elephants_dream/elephant.dutch.srt"></track>
 84+
 85+ <track kind="subtitles" id="video_en" srclang="en"
 86+ src="media/elephants_dream/elephant.english.srt"></track>
 87+
 88+ <track kind="subtitles" id="video_et" srclang="et"
 89+ src="media/elephants_dream/elephant.estonian.srt"></track>
 90+
 91+ <track kind="subtitles" id="video_fi" srclang="fi"
 92+ src="media/elephants_dream/elephant.finnish.srt"></track>
 93+
 94+ <track kind="subtitles" id="video_fr" srclang="fr"
 95+ src="media/elephants_dream/elephant.french.srt"></track>
 96+
 97+ <track kind="subtitles" id="video_de" srclang="de"
 98+ src="media/elephants_dream/elephant.german.srt"></track>
 99+
 100+ <track kind="subtitles" id="video_el" srclang="el"
 101+ src="media/elephants_dream/elephant.greek.srt"></track>
 102+
 103+ <track kind="subtitles" id="video_he" srclang="he"
 104+ src="media/elephants_dream/elephant.hebrew.srt"></track>
 105+
 106+ <track kind="subtitles" id="video_hu" srclang="hu"
 107+ src="media/elephants_dream/elephant.hungarian-utf8.srt"></track>
 108+
 109+ <track kind="subtitles" id="video_it" srclang="it"
 110+ src="media/elephants_dream/elephant.italian.srt"></track>
 111+
 112+ <track kind="subtitles" id="video_ja" srclang="ja"
 113+ src="media/elephants_dream/elephant.japanese.srt"></track>
 114+
 115+ <track kind="subtitles" id="video_ja" srclang="ja"
 116+ src="media/elephants_dream/elephant.japanese-euc.srt"></track>
 117+
 118+ <track kind="subtitles" id="video_mt" srclang="mt"
 119+ src="media/elephants_dream/elephant.maltese_utf8.srt"></track>
 120+
 121+ <track kind="subtitles" id="video_nn" srclang="nn"
 122+ src="media/elephants_dream/elephant.norwegian.srt"></track>
 123+
 124+ <track kind="subtitles" id="video_pl" srclang="pl"
 125+ src="media/elephants_dream/elephant.polish.srt"></track>
 126+
 127+ <track kind="subtitles" id="video_pt" srclang="pt"
 128+ src="media/elephants_dream/elephant.portuguese.srt"></track>
 129+
 130+ <track kind="subtitles" id="video_pt_br" srclang="pt-br"
 131+ src="media/elephants_dream/elephant.brazilian.srt"></track>
 132+
 133+ <track kind="subtitles" id="video_ro" srclang="ro"
 134+ src="media/elephants_dream/elephant.romanian.srt"></track>
 135+
 136+ <track kind="subtitles" id="video_ru" srclang="ru"
 137+ src="media/elephants_dream/elephant.russian.srt"></track>
 138+
 139+
 140+ <!-- Captions -->
 141+ <track kind="captions" id="video_sl" srclang="sl"
 142+ src="media/elephants_dream/elephant.slovenian.srt"></track>
 143+
 144+ <track kind="captions" id="video_es" srclang="es"
 145+ src="media/elephants_dream/elephant.spanish.srt"></track>
 146+
 147+ <track kind="captions" id="video_es_mx" srclang="es-mx"
 148+ src="media/elephants_dream/elephant.spanish-us.srt"></track>
 149+
 150+ <track kind="captions" id="video_sk" srclang="sk"
 151+ src="media/elephants_dream/elephant.slovak.srt"></track>
 152+
 153+ <track kind="captions" id="video_sv" srclang="sv"
 154+ src="media/elephants_dream/elephant.swedish.srt"></track>
 155+
 156+
 157+ <!-- Audio Description -->
 158+ <track kind="descriptions" id="audiodesc" srclang="en"
 159+ src="media/elephants_dream/audiodescription.srt"></track>
 160+
 161+ <!-- Chapters -->
 162+ <track kind="chapters" id="chapters" srclang="en" label="Chapters"
 163+ src="media/elephants_dream/chapters.srt"></track>
 164+
 165+ </video>
 166+
 167+ </td>
 168+
 169+ <td valign="top">
 170+ <h4>Text track inline embed example</h4>
 171+ see: <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#the-track-element">HTML5 timed text spec</a>
 172+ <br><textarea id="inlineTracksTextArea" style="width:600px;height:180px">
 173+
 174+ </textarea>
 175+ </td>
 176+ </tr>
 177+
 178+
 179+ </table>
 180+
 181+</body>
 182+</html>
 183+
Property changes on: branches/MwEmbedStandAlone/modules/TimedText/tests/Player_Timed_Text.html
___________________________________________________________________
Name: svn:mergeinfo
1184 + /branches/REL1_15/phase3/js2/mwEmbed/example_usage/Player_Timed_Text.html:51646
/branches/sqlite/js2/mwEmbed/example_usage/Player_Timed_Text.html:58211-58321
Name: svn:eol-style
2185 + native
Index: branches/MwEmbedStandAlone/modules/AddMedia/tests/Firefogg_GUI.html
@@ -2,7 +2,7 @@
33 <html><head>
44 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
55 <title>Firefogg - Make Ogg Video in your Browser</title>
6 - <script type="text/javascript" src="../ResourceLoader.php?class=window.jQuery,mwEmbed"></script>
 6+ <script type="text/javascript" src="../../../ResourceLoader.php?class=window.jQuery,mwEmbed"></script>
77 <!--<script type="text/javascript" src="../mwEmbed.js?debug=true"></script> -->
88 <style type="text/css" media="all">
99 body {
Index: branches/MwEmbedStandAlone/modules/AddMedia/tests/Add_Media_Wizard.html
@@ -12,7 +12,7 @@
1313 }
1414 </style>
1515 <!-- <script src="../ResourceLoader.php?class=window.jQuery,mwEmbed&debug=true"></script> -->
16 - <script type="text/javascript" src="../mwEmbed.js?debug=true"></script>
 16+ <script type="text/javascript" src="../../../mwEmbed.js?debug=true"></script>
1717
1818 <script type="text/javascript">
1919 mw.ready( function(){
Index: branches/MwEmbedStandAlone/modules/EmbedPlayer/tests/Player_Timed_Text.html
@@ -1,182 +0,0 @@
2 -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
3 -"http://www.w3.org/TR/html4/loose.dtd">
4 -<html>
5 -<head>
6 - <title>sample mv embed</title>
7 - <!-- <script type="text/javascript" src="../mwEmbed.js?debug=true"></script> -->
8 - <script type="text/javascript" src="../ResourceLoader.php?class=window.jQuery,mwEmbed&debug=true"></script>
9 - <script type="text/javascript">
10 - $j( document ).ready(function(){
11 - $j('#inlineTracksTextArea').text(
12 - $j.trim( $j('#inlineTracks').html() )
13 - );
14 - $j('#apiExampleTextArea').text(
15 - $j.trim( $j('#apiExample').html() )
16 - )
17 - });
18 -
19 - </script>
20 -</head>
21 -<body>
22 -<h3> mwEmbed Timed Text Examples:</h3>
23 -Click on the little lower right "CC" icon to expose the timed text
24 - <table border="1" cellpadding="6" width="950">
25 -
26 - <tr>
27 - <td id="apiExample" valign="top" width="410">
28 - <video
29 - style="width:512px;height:288px"
30 - durationHint="7:52"
31 - apiTitleKey="Yochai_Benkler_-_On_Autonomy,_Control_and_Cultural_Experience.ogg"
32 - apiProvider="commons"
33 - class="kskin"></video>
34 - <td valign="top">
35 - Commons Video API based timedText discovery<br>
36 -
37 - <textarea id="apiExampleTextArea" style="width:600px;height:180px"></textarea>
38 - </td>
39 - </tr>
40 -
41 -
42 - <tr>
43 - <td id="inlineTracks" valign="top" width="410">
44 -
45 - <video style="width:544px;height:304px;"
46 - poster="http://upload.wikimedia.org/wikipedia/commons/thumb/b/bd/Elephants_Dream.ogg/seek%3D13-Elephants_Dream.ogg.jpg"
47 - duration="10:53"
48 - linkback="http://www.elephantsdream.org/" >
49 - <source type="video/ogg" src="http://upload.wikimedia.org/wikipedia/commons/b/bd/Elephants_Dream.ogg" ></source>
50 - <source type="video/h264" src="http://www.archive.org/download/ElephantsDream/ed_1024_512kb.mp4"></source>
51 -
52 -
53 - <!-- Subtitles -->
54 -
55 - <track kind="subtitles" id="video_af" srclang="af"
56 - src="media/elephants_dream/elephant.afrikaans.srt"></track>
57 -
58 - <track kind="subtitles" id="video_ar" srclang="ar"
59 - src="media/elephants_dream/elephant.arabic.srt"></track>
60 -
61 - <track kind="subtitles" id="video_bn" srclang="bn"
62 - src="media/elephants_dream/elephant.bangla.srt"></track>
63 -
64 - <track kind="subtitles" id="video_br" srclang="br"
65 - src="media/elephants_dream/elephant.breton.srt"></track>
66 -
67 - <track kind="subtitles" id="video_bg" srclang="bg"
68 - src="media/elephants_dream/elephant.bulgarian.srt"></track>
69 -
70 - <track kind="subtitles" id="video_ca" srclang="ca"
71 - src="media/elephants_dream/elephant.catalan-utf8.srt"></track>
72 -
73 - <track kind="subtitles" id="video_zh" srclang="zh"
74 - src="media/elephants_dream/elephant.chinese.srt"></track>
75 -
76 - <track kind="subtitles" id="video_cz" srclang="cs"
77 - src="media/elephants_dream/elephant.czech.srt"></track>
78 -
79 - <track kind="subtitles" id="video_da" srclang="da"
80 - src="media/elephants_dream/elephant.danish.srt"></track>
81 -
82 - <track kind="subtitles" id="video_nl" srclang="nl"
83 - src="media/elephants_dream/elephant.dutch.srt"></track>
84 -
85 - <track kind="subtitles" id="video_en" srclang="en"
86 - src="media/elephants_dream/elephant.english.srt"></track>
87 -
88 - <track kind="subtitles" id="video_et" srclang="et"
89 - src="media/elephants_dream/elephant.estonian.srt"></track>
90 -
91 - <track kind="subtitles" id="video_fi" srclang="fi"
92 - src="media/elephants_dream/elephant.finnish.srt"></track>
93 -
94 - <track kind="subtitles" id="video_fr" srclang="fr"
95 - src="media/elephants_dream/elephant.french.srt"></track>
96 -
97 - <track kind="subtitles" id="video_de" srclang="de"
98 - src="media/elephants_dream/elephant.german.srt"></track>
99 -
100 - <track kind="subtitles" id="video_el" srclang="el"
101 - src="media/elephants_dream/elephant.greek.srt"></track>
102 -
103 - <track kind="subtitles" id="video_he" srclang="he"
104 - src="media/elephants_dream/elephant.hebrew.srt"></track>
105 -
106 - <track kind="subtitles" id="video_hu" srclang="hu"
107 - src="media/elephants_dream/elephant.hungarian-utf8.srt"></track>
108 -
109 - <track kind="subtitles" id="video_it" srclang="it"
110 - src="media/elephants_dream/elephant.italian.srt"></track>
111 -
112 - <track kind="subtitles" id="video_ja" srclang="ja"
113 - src="media/elephants_dream/elephant.japanese.srt"></track>
114 -
115 - <track kind="subtitles" id="video_ja" srclang="ja"
116 - src="media/elephants_dream/elephant.japanese-euc.srt"></track>
117 -
118 - <track kind="subtitles" id="video_mt" srclang="mt"
119 - src="media/elephants_dream/elephant.maltese_utf8.srt"></track>
120 -
121 - <track kind="subtitles" id="video_nn" srclang="nn"
122 - src="media/elephants_dream/elephant.norwegian.srt"></track>
123 -
124 - <track kind="subtitles" id="video_pl" srclang="pl"
125 - src="media/elephants_dream/elephant.polish.srt"></track>
126 -
127 - <track kind="subtitles" id="video_pt" srclang="pt"
128 - src="media/elephants_dream/elephant.portuguese.srt"></track>
129 -
130 - <track kind="subtitles" id="video_pt_br" srclang="pt-br"
131 - src="media/elephants_dream/elephant.brazilian.srt"></track>
132 -
133 - <track kind="subtitles" id="video_ro" srclang="ro"
134 - src="media/elephants_dream/elephant.romanian.srt"></track>
135 -
136 - <track kind="subtitles" id="video_ru" srclang="ru"
137 - src="media/elephants_dream/elephant.russian.srt"></track>
138 -
139 -
140 - <!-- Captions -->
141 - <track kind="captions" id="video_sl" srclang="sl"
142 - src="media/elephants_dream/elephant.slovenian.srt"></track>
143 -
144 - <track kind="captions" id="video_es" srclang="es"
145 - src="media/elephants_dream/elephant.spanish.srt"></track>
146 -
147 - <track kind="captions" id="video_es_mx" srclang="es-mx"
148 - src="media/elephants_dream/elephant.spanish-us.srt"></track>
149 -
150 - <track kind="captions" id="video_sk" srclang="sk"
151 - src="media/elephants_dream/elephant.slovak.srt"></track>
152 -
153 - <track kind="captions" id="video_sv" srclang="sv"
154 - src="media/elephants_dream/elephant.swedish.srt"></track>
155 -
156 -
157 - <!-- Audio Description -->
158 - <track kind="descriptions" id="audiodesc" srclang="en"
159 - src="media/elephants_dream/audiodescription.srt"></track>
160 -
161 - <!-- Chapters -->
162 - <track kind="chapters" id="chapters" srclang="en" label="Chapters"
163 - src="media/elephants_dream/chapters.srt"></track>
164 -
165 - </video>
166 -
167 - </td>
168 -
169 - <td valign="top">
170 - <h4>Text track inline embed example</h4>
171 - see: <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#the-track-element">HTML5 timed text spec</a>
172 - <br><textarea id="inlineTracksTextArea" style="width:600px;height:180px">
173 -
174 - </textarea>
175 - </td>
176 - </tr>
177 -
178 -
179 - </table>
180 -
181 -</body>
182 -</html>
183 -
Index: branches/MwEmbedStandAlone/modules/EmbedPlayer/tests/Player_Audio.html
@@ -2,8 +2,8 @@
33 <html>
44 <head>
55 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
6 - <!-- <script type="text/javascript" src="../mwEmbed.js?debug=true"></script> -->
7 - <script type="text/javascript" src="../ResourceLoader.php?class=window.jQuery,mwEmbed&debug=true"></script>
 6+ <!-- <script type="text/javascript" src="../../../mwEmbed.js?debug=true"></script> -->
 7+ <script type="text/javascript" src="../../../ResourceLoader.php?class=window.jQuery,mwEmbed&debug=true"></script>
88 <title>Audio Player sample</title>
99 </head>
1010 <body>
Index: branches/MwEmbedStandAlone/modules/EmbedPlayer/tests/Player_Themable.html
@@ -5,12 +5,9 @@
66 <title> Sample Themed Player </title>
77 Pre-loading demo ( stuff ) likely needed for video display
88 <!--
9 - <script type="text/javascript" src="../ResourceLoader.php?debug=true&class=mwEmbed"></script>
10 - <link rel="stylesheet" href="../skins/styles.css" type="text/css" media="screen" />
11 - <link rel="stylesheet" href="../skins/mvpcf/EmbedPlayer.css" type="text/css" media="screen" />
12 - <link rel="stylesheet" href="../skins/kskin/EmbedPlayer.css" type="text/css" media="screen" />
 9+ <script type="text/javascript" src="../../../ResourceLoader.php?debug=true&class=mwEmbed"></script>
1310 -->
14 - <script type="text/javascript" src="../mwEmbed.js?debug=true"></script>
 11+ <script type="text/javascript" src="../../../mwEmbed.js?debug=true"></script>
1512 </head>
1613 <script type="text/javascript">
1714 //Show the controls ( this is a theme demo )
Index: branches/MwEmbedStandAlone/modules/Sequencer/tests/Sequence_Editor.html
@@ -3,7 +3,7 @@
44 <html>
55 <head>
66 <title>SMIL Sequence Editor example</title>
7 - <script type="text/javascript" src="../../mwEmbed.js?debug=true"></script>
 7+ <script type="text/javascript" src="../../../mwEmbed.js?debug=true"></script>
88 <script type="text/javascript">
99 mw.ready(function(){
1010 mw.load( 'Sequencer', function(){
Index: branches/MwEmbedStandAlone/modules/ApiProxy/tests/testApiProxy.html
@@ -3,8 +3,8 @@
44 <head>
55 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
66 <title>Api Proxy Test</title>
7 - <!-- <script type="text/javascript" src="../mwEmbed.js?debug=true"></script> -->
8 - <script type="text/javascript" src="../ResourceLoader.php?class=window.jQuery,mwEmbed"></script>
 7+ <!-- <script type="text/javascript" src="../../../mwEmbed.js?debug=true"></script> -->
 8+ <script type="text/javascript" src="../../../ResourceLoader.php?class=window.jQuery,mwEmbed"></script>
99 <script type="text/javascript" >
1010 //HARD coded local test:
1111 var remote_wiki_host = 'http://commons.wikimedia.org';
Index: branches/MwEmbedStandAlone/mwEmbed.js
@@ -926,345 +926,6 @@
927927
928928
929929 /**
930 - * API Helper functions
931 - */
932 -
933 - /**
934 - *
935 - * Helper function to get revision text for a given title
936 - *
937 - * Assumes "follow redirects"
938 - *
939 - * $j.getTitleText( [apiUrl], title, callback )
940 - *
941 - * @param {String} url or title key
942 - * @parma {Mixed} title or callback function
943 - * @param {Function} callback Function or NULL
944 - *
945 - * @return callback is called with:
946 - * {Boolean} false if no page found
947 - * {String} text of wiki page
948 - */
949 - mw.getTitleText = function( apiUrl, title, callback ) {
950 - // Check if optional apiURL was not included
951 - if( !callback ) {
952 - title = apiUrl;
953 - callback = title;
954 - apiUrl = mw.getLocalApiUrl();
955 - }
956 - var request = {
957 - // Normalize the File NS (ie sometimes its present in apiTitleKey other times not
958 - 'titles' : title,
959 - 'prop' : 'revisions',
960 - 'rvprop' : 'content'
961 - };
962 -
963 - mw.getJSON( apiUrl , request, function( data ) {
964 - if( !data || !data.query || !data.query.pages ) {
965 - callback( false );
966 - }
967 - var pages = data.query.pages;
968 - for(var i in pages) {
969 - page = pages[ i ];
970 - if( page[ 'revisions' ] && page[ 'revisions' ][0]['*'] ) {
971 - callback( page[ 'revisions' ][0]['*'] );
972 - }
973 - }
974 - } );
975 - }
976 -
977 - /**
978 - * Issues the wikitext parse call
979 - *
980 - * @param {String} wikitext Wiki Text to be parsed by mediaWiki api call
981 - * @param {String} title Context title of the content to be parsed
982 - * @param {Function} callback Function called with api parser output
983 - */
984 - mw.parseWikiText = function( wikitext, title, callback ) {
985 - mw.log("mw.parseWikiText text length: " + wikitext.length + ' title context: ' + title );
986 - mw.load( 'JSON', function(){
987 - $j.ajax({
988 - type: 'POST',
989 - url: mw.getLocalApiUrl(),
990 - // Give the wiki 60 seconds to parse the wiki-text
991 - timeout : 60000,
992 - data: {
993 - 'action': 'parse',
994 - 'format': 'json',
995 - 'title' : title,
996 - 'text': wikitext
997 - },
998 - dataType: 'text',
999 - success: function( data ) {
1000 - var jsonData = JSON.parse( data ) ;
1001 - // xxx should handle other failures
1002 - callback( jsonData.parse.text['*'] );
1003 - },
1004 - error: function( XMLHttpRequest, textStatus, errorThrown ){
1005 - // xxx should better handle failures
1006 - mw.log( "Error: mw.parseWikiText:" + textStatus );
1007 - callback( "Error: failed to parse wikitext " );
1008 - }
1009 - });
1010 - });
1011 - }
1012 -
1013 - /**
1014 - * mediaWiki JSON a wrapper for jQuery getJSON:
1015 - * ( could also be named mw.apiRequest )
1016 - *
1017 - * The mwEmbed version lets you skip the url part
1018 - * mw.getJSON( [url], data, callback, [timeoutCallback] );
1019 - *
1020 - * Lets you assume:
1021 - * url is optional
1022 - * ( If the first argument is not a string we assume a local mediaWiki api request )
1023 - * callback parameter is not needed for the request data
1024 - * url param 'action'=>'query' is assumed ( if not set to something else in the "data" param
1025 - * format is set to "json" automatically
1026 - * automatically issues request over "POST" if the request api post type
1027 - * automatically will setup apiProxy where request is cross domain
1028 - *
1029 - * @param {Mixed} url or data request
1030 - * @param {Mixed} data or callback
1031 - * @param {Function} callbcak function called on success
1032 - * @param {Function} callbackTimeout - optional function called on timeout
1033 - * Setting timeout callback also avoids default timed-out dialog for proxy requests
1034 - */
1035 - mw.getJSON = function() {
1036 - // Proccess the arguments:
1037 -
1038 - // Set up the url
1039 - var url = false;
1040 - url = ( typeof arguments[0] == 'string' ) ? arguments[0] : mw.getLocalApiUrl();
1041 -
1042 - // Set up the data:
1043 - var data = null;
1044 - data = ( typeof arguments[0] == 'object' ) ? arguments[0] : null;
1045 - if( !data && typeof arguments[1] == 'object' ) {
1046 - data = arguments[1];
1047 - }
1048 -
1049 - // Setup the callback
1050 - var callback = false;
1051 - callback = ( typeof arguments[1] == 'function') ? arguments[1] : false;
1052 - var cbinx = 1;
1053 - if( ! callback && ( typeof arguments[2] == 'function') ) {
1054 - callback = arguments[2];
1055 - cbinx = 2;
1056 - }
1057 -
1058 - // Setup the timeoutCallback ( function after callback index )
1059 - var timeoutCallback = false;
1060 - timeoutCallback = ( typeof arguments[ cbinx + 1 ] == 'function' ) ? arguments[ cbinx + 1 ] : false;
1061 -
1062 - // Make sure we got a url:
1063 - if( !url ) {
1064 - mw.log( 'Error: no api url for api request' );
1065 - return false;
1066 - }
1067 -
1068 - // Add default action if unset:
1069 - if( !data['action'] ) {
1070 - data['action'] = 'query';
1071 - }
1072 -
1073 - // Add default format if not set:
1074 - if( !data['format'] ) {
1075 - data['format'] = 'json';
1076 - }
1077 -
1078 - // Setup callback wrapper for timeout
1079 - var requestTimeOutFlag = false;
1080 - var ranCallback = false;
1081 -
1082 - /**
1083 - * local callback function to control timeout
1084 - * @param {Object} data Result data
1085 - */
1086 - var myCallback = function( data ){
1087 - if( ! requestTimeOutFlag ){
1088 - ranCallback = true;
1089 - callback( data );
1090 - }
1091 - }
1092 - // Set the local timeout call based on defaultRequestTimeout
1093 - setTimeout( function( ) {
1094 - if( ! ranCallback ) {
1095 - requestTimeOutFlag = true;
1096 - mw.log( "Error:: request timed out: " + url );
1097 - if( timeoutCallback ){
1098 - timeoutCallback();
1099 - }
1100 - }
1101 - }, mw.getConfig( 'defaultRequestTimeout' ) * 1000 );
1102 -
1103 - mw.log("run getJSON: " + mw.replaceUrlParams( url, data ) );
1104 -
1105 - // Check if the request requires a "post"
1106 - if( mw.checkRequestPost( data ) ) {
1107 -
1108 - // Check if we need to setup a proxy
1109 - if( ! mw.isLocalDomain( url ) ) {
1110 -
1111 - //Set local scope ranCallback to true
1112 - // ( ApiProxy handles timeouts internally )
1113 - ranCallback = true;
1114 -
1115 - // Load the proxy and issue the request
1116 - mw.load( 'ApiProxy', function( ) {
1117 - mw.ApiProxy.doRequest( url, data, callback, timeoutCallback);
1118 - } );
1119 -
1120 - } else {
1121 -
1122 - // Do the request an ajax post
1123 - $j.post( url, data, myCallback, 'json');
1124 - }
1125 - return ;
1126 - }
1127 -
1128 - // If cross domain setup a callback:
1129 - if( ! mw.isLocalDomain( url ) ) {
1130 - if( url.indexOf( 'callback=' ) == -1 || data[ 'callback' ] == -1 ) {
1131 - // jQuery specific jsonp format: ( second ? is replaced with the callback )
1132 - url += ( url.indexOf('?') == -1 ) ? '?callback=?' : '&callback=?';
1133 - }
1134 - }
1135 - // Pass off the jQuery getJSON request:
1136 - $j.getJSON( url, data, myCallback );
1137 - }
1138 -
1139 - /**
1140 - * Checks if a mw request data requires a post request or not
1141 - * @param {Object}
1142 - * @return {Boolean}
1143 - * true if the request requires a post request
1144 - * false if the request does not
1145 - */
1146 - mw.checkRequestPost = function ( data ) {
1147 - if( $j.inArray( data['action'], mw.getConfig( 'apiPostActions' ) ) != -1 ) {
1148 - return true;
1149 - }
1150 - if( data['prop'] == 'info' && data['intoken'] ) {
1151 - return true;
1152 - }
1153 - if( data['meta'] == 'userinfo' ) {
1154 - return true;
1155 - }
1156 - return false;
1157 - }
1158 -
1159 - /**
1160 - * Check if the url is a request for the local domain
1161 - * relative paths are "local" domain
1162 - * @param {String} url Url for local domain
1163 - * @return {Boolean}
1164 - * true if url domain is local or relative
1165 - * false if the domain is
1166 - */
1167 - mw.isLocalDomain = function( url ) {
1168 - if( mw.parseUri( document.URL ).host == mw.parseUri( url ).host
1169 - || url.indexOf( '://' ) == -1 )
1170 - {
1171 - return true;
1172 - }
1173 - return false;
1174 - }
1175 -
1176 - /**
1177 - * Api helper to grab an edit token
1178 - *
1179 - * @param {String} [apiUrl] Optional target API URL (uses default local api if unset)
1180 - * @param {String} title The wiki page title you want to edit
1181 - * @param {callback} callback Function to pass the token to.
1182 - * issues callback with "false" if token not retrieved
1183 - */
1184 - mw.getToken = function( apiUrl, title, callback ) {
1185 - // Make the apiUrl be optional:
1186 - if( typeof title == 'function' ) {
1187 - callback = title;
1188 - title = apiUrl;
1189 - apiUrl = mw.getLocalApiUrl();
1190 - }
1191 -
1192 - mw.log( 'mw:getToken' );
1193 -
1194 - var request = {
1195 - 'prop': 'info',
1196 - 'intoken': 'edit',
1197 - 'titles': title
1198 - };
1199 - mw.getJSON( apiUrl, request, function( data ) {
1200 - for ( var i in data.query.pages ) {
1201 - if ( data.query.pages[i]['edittoken'] ) {
1202 - callback ( data.query.pages[i]['edittoken'] );
1203 - return ;
1204 - }
1205 - }
1206 - // No token found:
1207 - callback ( false );
1208 - } );
1209 - }
1210 -
1211 - /**
1212 - * Api helper to grab the username
1213 - * @param {String} [apiUrl] Optional target API url (uses default local api if unset)
1214 - * @param {Function} callback Function to callback with username or false if not found
1215 - * @param {Boolean} fresh A fresh check is issued.
1216 - */
1217 - // Stub feature apiUserNameCache to avoid multiple calls
1218 - // ( a more general api framework should be developed )
1219 - var apiUserNameCache = {};
1220 - mw.getUserName = function( apiUrl, callback, fresh ){
1221 - if( typeof apiUrl == 'function' ){
1222 - var callback = apiUrl;
1223 - var apiUrl = mw.getLocalApiUrl();
1224 - }
1225 -
1226 - // If apiUrl is local check wgUserName global
1227 - // before issuing the api request.
1228 - if( mw.isLocalDomain( apiUrl ) ){
1229 - if( typeof wgUserName != 'undefined' && wgUserName !== null ) {
1230 - callback( wgUserName )
1231 - // In case someone called this function without a callback
1232 - return wgUserName;
1233 - }
1234 - }
1235 - if( ! fresh && apiUserNameCache[ apiUrl ] ) {
1236 - callback( apiUserNameCache[ apiUrl ] );
1237 - return ;
1238 - }
1239 -
1240 - // Setup the api request
1241 - var request = {
1242 - 'action':'query',
1243 - 'meta':'userinfo'
1244 - }
1245 -
1246 - // Do request
1247 - mw.getJSON( apiUrl, request, function( data ) {
1248 - if( !data || !data.query || !data.query.userinfo || !data.query.userinfo.name ){
1249 - // Could not get user name user is not-logged in
1250 - mw.log( " No userName in response " );
1251 - callback( false );
1252 - return ;
1253 - }
1254 - // Check for "not logged in" id == 0
1255 - if( data.query.userinfo.id == 0 ){
1256 - callback( false );
1257 - return ;
1258 - }
1259 - apiUserNameCache[ apiUrl ] = data.query.userinfo.name;
1260 - // Else return the username:
1261 - callback( data.query.userinfo.name );
1262 - }, function(){
1263 - // Timeout also results in callback( false ) ( no user found)
1264 - callback( false );
1265 - } );
1266 - }
1267 -
1268 - /**
1269930 * Utility Functions
1270931 */
1271932
@@ -1706,32 +1367,7 @@
17071368 }
17081369 };
17091370
1710 - /**
1711 - * Get the api url for a given content provider key
1712 - * @return {Mixed}
1713 - * url for the provider
1714 - * local wiki api if no apiProvider is set
1715 - */
1716 - mw.getApiProviderURL = function( providerId ) {
1717 - if( mw.getConfig( providerId + '_apiurl') ) {
1718 - return mw.getConfig( providerId + '_apiurl');
1719 - }
1720 - return mw.getLocalApiUrl();
1721 - };
17221371
1723 - /**
1724 - * Get Api URL from mediaWiki page defined variables
1725 - * @return {Mixed}
1726 - * api url
1727 - * false
1728 - */
1729 - mw.getLocalApiUrl = function() {
1730 - if ( typeof wgServer != 'undefined' && typeof wgScriptPath != 'undefined' ) {
1731 - return wgServer + wgScriptPath + '/api.php';
1732 - }
1733 - return false;
1734 - };
1735 -
17361372 // Local mwEmbedPath variable ( for cache of mw.getMwEmbedPath )
17371373 var mwEmbedPath = null;
17381374
@@ -1919,8 +1555,9 @@
19201556 * Get URL Parameters per parameters in the host script include
19211557 */
19221558 mw.getUrlParam = function() {
1923 - if ( mwUrlParam )
 1559+ if ( mwUrlParam ) {
19241560 return mwUrlParam;
 1561+ }
19251562
19261563 var mwEmbedSrc = mw.getMwEmbedSrc();
19271564 var req_param = '';
@@ -2238,6 +1875,7 @@
22391876 // The follow code is ONLY RUN in debug / raw file mode
22401877 mw.load( 'loader.js', callback );
22411878 }
 1879+
22421880 /**
22431881 * Checks if the javascript is a static package ( not using resource loader )
22441882 * @return {boolean}

Status & tagging log