r75486 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r75485‎ | r75486 | r75487 >
Date:23:40, 26 October 2010
Author:tparscal
Status:ok (Comments)
Tags:
Comment:
Introducing mediaWiki.language, and mediaWiki.message which are modeled after their PHP counterparts Language and wfMessage respectively.
Modified paths:
  • /trunk/phase3/resources/Resources.php (modified) (history)
  • /trunk/phase3/resources/mediawiki.language (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/am.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/ar.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/bat-smg.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/be-tarask.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/be.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/bh.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/bs.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/cs.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/cu.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/cy.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/dsb.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/fr.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/ga.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/gd.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/gv.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/he.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/hi.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/hr.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/hsb.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/hy.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/ksh.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/ln.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/lt.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/lv.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/mg.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/mk.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/mo.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/mt.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/nso.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/pl.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/pt-br.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/ro.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/ru.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/se.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/sh.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/sk.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/sl.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/sma.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/sr-ec.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/sr-el.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/sr.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/ti.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/tl.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/uk.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/languages/wa.js (added) (history)
  • /trunk/phase3/resources/mediawiki.language/mediawiki.language.js (added) (history)
  • /trunk/phase3/resources/mediawiki.specials (added) (history)
  • /trunk/phase3/resources/mediawiki.specials/mediawiki.specials.preferences.js (added) (history)
  • /trunk/phase3/resources/mediawiki.specials/mediawiki.specials.search.js (added) (history)
  • /trunk/phase3/resources/mediawiki.util (added) (history)
  • /trunk/phase3/resources/mediawiki.util/mediawiki.util.js (added) (history)
  • /trunk/phase3/resources/mediawiki.util/mediawiki.util.test.js (added) (history)
  • /trunk/phase3/resources/mediawiki.views (added) (history)
  • /trunk/phase3/resources/mediawiki.views/mediawiki.views.history.js (added) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.js (modified) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.specials.preferences.js (deleted) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.specials.search.js (deleted) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.util.js (deleted) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.utiltest.js (deleted) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.views.history.js (deleted) (history)
  • /trunk/phase3/skins/common/ajaxwatch.js (modified) (history)
  • /trunk/phase3/skins/common/wikibits.js (modified) (history)

Diff [purge]

Index: trunk/phase3/skins/common/ajaxwatch.js
@@ -12,17 +12,17 @@
1313 if ( action == 'watch' || action == 'unwatch' ) {
1414 // save the accesskey from the title
1515 var keyCommand = $link.attr( 'title' ).match( /\[.*?\]$/ ) ? $link.attr( 'title' ).match( /\[.*?\]$/ )[0] : '';
16 - $link.attr( 'title', mediaWiki.msg.get( 'tooltip-ca-' + action ) + ' ' + keyCommand );
 16+ $link.attr( 'title', mediaWiki.message( 'tooltip-ca-' + action ) + ' ' + keyCommand );
1717 }
1818 if ( $link.data( 'icon' ) ) {
19 - $link.attr( 'alt', mediaWiki.msg.get( action ) );
 19+ $link.attr( 'alt', mediaWiki.message( action ) );
2020 if ( action == 'watching' || action == 'unwatching' ) {
2121 $link.addClass( 'loading' );
2222 } else {
2323 $link.removeClass( 'loading' );
2424 }
2525 } else {
26 - $link.html( mediaWiki.msg.get( action ) );
 26+ $link.html( mediaWiki.message( action ) );
2727 }
2828 };
2929
@@ -110,7 +110,7 @@
111111 if( $link.parents( 'li' ).attr( 'id' ) == 'ca-' + action ) {
112112 $link.parents( 'li' ).attr( 'id', 'ca-' + otheraction );
113113 // update the link text with the new message
114 - $link.text( mediaWiki.msg.get( otheraction ) );
 114+ $link.text( mediaWiki.message( otheraction ) );
115115 }
116116 };
117117 return false;
Index: trunk/phase3/skins/common/wikibits.js
@@ -156,7 +156,7 @@
157157 toggleLink.href = '#';
158158 addClickHandler( toggleLink, function( evt ) { toggleToc(); return killEvt( evt ); } );
159159
160 - toggleLink.appendChild( document.createTextNode( mediaWiki.msg.get( 'hidetoc' ) ) );
 160+ toggleLink.appendChild( document.createTextNode( mediaWiki.message( 'hidetoc' ) ) );
161161
162162 outerSpan.appendChild( document.createTextNode( '[' ) );
163163 outerSpan.appendChild( toggleLink );
@@ -198,12 +198,12 @@
199199 var toggleLink = document.getElementById( 'togglelink' );
200200
201201 if ( toc && toggleLink && toc.style.display == 'none' ) {
202 - changeText( toggleLink, mediaWiki.msg.get( 'hidetoc' ) );
 202+ changeText( toggleLink, mediaWiki.message( 'hidetoc' ) );
203203 toc.style.display = 'block';
204204 document.cookie = "hidetoc=0";
205205 tocmain.className = 'toc';
206206 } else {
207 - changeText( toggleLink, mediaWiki.msg.get( 'showtoc' ) );
 207+ changeText( toggleLink, mediaWiki.message( 'showtoc' ) );
208208 toc.style.display = 'none';
209209 document.cookie = "hidetoc=1";
210210 tocmain.className = 'toc tochidden';
Index: trunk/phase3/resources/mediawiki.util/mediawiki.util.test.js
@@ -0,0 +1,150 @@
 2+/*
 3+ * mediaWiki Debug Test Suit.
 4+ * Available on "/Special:BlankPage?action=mwutiltest&debug=true")
 5+ */
 6+
 7+(function ($, mw) {
 8+
 9+ mediaWiki.test = {
 10+
 11+ /* Variables */
 12+ '$table' : null,
 13+ 'addedTests' : [],
 14+
 15+ /* Functions */
 16+
 17+ /**
 18+ * Adds a row to the test-table
 19+ *
 20+ * @param String code Code of the test to be executed
 21+ * @param String result Expected result in 'var (vartype)' form
 22+ * @param String contain Important part of the result, if result is different but does contain this it will not return ERROR but PARTIALLY
 23+ */
 24+ 'addTest' : function (code, result, contain) {
 25+ if (!contain) {
 26+ contain = result;
 27+ }
 28+ this.addedTests.push([code, result, contain]);
 29+ this.$table.append('<tr><td>' + mw.util.htmlEscape(code) + '</td><td>' + mw.util.htmlEscape(result) + '<td></td></td><td>?</td></tr>');
 30+ },
 31+
 32+ /* Initialisation */
 33+ 'initialised' : false,
 34+ 'init' : function () {
 35+ if (this.initialised === false) {
 36+ this.initialised = true;
 37+ $(function () {
 38+ if (wgCanonicalSpecialPageName == 'Blankpage' && mw.util.getParamValue('action') === 'mwutiltest') {
 39+
 40+ // Build page
 41+ document.title = 'mediaWiki.util JavaScript Test - ' + wgSiteName;
 42+ $('#firstHeading').text('mediaWiki.util JavaScript Test');
 43+ mw.util.$content.html(
 44+ '<p>Below is a list of tests to confirm proper functionality of the mediaWiki.util functions</p>' +
 45+ '<hr />' +
 46+ '<table id="mw-mwutiltest-table" class="wikitable sortable"><tr><th>Exec</th><th>Should return</th><th>Does return</th><th>Equal ?</th></tr></table>'
 47+ );
 48+ mw.test.$table = $('table#mw-mwutiltest-table');
 49+
 50+ // Populate tests
 51+ mw.test.addTest('typeof String.prototype.trim',
 52+ 'function (string)');
 53+ mw.test.addTest('typeof String.prototype.trimLeft',
 54+ 'function (string)');
 55+ mw.test.addTest('typeof String.prototype.trimRight',
 56+ 'function (string)');
 57+ mw.test.addTest('typeof Array.prototype.compare',
 58+ 'function (string)');
 59+ mw.test.addTest('typeof Array.prototype.indexOf',
 60+ 'function (string)');
 61+ mw.test.addTest('4',
 62+ '4 (number)');
 63+ mw.test.addTest('typeof mediaWiki',
 64+ 'object (string)');
 65+ mw.test.addTest('typeof mw',
 66+ 'object (string)');
 67+ mw.test.addTest('typeof mw.util',
 68+ 'object (string)');
 69+ mw.test.addTest('typeof String.prototype.ucFirst',
 70+ 'function (string)');
 71+ mw.test.addTest('\'mediawiki\'.ucFirst()',
 72+ 'Mediawiki (string)');
 73+ mw.test.addTest('typeof $.fn.enableCheckboxShiftClick',
 74+ 'function (string)');
 75+ mw.test.addTest('typeof mw.util.rawurlencode',
 76+ 'function (string)');
 77+ mw.test.addTest('mw.util.rawurlencode(\'Test: A&B/Here\')',
 78+ 'Test%3A%20A%26B%2FHere (string)');
 79+ mw.test.addTest('typeof mw.util.getWikilink',
 80+ 'function (string)');
 81+ mw.test.addTest('typeof mw.util.getParamValue',
 82+ 'function (string)');
 83+ mw.test.addTest('mw.util.getParamValue(\'action\')',
 84+ 'mwutiltest (string)');
 85+ mw.test.addTest('typeof mw.util.htmlEscape',
 86+ 'function (string)');
 87+ mw.test.addTest('mw.util.htmlEscape(\'<a href="http://mw.org/?a=b&c=d">link</a>\')',
 88+ '&lt;a href="http://mw.org/?a=b&amp;c=d"&gt;link&lt;/a&gt; (string)');
 89+ mw.test.addTest('typeof mw.util.htmlUnescape',
 90+ 'function (string)');
 91+ mw.test.addTest('mw.util.htmlUnescape(\'&lt;a href="http://mw.org/?a=b&amp;c=d"&gt;link&lt;/a&gt;\')',
 92+ '<a href="http://mw.org/?a=b&c=d">link</a> (string)');
 93+ mw.test.addTest('typeof mw.util.tooltipAccessKeyRegexp',
 94+ 'function (string)');
 95+ mw.test.addTest('typeof mw.util.updateTooltipAccessKeys',
 96+ 'function (string)');
 97+ mw.test.addTest('typeof mw.util.addPortletLink',
 98+ 'function (string)');
 99+ mw.test.addTest('typeof mw.util.addPortletLink("p-tb", "http://mediawiki.org/", "MediaWiki.org", "t-mworg", "Go to MediaWiki.org ", "m", "#t-print")',
 100+ 'object (string)');
 101+ mw.test.addTest('a = mw.util.addPortletLink("p-tb", "http://mediawiki.org/", "MediaWiki.org", "t-mworg", "Go to MediaWiki.org ", "m", "#t-print"); if(a){ a.outerHTML; }',
 102+ '<li id="t-mworg"><span><a href="http://mediawiki.org/" accesskey="m" title="Go to MediaWiki.org [ctrl-alt-m]">MediaWiki.org</a></span></li> (string)',
 103+ 'href="http://mediawiki.org/"');
 104+
 105+ // Run tests and compare results
 106+ var exec,
 107+ result,
 108+ resulttype,
 109+ numberoftests = 0,
 110+ numberofpasseds = 0,
 111+ numberofpartials = 0,
 112+ numberoferrors = 0,
 113+ $testrows;
 114+ $testrows = mw.test.$table.find('tr');
 115+ $.each(mw.test.addedTests, (function (i) {
 116+ numberoftests++;
 117+
 118+ exec = mw.test.addedTests[i][0];
 119+ shouldreturn = mw.test.addedTests[i][1];
 120+ shouldcontain = mw.test.addedTests[i][2];
 121+ doesreturn = eval(exec);
 122+ doesreturn = doesreturn + ' (' + typeof doesreturn + ')';
 123+ $thisrow = $testrows.eq(i + 1);
 124+ $thisrow.find('> td').eq(2).text(doesreturn);
 125+
 126+ if (doesreturn.indexOf(shouldcontain) !== -1) {
 127+ if (doesreturn == shouldreturn){
 128+ $thisrow.find('> td').eq(3).css('background', '#EFE').text('OK');
 129+ numberofpasseds++;
 130+ } else {
 131+ $thisrow.find('> td').eq(3).css('background', '#FFE').html('<small>PARTIALLY</small>');
 132+ numberofpartials++;
 133+ }
 134+ } else {
 135+ $thisrow.find('> td').eq(3).css('background', '#FEE').text('ERROR');
 136+ numberoferrors++;
 137+ }
 138+
 139+ })
 140+ );
 141+ mw.test.$table.before('<p><strong>Ran ' + numberoftests + ' tests. ' + numberofpasseds + ' passed test(s). ' + numberoferrors + ' error(s). ' + numberofpartials + ' partially passed test(s). </p>');
 142+
 143+ }
 144+ });
 145+ }
 146+ }
 147+ };
 148+
 149+ mediaWiki.test.init();
 150+
 151+})(jQuery, mediaWiki);
\ No newline at end of file
Property changes on: trunk/phase3/resources/mediawiki.util/mediawiki.util.test.js
___________________________________________________________________
Added: svn:eol-style
1152 + native
Index: trunk/phase3/resources/mediawiki.util/mediawiki.util.js
@@ -0,0 +1,314 @@
 2+/*
 3+ * Utilities
 4+ */
 5+
 6+(function ($, mw) {
 7+
 8+ mediaWiki.util = {
 9+
 10+ /* Initialisation */
 11+ 'initialised' : false,
 12+ 'init' : function () {
 13+ if (this.initialised === false) {
 14+ this.initialised = true;
 15+
 16+ // Set tooltipAccessKeyPrefix
 17+ if (is_opera) {
 18+ this.tooltipAccessKeyPrefix = 'shift-esc-';
 19+ } else if (is_chrome) {
 20+ this.tooltipAccessKeyPrefix = is_chrome_mac ? 'ctrl-option-' : 'alt-';
 21+ } else if (!is_safari_win && is_safari && webkit_version > 526) {
 22+ this.tooltipAccessKeyPrefix = 'ctrl-alt-';
 23+ } else if (!is_safari_win &&
 24+ (is_safari || clientPC.indexOf('mac') !== -1 || clientPC.indexOf('konqueror') !== -1)) {
 25+ this.tooltipAccessKeyPrefix = 'ctrl-';
 26+ } else if (is_ff2) {
 27+ this.tooltipAccessKeyPrefix = 'alt-shift-';
 28+ }
 29+
 30+ // Setup CheckboxShiftClick
 31+ $.fn.enableCheckboxShiftClick = function () {
 32+ var prevCheckbox = null;
 33+ var $box = this;
 34+ $box.click(function (e) {
 35+ if (prevCheckbox !== null && e.shiftKey) {
 36+ $box.slice(
 37+ Math.min($box.index(prevCheckbox), $box.index(e.target)),
 38+ Math.max($box.index(prevCheckbox), $box.index(e.target)) + 1
 39+ ).attr({checked: e.target.checked ? 'checked' : ''});
 40+ }
 41+ prevCheckbox = e.target;
 42+ });
 43+ return $box;
 44+ };
 45+
 46+ // Prototype enhancements
 47+ if (typeof String.prototype.ucFirst === 'undefined') {
 48+ String.prototype.ucFirst = function () {
 49+ return this.substr(0, 1).toUpperCase() + this.substr(1, this.length);
 50+ };
 51+ }
 52+
 53+ // Any initialisation after the DOM is ready
 54+ $(function () {
 55+
 56+ // Enable CheckboxShiftClick
 57+ $('input[type=checkbox]:not(.noshiftselect)').enableCheckboxShiftClick();
 58+
 59+ // Fill bodyContant var
 60+ if ($('#bodyContent').length) {
 61+ mw.util.$content = $('#bodyContent');
 62+ } else if ($('#article').length) {
 63+ mw.util.$content = $('#article');
 64+ } else {
 65+ mw.util.$content = $('#content');
 66+ }
 67+ });
 68+
 69+
 70+ return true;
 71+ }
 72+ return false;
 73+ },
 74+
 75+ /* Main body */
 76+
 77+ /**
 78+ * Encodes the string like PHP's rawurlencode
 79+ *
 80+ * @param String str string to be encoded
 81+ */
 82+ 'rawurlencode' : function (str) {
 83+ str = (str + '').toString();
 84+ return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28')
 85+ .replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/~/g, '%7E');
 86+ },
 87+
 88+ /**
 89+ * Encode pagetitles for use in a URL
 90+ * We want / and : to be included as literal characters in our title URLs
 91+ * as they otherwise fatally break the title
 92+ *
 93+ * @param String str string to be encoded
 94+ */
 95+ 'wikiUrlencode' : function (str) {
 96+ return this.rawurlencode(str).replace(/%20/g, '_').replace(/%3A/g, ':').replace(/%2F/g, '/');
 97+ },
 98+
 99+ /**
 100+ * Get the full url to a pagename
 101+ *
 102+ * @param String str pagename to link to
 103+ */
 104+ 'getWikilink' : function (str) {
 105+ return wgServer + wgArticlePath.replace('$1', this.wikiUrlencode(str));
 106+ },
 107+
 108+ /**
 109+ * Check is a variable is empty. Support for strings, booleans, arrays and objects.
 110+ * String "0" is considered empty. String containing only whitespace (ie. " ") is considered not empty.
 111+ *
 112+ * @param Mixed v the variable to check for empty ness
 113+ */
 114+ 'isEmpty' : function (v) {
 115+ var key;
 116+ if (v === "" || v === 0 || v === "0" || v === null || v === false || typeof v === 'undefined') {
 117+ return true;
 118+ }
 119+ if (v.length === 0) {
 120+ return true;
 121+ }
 122+ if (typeof v === 'object') {
 123+ for (key in v) {
 124+ return false;
 125+ }
 126+ return true;
 127+ }
 128+ return false;
 129+ },
 130+
 131+
 132+ /**
 133+ * Grabs the url parameter value for the given parameter
 134+ * Returns null if not found
 135+ *
 136+ * @param String param paramter name
 137+ * @param String url url to search through (optional)
 138+ */
 139+ 'getParamValue' : function (param, url) {
 140+ url = url ? url : document.location.href;
 141+ var re = new RegExp('[^#]*[&?]' + param + '=([^&#]*)'); // Get last match, stop at hash
 142+ var m = re.exec(url);
 143+ if (m && m.length > 1) {
 144+ return decodeURIComponent(m[1]);
 145+ }
 146+ return null;
 147+ },
 148+
 149+ /**
 150+ * Converts special characters to their HTML entities
 151+ *
 152+ * @param String str text to escape
 153+ * @param Bool quotes if true escapes single and double quotes aswell (by default false)
 154+ */
 155+ 'htmlEscape' : function (str, quotes) {
 156+ str = $('<div/>').text(str).html();
 157+ if (typeof quotes === 'undefined') {
 158+ quotes = false;
 159+ }
 160+ if (quotes === true) {
 161+ str = str.replace(/'/g, '&#039;').replace(/"/g, '&quot;');
 162+ }
 163+ return str;
 164+ },
 165+
 166+ /**
 167+ * Converts HTML entities back to text
 168+ *
 169+ * @param String str text to unescape
 170+ */
 171+ 'htmlUnescape' : function (str) {
 172+ return $('<div/>').html(str).text();
 173+ },
 174+
 175+ // Access key prefix
 176+ // will be re-defined based on browser/operating system detection in mw.util.init()
 177+ 'tooltipAccessKeyPrefix' : 'alt-',
 178+
 179+ // Regex to match accesskey tooltips
 180+ 'tooltipAccessKeyRegexp': /\[(ctrl-)?(alt-)?(shift-)?(esc-)?(.)\]$/,
 181+
 182+ /**
 183+ * Add the appropriate prefix to the accesskey shown in the tooltip.
 184+ * If the nodeList parameter is given, only those nodes are updated;
 185+ * otherwise, all the nodes that will probably have accesskeys by
 186+ * default are updated.
 187+ *
 188+ * @param Mixed nodeList jQuery object, or array of elements
 189+ */
 190+ 'updateTooltipAccessKeys' : function (nodeList) {
 191+ var $nodes;
 192+ if (nodeList instanceof jQuery) {
 193+ $nodes = nodeList;
 194+ } else if (nodeList) {
 195+ $nodes = $(nodeList);
 196+ } else {
 197+ // Rather than scanning all links, just
 198+ $('#column-one a, #mw-head a, #mw-panel a, #p-logo a');
 199+
 200+ // these are rare enough that no such optimization is needed
 201+ this.updateTooltipAccessKeys($('input'));
 202+ this.updateTooltipAccessKeys($('label'));
 203+ return;
 204+ }
 205+
 206+ $nodes.each(function (i) {
 207+ var tip = $(this).attr('title');
 208+ if (!!tip && mw.util.tooltipAccessKeyRegexp.exec(tip)) {
 209+ tip = tip.replace(mw.util.tooltipAccessKeyRegexp, '[' + mw.util.tooltipAccessKeyPrefix + "$5]");
 210+ $(this).attr('title', tip);
 211+ }
 212+ });
 213+ },
 214+
 215+ // jQuery object that refers to the page-content element
 216+ // Populated by init()
 217+ '$content' : null,
 218+
 219+
 220+ /**
 221+ * Add a link to a portlet menu on the page, such as:
 222+ *
 223+ * p-cactions (Content actions), p-personal (Personal tools), p-navigation (Navigation), p-tb (Toolbox)
 224+ *
 225+ * The first three paramters are required, others are optionals. Though
 226+ * providing an id and tooltip is recommended.
 227+ *
 228+ * By default the new link will be added to the end of the list. To add the link before a given existing item,
 229+ * pass the DOM node (document.getElementById('foobar') or the jQuery-selector ('#foobar') of that item.
 230+ *
 231+ * @example mw.util.addPortletLink('p-tb', 'http://mediawiki.org/', 'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org ', 'm', '#t-print')
 232+ *
 233+ * @param String portlet id of the target portlet ('p-cactions' or 'p-personal' etc.)
 234+ * @param String href link URL
 235+ * @param String text link text (will be automatically lowercased by CSS for p-cactions in Monobook)
 236+ * @param String id id of the new item, should be unique and preferably have the appropriate prefix ('ca-', 'pt-', 'n-' or 't-')
 237+ * @param String tooltip text to show when hovering over the link, without accesskey suffix
 238+ * @param String accesskey accesskey to activate this link (one character, try to avoid conflicts. Use $('[accesskey=x').get() in the console to see if 'x' is already used.
 239+ * @param mixed nextnode DOM node or jQuery-selector of the item that the new item should be added before, should be another item in the same list will be ignored if not the so
 240+ *
 241+ * @return Node the DOM node of the new item (a LI element, or A element for older skins) or null
 242+ */
 243+ 'addPortletLink' : function (portlet, href, text, id, tooltip, accesskey, nextnode) {
 244+ var $link = $('<a />').attr('href', href).text(text);
 245+
 246+ // Some skins don't have portlets
 247+ // Just add it to the bottom of their 'sidebar' element ignoring the specified portlet target
 248+ switch (skin) {
 249+ case 'standard' :
 250+ case 'cologneblue' :
 251+ $("#quickbar").append($link.after('<br />'));
 252+ return $link.get(0);
 253+ case 'nostalgia' :
 254+ $("#searchform").before($link).before(' &#124; ');
 255+ return $link.get(0);
 256+ default : // chick, modern, monobook, myskin, simple, vector...
 257+
 258+ var $portlet = $('#' + portlet);
 259+ if ($portlet.length === 0) {
 260+ return null;
 261+ }
 262+ var $ul = $portlet.find('ul').eq(0);
 263+ if ($ul.length === 0) {
 264+ if ($portlet.find('div').length === 0) {
 265+ $portlet.append('<ul />');
 266+ } else {
 267+ $portlet.find('div').eq(-1).append('<ul />');
 268+ }
 269+ $ul = $portlet.find('ul').eq(0);
 270+ }
 271+ if ($ul.length === 0) {
 272+ return null;
 273+ }
 274+
 275+ // unhide portlet if it was hidden before
 276+ $portlet.removeClass('emptyPortlet');
 277+
 278+ var $item = $link.wrap('<li><span /></li>').parent().parent();
 279+
 280+ if (id) {
 281+ $item.attr('id', id);
 282+ }
 283+ if (accesskey) {
 284+ $link.attr('accesskey', accesskey);
 285+ tooltip += ' [' + accesskey + ']';
 286+ }
 287+ if (tooltip) {
 288+ $link.attr('title', tooltip);
 289+ }
 290+ if (accesskey && tooltip) {
 291+ this.updateTooltipAccessKeys($link);
 292+ }
 293+
 294+ // Append using DOM-element passing
 295+ if (nextnode && nextnode.parentNode == $ul.get(0)) {
 296+ $(nextnode).before($item);
 297+ } else {
 298+ // If the jQuery selector isn't found within the <ul>, just append it at the end
 299+ if ($ul.find(nextnode).length === 0) {
 300+ $ul.append($item);
 301+ } else {
 302+ // Append using jQuery CSS selector
 303+ $ul.find(nextnode).eq(0).before($item);
 304+ }
 305+ }
 306+
 307+ return $item.get(0);
 308+ }
 309+ }
 310+
 311+ };
 312+
 313+ mediaWiki.util.init();
 314+
 315+})(jQuery, mediaWiki);
\ No newline at end of file
Property changes on: trunk/phase3/resources/mediawiki.util/mediawiki.util.js
___________________________________________________________________
Added: svn:eol-style
1316 + native
Index: trunk/phase3/resources/mediawiki.views/mediawiki.views.history.js
@@ -0,0 +1,7 @@
 2+/*
 3+ * JavaScript for History view
 4+ */
 5+
 6+// Replaces histrowinit
 7+$( '#pagehistory li input[name=diff], #pagehistory li input[name=oldid]' ).click( diffcheck );
 8+diffcheck();
\ No newline at end of file
Property changes on: trunk/phase3/resources/mediawiki.views/mediawiki.views.history.js
___________________________________________________________________
Added: svn:eol-style
19 + native
Index: trunk/phase3/resources/Resources.php
@@ -317,21 +317,71 @@
318318 'debugRaw' => false
319319 ) ),
320320 'mediawiki.specials.preferences' => new ResourceLoaderFileModule( array(
321 - 'scripts' => 'resources/mediawiki/mediawiki.specials.preferences.js',
 321+ 'scripts' => 'resources/mediawiki.specials/mediawiki.specials.preferences.js',
322322 ) ),
323323 'mediawiki.specials.search' => new ResourceLoaderFileModule( array(
324 - 'scripts' => 'resources/mediawiki/mediawiki.specials.search.js',
 324+ 'scripts' => 'resources/mediawiki.specials/mediawiki.specials.search.js',
325325 ) ),
326326 'mediawiki.views.history' => new ResourceLoaderFileModule( array(
327 - 'scripts' => 'resources/mediawiki/mediawiki.views.history.js',
 327+ 'scripts' => 'resources/mediawiki.views/mediawiki.views.history.js',
328328 'dependencies' => 'mediawiki.legacy.history',
329329 ) ),
 330+ 'mediawiki.language' => new ResourceLoaderFileModule( array(
 331+ 'scripts' => 'resources/mediawiki.language/mediawiki.language.js',
 332+ 'languageScripts' => array(
 333+ 'am' => 'resources/mediawiki.language/languages/am.js',
 334+ 'ar' => 'resources/mediawiki.language/languages/ar.js',
 335+ 'bat-smg' => 'resources/mediawiki.language/languages/bat-smg.js',
 336+ 'be' => 'resources/mediawiki.language/languages/be.js',
 337+ 'be-tarask' => 'resources/mediawiki.language/languages/be-tarask.js',
 338+ 'bh' => 'resources/mediawiki.language/languages/bh.js',
 339+ 'bs' => 'resources/mediawiki.language/languages/bs.js',
 340+ 'cs' => 'resources/mediawiki.language/languages/cs.js',
 341+ 'cu' => 'resources/mediawiki.language/languages/cu.js',
 342+ 'cy' => 'resources/mediawiki.language/languages/cy.js',
 343+ 'dsb' => 'resources/mediawiki.language/languages/dsb.js',
 344+ 'fr' => 'resources/mediawiki.language/languages/fr.js',
 345+ 'ga' => 'resources/mediawiki.language/languages/ga.js',
 346+ 'gd' => 'resources/mediawiki.language/languages/gd.js',
 347+ 'gv' => 'resources/mediawiki.language/languages/gv.js',
 348+ 'he' => 'resources/mediawiki.language/languages/he.js',
 349+ 'hi' => 'resources/mediawiki.language/languages/hi.js',
 350+ 'hr' => 'resources/mediawiki.language/languages/hr.js',
 351+ 'hsb' => 'resources/mediawiki.language/languages/hsb.js',
 352+ 'hy' => 'resources/mediawiki.language/languages/hy.js',
 353+ 'ksh' => 'resources/mediawiki.language/languages/ksh.js',
 354+ 'ln' => 'resources/mediawiki.language/languages/ln.js',
 355+ 'lt' => 'resources/mediawiki.language/languages/lt.js',
 356+ 'lv' => 'resources/mediawiki.language/languages/lv.js',
 357+ 'mg' => 'resources/mediawiki.language/languages/mg.js',
 358+ 'mk' => 'resources/mediawiki.language/languages/mk.js',
 359+ 'mo' => 'resources/mediawiki.language/languages/mo.js',
 360+ 'mt' => 'resources/mediawiki.language/languages/mt.js',
 361+ 'nso' => 'resources/mediawiki.language/languages/nso.js',
 362+ 'pl' => 'resources/mediawiki.language/languages/pl.js',
 363+ 'pt-br' => 'resources/mediawiki.language/languages/pt-br.js',
 364+ 'ro' => 'resources/mediawiki.language/languages/ro.js',
 365+ 'ru' => 'resources/mediawiki.language/languages/ru.js',
 366+ 'se' => 'resources/mediawiki.language/languages/se.js',
 367+ 'sh' => 'resources/mediawiki.language/languages/sh.js',
 368+ 'sk' => 'resources/mediawiki.language/languages/sk.js',
 369+ 'sl' => 'resources/mediawiki.language/languages/sl.js',
 370+ 'sma' => 'resources/mediawiki.language/languages/sma.js',
 371+ 'sr-ec' => 'resources/mediawiki.language/languages/sr-ec.js',
 372+ 'sr-el' => 'resources/mediawiki.language/languages/sr-el.js',
 373+ 'sr' => 'resources/mediawiki.language/languages/sr.js',
 374+ 'ti' => 'resources/mediawiki.language/languages/ti.js',
 375+ 'tl' => 'resources/mediawiki.language/languages/tl.js',
 376+ 'uk' => 'resources/mediawiki.language/languages/uk.js',
 377+ 'wa' => 'resources/mediawiki.language/languages/wa.js',
 378+ ),
 379+ ) ),
330380 'mediawiki.util' => new ResourceLoaderFileModule( array(
331 - 'scripts' => 'resources/mediawiki/mediawiki.util.js',
332 - 'debugScripts' => 'resources/mediawiki/mediawiki.utiltest.js',
 381+ 'scripts' => 'resources/mediawiki.util/mediawiki.util.js',
 382+ 'debugScripts' => 'resources/mediawiki.util/mediawiki.util.test.js',
333383 ) ),
334384
335 - /* MediaWiki Legacy */
 385+ /* mediawiki Legacy */
336386
337387 'mediawiki.legacy.ajax' => new ResourceLoaderFileModule( array(
338388 'scripts' => 'skins/common/ajax.js',
@@ -430,6 +480,7 @@
431481 ) ),
432482 'mediawiki.legacy.wikibits' => new ResourceLoaderFileModule( array(
433483 'scripts' => 'skins/common/wikibits.js',
 484+ 'dependencies' => 'mediawiki.language',
434485 'messages' => array( 'showtoc', 'hidetoc' ),
435486 ) ),
436487 'mediawiki.legacy.wikiprintable' => new ResourceLoaderFileModule( array(
Index: trunk/phase3/resources/mediawiki/mediawiki.specials.preferences.js
@@ -1,40 +0,0 @@
2 -/*
3 - * JavaScript for Special:Preferences
4 - */
5 -
6 -$( '#prefsubmit' ).attr( 'id', 'prefcontrol' );
7 -$( '#preferences' )
8 - .addClass( 'jsprefs' )
9 - .before( $( '<ul id="preftoc"></ul>' ) )
10 - .children( 'fieldset' )
11 - .hide()
12 - .addClass( 'prefsection' )
13 - .children( 'legend' )
14 - .addClass( 'mainLegend' )
15 - .each( function( i ) {
16 - $(this).parent().attr( 'id', 'prefsection-' + i );
17 - if ( i === 0 ) {
18 - $(this).parent().show();
19 - }
20 - $( '#preftoc' ).append(
21 - $( '<li></li>' )
22 - .addClass( i === 0 ? 'selected' : null )
23 - .append(
24 - $( '<a></a>')
25 - .text( $(this).text() )
26 - .attr( 'href', '#prefsection-' + i )
27 - .mousedown( function( e ) {
28 - $(this).parent().parent().find( 'li' ).removeClass( 'selected' );
29 - $(this).parent().addClass( 'selected' );
30 - e.preventDefault();
31 - return false;
32 - } )
33 - .click( function( e ) {
34 - $( '#preferences > fieldset' ).hide();
35 - $( '#prefsection-' + i ).show();
36 - e.preventDefault();
37 - return false;
38 - } )
39 - )
40 - );
41 - } );
Index: trunk/phase3/resources/mediawiki/mediawiki.specials.search.js
@@ -1,8 +0,0 @@
2 -/*
3 - * JavaScript for Specical:Search
4 - */
5 -
6 -// Emulate HTML5 autofocus behavior in non HTML5 compliant browsers
7 -if ( !( 'autofocus' in document.createElement( 'input' ) ) ) {
8 - $( 'input[autofocus]' ).focus();
9 -}
Index: trunk/phase3/resources/mediawiki/mediawiki.util.js
@@ -1,314 +0,0 @@
2 -/*
3 - * Utilities
4 - */
5 -
6 -(function ($, mw) {
7 -
8 - mediaWiki.util = {
9 -
10 - /* Initialisation */
11 - 'initialised' : false,
12 - 'init' : function () {
13 - if (this.initialised === false) {
14 - this.initialised = true;
15 -
16 - // Set tooltipAccessKeyPrefix
17 - if (is_opera) {
18 - this.tooltipAccessKeyPrefix = 'shift-esc-';
19 - } else if (is_chrome) {
20 - this.tooltipAccessKeyPrefix = is_chrome_mac ? 'ctrl-option-' : 'alt-';
21 - } else if (!is_safari_win && is_safari && webkit_version > 526) {
22 - this.tooltipAccessKeyPrefix = 'ctrl-alt-';
23 - } else if (!is_safari_win &&
24 - (is_safari || clientPC.indexOf('mac') !== -1 || clientPC.indexOf('konqueror') !== -1)) {
25 - this.tooltipAccessKeyPrefix = 'ctrl-';
26 - } else if (is_ff2) {
27 - this.tooltipAccessKeyPrefix = 'alt-shift-';
28 - }
29 -
30 - // Setup CheckboxShiftClick
31 - $.fn.enableCheckboxShiftClick = function () {
32 - var prevCheckbox = null;
33 - var $box = this;
34 - $box.click(function (e) {
35 - if (prevCheckbox !== null && e.shiftKey) {
36 - $box.slice(
37 - Math.min($box.index(prevCheckbox), $box.index(e.target)),
38 - Math.max($box.index(prevCheckbox), $box.index(e.target)) + 1
39 - ).attr({checked: e.target.checked ? 'checked' : ''});
40 - }
41 - prevCheckbox = e.target;
42 - });
43 - return $box;
44 - };
45 -
46 - // Prototype enhancements
47 - if (typeof String.prototype.ucFirst === 'undefined') {
48 - String.prototype.ucFirst = function () {
49 - return this.substr(0, 1).toUpperCase() + this.substr(1, this.length);
50 - };
51 - }
52 -
53 - // Any initialisation after the DOM is ready
54 - $(function () {
55 -
56 - // Enable CheckboxShiftClick
57 - $('input[type=checkbox]:not(.noshiftselect)').enableCheckboxShiftClick();
58 -
59 - // Fill bodyContant var
60 - if ($('#bodyContent').length) {
61 - mw.util.$content = $('#bodyContent');
62 - } else if ($('#article').length) {
63 - mw.util.$content = $('#article');
64 - } else {
65 - mw.util.$content = $('#content');
66 - }
67 - });
68 -
69 -
70 - return true;
71 - }
72 - return false;
73 - },
74 -
75 - /* Main body */
76 -
77 - /**
78 - * Encodes the string like PHP's rawurlencode
79 - *
80 - * @param String str string to be encoded
81 - */
82 - 'rawurlencode' : function (str) {
83 - str = (str + '').toString();
84 - return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28')
85 - .replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/~/g, '%7E');
86 - },
87 -
88 - /**
89 - * Encode pagetitles for use in a URL
90 - * We want / and : to be included as literal characters in our title URLs
91 - * as they otherwise fatally break the title
92 - *
93 - * @param String str string to be encoded
94 - */
95 - 'wikiUrlencode' : function (str) {
96 - return this.rawurlencode(str).replace(/%20/g, '_').replace(/%3A/g, ':').replace(/%2F/g, '/');
97 - },
98 -
99 - /**
100 - * Get the full url to a pagename
101 - *
102 - * @param String str pagename to link to
103 - */
104 - 'getWikilink' : function (str) {
105 - return wgServer + wgArticlePath.replace('$1', this.wikiUrlencode(str));
106 - },
107 -
108 - /**
109 - * Check is a variable is empty. Support for strings, booleans, arrays and objects.
110 - * String "0" is considered empty. String containing only whitespace (ie. " ") is considered not empty.
111 - *
112 - * @param Mixed v the variable to check for empty ness
113 - */
114 - 'isEmpty' : function (v) {
115 - var key;
116 - if (v === "" || v === 0 || v === "0" || v === null || v === false || typeof v === 'undefined') {
117 - return true;
118 - }
119 - if (v.length === 0) {
120 - return true;
121 - }
122 - if (typeof v === 'object') {
123 - for (key in v) {
124 - return false;
125 - }
126 - return true;
127 - }
128 - return false;
129 - },
130 -
131 -
132 - /**
133 - * Grabs the url parameter value for the given parameter
134 - * Returns null if not found
135 - *
136 - * @param String param paramter name
137 - * @param String url url to search through (optional)
138 - */
139 - 'getParamValue' : function (param, url) {
140 - url = url ? url : document.location.href;
141 - var re = new RegExp('[^#]*[&?]' + param + '=([^&#]*)'); // Get last match, stop at hash
142 - var m = re.exec(url);
143 - if (m && m.length > 1) {
144 - return decodeURIComponent(m[1]);
145 - }
146 - return null;
147 - },
148 -
149 - /**
150 - * Converts special characters to their HTML entities
151 - *
152 - * @param String str text to escape
153 - * @param Bool quotes if true escapes single and double quotes aswell (by default false)
154 - */
155 - 'htmlEscape' : function (str, quotes) {
156 - str = $('<div/>').text(str).html();
157 - if (typeof quotes === 'undefined') {
158 - quotes = false;
159 - }
160 - if (quotes === true) {
161 - str = str.replace(/'/g, '&#039;').replace(/"/g, '&quot;');
162 - }
163 - return str;
164 - },
165 -
166 - /**
167 - * Converts HTML entities back to text
168 - *
169 - * @param String str text to unescape
170 - */
171 - 'htmlUnescape' : function (str) {
172 - return $('<div/>').html(str).text();
173 - },
174 -
175 - // Access key prefix
176 - // will be re-defined based on browser/operating system detection in mw.util.init()
177 - 'tooltipAccessKeyPrefix' : 'alt-',
178 -
179 - // Regex to match accesskey tooltips
180 - 'tooltipAccessKeyRegexp': /\[(ctrl-)?(alt-)?(shift-)?(esc-)?(.)\]$/,
181 -
182 - /**
183 - * Add the appropriate prefix to the accesskey shown in the tooltip.
184 - * If the nodeList parameter is given, only those nodes are updated;
185 - * otherwise, all the nodes that will probably have accesskeys by
186 - * default are updated.
187 - *
188 - * @param Mixed nodeList jQuery object, or array of elements
189 - */
190 - 'updateTooltipAccessKeys' : function (nodeList) {
191 - var $nodes;
192 - if (nodeList instanceof jQuery) {
193 - $nodes = nodeList;
194 - } else if (nodeList) {
195 - $nodes = $(nodeList);
196 - } else {
197 - // Rather than scanning all links, just
198 - $('#column-one a, #mw-head a, #mw-panel a, #p-logo a');
199 -
200 - // these are rare enough that no such optimization is needed
201 - this.updateTooltipAccessKeys($('input'));
202 - this.updateTooltipAccessKeys($('label'));
203 - return;
204 - }
205 -
206 - $nodes.each(function (i) {
207 - var tip = $(this).attr('title');
208 - if (!!tip && mw.util.tooltipAccessKeyRegexp.exec(tip)) {
209 - tip = tip.replace(mw.util.tooltipAccessKeyRegexp, '[' + mw.util.tooltipAccessKeyPrefix + "$5]");
210 - $(this).attr('title', tip);
211 - }
212 - });
213 - },
214 -
215 - // jQuery object that refers to the page-content element
216 - // Populated by init()
217 - '$content' : null,
218 -
219 -
220 - /**
221 - * Add a link to a portlet menu on the page, such as:
222 - *
223 - * p-cactions (Content actions), p-personal (Personal tools), p-navigation (Navigation), p-tb (Toolbox)
224 - *
225 - * The first three paramters are required, others are optionals. Though
226 - * providing an id and tooltip is recommended.
227 - *
228 - * By default the new link will be added to the end of the list. To add the link before a given existing item,
229 - * pass the DOM node (document.getElementById('foobar') or the jQuery-selector ('#foobar') of that item.
230 - *
231 - * @example mw.util.addPortletLink('p-tb', 'http://mediawiki.org/', 'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org ', 'm', '#t-print')
232 - *
233 - * @param String portlet id of the target portlet ('p-cactions' or 'p-personal' etc.)
234 - * @param String href link URL
235 - * @param String text link text (will be automatically lowercased by CSS for p-cactions in Monobook)
236 - * @param String id id of the new item, should be unique and preferably have the appropriate prefix ('ca-', 'pt-', 'n-' or 't-')
237 - * @param String tooltip text to show when hovering over the link, without accesskey suffix
238 - * @param String accesskey accesskey to activate this link (one character, try to avoid conflicts. Use $('[accesskey=x').get() in the console to see if 'x' is already used.
239 - * @param mixed nextnode DOM node or jQuery-selector of the item that the new item should be added before, should be another item in the same list will be ignored if not the so
240 - *
241 - * @return Node the DOM node of the new item (a LI element, or A element for older skins) or null
242 - */
243 - 'addPortletLink' : function (portlet, href, text, id, tooltip, accesskey, nextnode) {
244 - var $link = $('<a />').attr('href', href).text(text);
245 -
246 - // Some skins don't have portlets
247 - // Just add it to the bottom of their 'sidebar' element ignoring the specified portlet target
248 - switch (skin) {
249 - case 'standard' :
250 - case 'cologneblue' :
251 - $("#quickbar").append($link.after('<br />'));
252 - return $link.get(0);
253 - case 'nostalgia' :
254 - $("#searchform").before($link).before(' &#124; ');
255 - return $link.get(0);
256 - default : // chick, modern, monobook, myskin, simple, vector...
257 -
258 - var $portlet = $('#' + portlet);
259 - if ($portlet.length === 0) {
260 - return null;
261 - }
262 - var $ul = $portlet.find('ul').eq(0);
263 - if ($ul.length === 0) {
264 - if ($portlet.find('div').length === 0) {
265 - $portlet.append('<ul />');
266 - } else {
267 - $portlet.find('div').eq(-1).append('<ul />');
268 - }
269 - $ul = $portlet.find('ul').eq(0);
270 - }
271 - if ($ul.length === 0) {
272 - return null;
273 - }
274 -
275 - // unhide portlet if it was hidden before
276 - $portlet.removeClass('emptyPortlet');
277 -
278 - var $item = $link.wrap('<li><span /></li>').parent().parent();
279 -
280 - if (id) {
281 - $item.attr('id', id);
282 - }
283 - if (accesskey) {
284 - $link.attr('accesskey', accesskey);
285 - tooltip += ' [' + accesskey + ']';
286 - }
287 - if (tooltip) {
288 - $link.attr('title', tooltip);
289 - }
290 - if (accesskey && tooltip) {
291 - this.updateTooltipAccessKeys($link);
292 - }
293 -
294 - // Append using DOM-element passing
295 - if (nextnode && nextnode.parentNode == $ul.get(0)) {
296 - $(nextnode).before($item);
297 - } else {
298 - // If the jQuery selector isn't found within the <ul>, just append it at the end
299 - if ($ul.find(nextnode).length === 0) {
300 - $ul.append($item);
301 - } else {
302 - // Append using jQuery CSS selector
303 - $ul.find(nextnode).eq(0).before($item);
304 - }
305 - }
306 -
307 - return $item.get(0);
308 - }
309 - }
310 -
311 - };
312 -
313 - mediaWiki.util.init();
314 -
315 -})(jQuery, mediaWiki);
\ No newline at end of file
Index: trunk/phase3/resources/mediawiki/mediawiki.utiltest.js
@@ -1,150 +0,0 @@
2 -/*
3 - * mediaWiki Debug Test Suit.
4 - * Available on "/Special:BlankPage?action=mwutiltest&debug=true")
5 - */
6 -
7 -(function ($, mw) {
8 -
9 - mediaWiki.test = {
10 -
11 - /* Variables */
12 - '$table' : null,
13 - 'addedTests' : [],
14 -
15 - /* Functions */
16 -
17 - /**
18 - * Adds a row to the test-table
19 - *
20 - * @param String code Code of the test to be executed
21 - * @param String result Expected result in 'var (vartype)' form
22 - * @param String contain Important part of the result, if result is different but does contain this it will not return ERROR but PARTIALLY
23 - */
24 - 'addTest' : function (code, result, contain) {
25 - if (!contain) {
26 - contain = result;
27 - }
28 - this.addedTests.push([code, result, contain]);
29 - this.$table.append('<tr><td>' + mw.util.htmlEscape(code) + '</td><td>' + mw.util.htmlEscape(result) + '<td></td></td><td>?</td></tr>');
30 - },
31 -
32 - /* Initialisation */
33 - 'initialised' : false,
34 - 'init' : function () {
35 - if (this.initialised === false) {
36 - this.initialised = true;
37 - $(function () {
38 - if (wgCanonicalSpecialPageName == 'Blankpage' && mw.util.getParamValue('action') === 'mwutiltest') {
39 -
40 - // Build page
41 - document.title = 'mediaWiki.util JavaScript Test - ' + wgSiteName;
42 - $('#firstHeading').text('mediaWiki.util JavaScript Test');
43 - mw.util.$content.html(
44 - '<p>Below is a list of tests to confirm proper functionality of the mediaWiki.util functions</p>' +
45 - '<hr />' +
46 - '<table id="mw-mwutiltest-table" class="wikitable sortable"><tr><th>Exec</th><th>Should return</th><th>Does return</th><th>Equal ?</th></tr></table>'
47 - );
48 - mw.test.$table = $('table#mw-mwutiltest-table');
49 -
50 - // Populate tests
51 - mw.test.addTest('typeof String.prototype.trim',
52 - 'function (string)');
53 - mw.test.addTest('typeof String.prototype.trimLeft',
54 - 'function (string)');
55 - mw.test.addTest('typeof String.prototype.trimRight',
56 - 'function (string)');
57 - mw.test.addTest('typeof Array.prototype.compare',
58 - 'function (string)');
59 - mw.test.addTest('typeof Array.prototype.indexOf',
60 - 'function (string)');
61 - mw.test.addTest('4',
62 - '4 (number)');
63 - mw.test.addTest('typeof mediaWiki',
64 - 'object (string)');
65 - mw.test.addTest('typeof mw',
66 - 'object (string)');
67 - mw.test.addTest('typeof mw.util',
68 - 'object (string)');
69 - mw.test.addTest('typeof String.prototype.ucFirst',
70 - 'function (string)');
71 - mw.test.addTest('\'mediawiki\'.ucFirst()',
72 - 'Mediawiki (string)');
73 - mw.test.addTest('typeof $.fn.enableCheckboxShiftClick',
74 - 'function (string)');
75 - mw.test.addTest('typeof mw.util.rawurlencode',
76 - 'function (string)');
77 - mw.test.addTest('mw.util.rawurlencode(\'Test: A&B/Here\')',
78 - 'Test%3A%20A%26B%2FHere (string)');
79 - mw.test.addTest('typeof mw.util.getWikilink',
80 - 'function (string)');
81 - mw.test.addTest('typeof mw.util.getParamValue',
82 - 'function (string)');
83 - mw.test.addTest('mw.util.getParamValue(\'action\')',
84 - 'mwutiltest (string)');
85 - mw.test.addTest('typeof mw.util.htmlEscape',
86 - 'function (string)');
87 - mw.test.addTest('mw.util.htmlEscape(\'<a href="http://mw.org/?a=b&c=d">link</a>\')',
88 - '&lt;a href="http://mw.org/?a=b&amp;c=d"&gt;link&lt;/a&gt; (string)');
89 - mw.test.addTest('typeof mw.util.htmlUnescape',
90 - 'function (string)');
91 - mw.test.addTest('mw.util.htmlUnescape(\'&lt;a href="http://mw.org/?a=b&amp;c=d"&gt;link&lt;/a&gt;\')',
92 - '<a href="http://mw.org/?a=b&c=d">link</a> (string)');
93 - mw.test.addTest('typeof mw.util.tooltipAccessKeyRegexp',
94 - 'function (string)');
95 - mw.test.addTest('typeof mw.util.updateTooltipAccessKeys',
96 - 'function (string)');
97 - mw.test.addTest('typeof mw.util.addPortletLink',
98 - 'function (string)');
99 - mw.test.addTest('typeof mw.util.addPortletLink("p-tb", "http://mediawiki.org/", "MediaWiki.org", "t-mworg", "Go to MediaWiki.org ", "m", "#t-print")',
100 - 'object (string)');
101 - mw.test.addTest('a = mw.util.addPortletLink("p-tb", "http://mediawiki.org/", "MediaWiki.org", "t-mworg", "Go to MediaWiki.org ", "m", "#t-print"); if(a){ a.outerHTML; }',
102 - '<li id="t-mworg"><span><a href="http://mediawiki.org/" accesskey="m" title="Go to MediaWiki.org [ctrl-alt-m]">MediaWiki.org</a></span></li> (string)',
103 - 'href="http://mediawiki.org/"');
104 -
105 - // Run tests and compare results
106 - var exec,
107 - result,
108 - resulttype,
109 - numberoftests = 0,
110 - numberofpasseds = 0,
111 - numberofpartials = 0,
112 - numberoferrors = 0,
113 - $testrows;
114 - $testrows = mw.test.$table.find('tr');
115 - $.each(mw.test.addedTests, (function (i) {
116 - numberoftests++;
117 -
118 - exec = mw.test.addedTests[i][0];
119 - shouldreturn = mw.test.addedTests[i][1];
120 - shouldcontain = mw.test.addedTests[i][2];
121 - doesreturn = eval(exec);
122 - doesreturn = doesreturn + ' (' + typeof doesreturn + ')';
123 - $thisrow = $testrows.eq(i + 1);
124 - $thisrow.find('> td').eq(2).text(doesreturn);
125 -
126 - if (doesreturn.indexOf(shouldcontain) !== -1) {
127 - if (doesreturn == shouldreturn){
128 - $thisrow.find('> td').eq(3).css('background', '#EFE').text('OK');
129 - numberofpasseds++;
130 - } else {
131 - $thisrow.find('> td').eq(3).css('background', '#FFE').html('<small>PARTIALLY</small>');
132 - numberofpartials++;
133 - }
134 - } else {
135 - $thisrow.find('> td').eq(3).css('background', '#FEE').text('ERROR');
136 - numberoferrors++;
137 - }
138 -
139 - })
140 - );
141 - mw.test.$table.before('<p><strong>Ran ' + numberoftests + ' tests. ' + numberofpasseds + ' passed test(s). ' + numberoferrors + ' error(s). ' + numberofpartials + ' partially passed test(s). </p>');
142 -
143 - }
144 - });
145 - }
146 - }
147 - };
148 -
149 - mediaWiki.test.init();
150 -
151 -})(jQuery, mediaWiki);
\ No newline at end of file
Index: trunk/phase3/resources/mediawiki/mediawiki.views.history.js
@@ -1,7 +0,0 @@
2 -/*
3 - * JavaScript for History view
4 - */
5 -
6 -// Replaces histrowinit
7 -$( '#pagehistory li input[name=diff], #pagehistory li input[name=oldid]' ).click( diffcheck );
8 -diffcheck();
\ No newline at end of file
Index: trunk/phase3/resources/mediawiki/mediawiki.js
@@ -3,178 +3,200 @@
44 */
55
66 // New fallback String trimming functionality, was introduced natively in JavaScript 1.8.1
7 -if (typeof String.prototype.trim === 'undefined') {
8 -// Add removing trailing and leading whitespace functionality cross-browser
9 -// See also: http://blog.stevenlevithan.com/archives/faster-trim-javascript
10 - String.prototype.trim = function () {
11 - return this.replace(/^\s+|\s+$/g, '');
 7+if ( typeof String.prototype.trim === 'undefined' ) {
 8+ // Add removing trailing and leading whitespace functionality cross-browser
 9+ // See also: http://blog.stevenlevithan.com/archives/faster-trim-javascript
 10+ String.prototype.trim = function() {
 11+ return this.replace( /^\s+|\s+$/g, '' );
1212 };
1313 }
14 -if (typeof String.prototype.trimLeft === 'undefined') {
15 - String.prototype.trimLeft = function () {
16 - return this.replace(/^\s\s*/, "");
 14+if ( typeof String.prototype.trimLeft === 'undefined' ) {
 15+ String.prototype.trimLeft = function() {
 16+ return this.replace( /^\s\s*/, "" );
1717 };
1818 }
1919
20 -if (typeof String.prototype.trimRight === 'undefined') {
21 - String.prototype.trimRight = function () {
 20+if ( typeof String.prototype.trimRight === 'undefined' ) {
 21+ String.prototype.trimRight = function() {
2222 return this.replace(/\s\s*$/, "");
2323 };
2424 }
2525
26 -// Add array comparison functionality
27 -if (typeof Array.prototype.compare === 'undefined') {
28 - Array.prototype.compare = function (against) {
29 - if (this.length !== against.length) {
30 - return false;
31 - }
32 - for (var i = 0; i < against.length; i++) {
33 - if (this[i].compare) {
34 - if (!this[i].compare(against[i])) {
35 - return false;
36 - }
37 - }
38 - if (this[i] !== against[i]) {
39 - return false;
40 - }
41 - }
42 - return true;
43 - };
44 -}
45 -
46 -// Make calling .indexOf() on an array work on older browsers
47 -if (typeof Array.prototype.indexOf === 'undefined') {
48 - Array.prototype.indexOf = function (needle) {
49 - for (var i = 0; i < this.length; i++) {
50 - if (this[i] === needle) {
51 - return i;
52 - }
53 - }
54 - return -1;
55 - };
56 -}
57 -
5826 /*
5927 * Core MediaWiki JavaScript Library
6028 */
 29+
6130 // Attach to window
6231 window.mediaWiki = new ( function( $ ) {
63 -
 32+
6433 /* Constants */
65 -
 34+
6635 // This will not change until we are 100% ready to turn off legacy globals
6736 var LEGACY_GLOBALS = true;
68 -
 37+
6938 /* Private Members */
70 -
71 - var that = this;
72 -
 39+
 40+ // List of messages that have been requested to be loaded
 41+ var messageQueue = {};
 42+
7343 /* Prototypes */
74 -
75 - this.prototypes = {
76 - /*
77 - * An object which allows single and multiple get/set/exists functionality on a list of key / value pairs
78 - *
79 - * @param {boolean} global whether to get/set/exists values on the window object or a private object
80 - * @param {function} parser function to perform extra processing; in the form of function( value, options )
81 - * @param {function} fallback function to format default fallback; in the form of function( key )
82 - * where value is the data to be parsed and options is additional data passed through to the parser
83 - */
84 - 'map': function( global, parser, fallback ) {
85 -
86 - /* Private Members */
87 -
88 - var that = this;
89 - var values = global === true ? window : {};
90 -
91 - /* Public Methods */
92 -
93 - /**
94 - * Gets one or more values
95 - *
96 - * If called with no arguments, all values will be returned. If a parser is in use, no parsing will take
97 - * place when calling with no arguments or calling with an array of names.
98 - *
99 - * @param {mixed} selection string name of value to get, array of string names of values to get, or object
100 - * of name/option pairs
101 - * @param {object} options optional set of options which are also passed to a parser if in use; only used
102 - * when selection is a string
103 - * @format options
104 - * {
105 - * // Value to use if key does not exist
106 - * 'fallback': ''
107 - * }
108 - */
109 - this.get = function( selection, options ) {
110 - if ( typeof selection === 'object' ) {
111 - var results = {};
112 - for ( var s in selection ) {
113 - if ( selection.hasOwnProperty( s ) ) {
114 - if ( typeof s === 'string' ) {
115 - return that.get( values[s], selection[s] );
116 - } else {
117 - return that.get( selection[s] );
118 - }
119 - }
120 - }
121 - return results;
122 - } else if ( typeof selection === 'string' ) {
123 - if ( typeof values[selection] === 'undefined' ) {
124 - if ( typeof options === 'object' && 'fallback' in options ) {
125 - return options.fallback;
126 - } else if ( typeof fallback === 'function' ) {
127 - return fallback( selection );
128 - } else {
129 - return null;
130 - }
131 - } else {
132 - if ( typeof parser === 'function' ) {
133 - return parser( values[selection], options );
134 - } else {
135 - return values[selection];
136 - }
137 - }
138 - } else {
139 - return values;
 44+
 45+ /**
 46+ * An object which allows single and multiple get/set/exists functionality on a list of key / value pairs.
 47+ *
 48+ * @param {boolean} global Whether to get/set/exists values on the window object or a private object
 49+ */
 50+ function Map( global ) {
 51+ this.values = ( global === true ) ? window : {};
 52+ };
 53+
 54+ /**
 55+ * Gets the value of a key, or a list of key/value pairs for an array of keys.
 56+ *
 57+ * If called with no arguments, all values will be returned.
 58+ *
 59+ * @param {mixed} selection Key or array of keys to get values for
 60+ * @param {mixed} fallback Value to use in case key(s) do not exist (optional)
 61+ */
 62+ Map.prototype.get = function( selection, fallback ) {
 63+ if ( typeof selection === 'object' ) {
 64+ selection = $.makeArray( selection );
 65+ var results = {};
 66+ for ( var i = 0; i < selection.length; i++ ) {
 67+ results[selection[i]] = this.get( selection[i], fallback );
 68+ }
 69+ return results;
 70+ } else if ( typeof selection === 'string' ) {
 71+ if ( typeof this.values[selection] === 'undefined' ) {
 72+ if ( typeof fallback !== 'undefined' ) {
 73+ return fallback;
14074 }
141 - };
142 -
143 - /**
144 - * Sets one or multiple configuration values using a key and a value or an object of keys and values
145 - *
146 - * @param {mixed} key string of name by which value will be made accessible, or object of name/value pairs
147 - * @param {mixed} value optional value to set, only in use when key is a string
148 - */
149 - this.set = function( selection, value ) {
150 - if ( typeof selection === 'object' ) {
151 - for ( var s in selection ) {
152 - values[s] = selection[s];
153 - }
154 - } else if ( typeof selection === 'string' && typeof value !== 'undefined' ) {
155 - values[selection] = value;
 75+ return null;
 76+ }
 77+ return this.values[selection];
 78+ }
 79+ return this.values;
 80+ };
 81+
 82+ /**
 83+ * Sets one or multiple key/value pairs.
 84+ *
 85+ * @param {mixed} selection Key or object of key/value pairs to set
 86+ * @param {mixed} value Value to set (optional, only in use when key is a string)
 87+ */
 88+ Map.prototype.set = function( selection, value ) {
 89+ if ( typeof selection === 'object' ) {
 90+ for ( var s in selection ) {
 91+ this.values[s] = selection[s];
 92+ }
 93+ } else if ( typeof selection === 'string' && typeof value !== 'undefined' ) {
 94+ this.values[selection] = value;
 95+ }
 96+ };
 97+
 98+ /**
 99+ * Checks if one or multiple keys exist.
 100+ *
 101+ * @param {mixed} key Key or array of keys to check
 102+ * @return {boolean} Existence of key(s)
 103+ */
 104+ Map.prototype.exists = function( selection ) {
 105+ if ( typeof keys === 'object' ) {
 106+ for ( var s = 0; s < selection.length; s++ ) {
 107+ if ( !( selection[s] in this.values ) ) {
 108+ return false;
156109 }
157 - };
158 -
159 - /**
160 - * Checks if one or multiple configuration fields exist
161 - */
162 - this.exists = function( selection ) {
163 - if ( typeof keys === 'object' ) {
164 - for ( var s = 0; s < selection.length; s++ ) {
165 - if ( !( selection[s] in values ) ) {
166 - return false;
167 - }
168 - }
169 - return true;
170 - } else {
171 - return selection in values;
172 - }
173 - };
 110+ }
 111+ return true;
 112+ } else {
 113+ return selection in this.values;
174114 }
175115 };
 116+
 117+ /**
 118+ * Message object, similar to Message in PHP
 119+ */
 120+ function Message( map, key, parameters ) {
 121+ this.format = 'parse';
 122+ this.map = map;
 123+ this.key = key;
 124+ this.parameters = typeof parameters === 'undefined' ? [] : $.makeArray( parameters );
 125+ };
 126+
 127+ /**
 128+ * Appends parameters for replacement
 129+ *
 130+ * @param {mixed} args First in a list of variadic arguments to append as message parameters
 131+ */
 132+ Message.prototype.params = function( parameters ) {
 133+ for ( var i = 0; i < parameters.length; i++ ) {
 134+ this.parameters[this.parameters.length] = parameters[i];
 135+ }
 136+ return this;
 137+ };
 138+
 139+ /**
 140+ * Converts message object to it's string form based on the state of format
 141+ *
 142+ * @return {string} String form of message
 143+ */
 144+ Message.prototype.toString = function() {
 145+ if ( !this.map.exists( this.key ) ) {
 146+ // Return <key> if key does not exist
 147+ return '<' + key + '>';
 148+ }
 149+ var text = this.map.get( this.key );
 150+ var parameters = this.parameters;
 151+ text = text.replace( /\$(\d+)/g, function( string, match ) {
 152+ var index = parseInt( match, 10 ) - 1;
 153+ return index in parameters ? parameters[index] : '$' + match;
 154+ } );
 155+ /* This should be fixed up when we have a parser
 156+ if ( this.format === 'parse' && 'language' in mediaWiki ) {
 157+ text = mediaWiki.language.parse( text );
 158+ }
 159+ */
 160+ return text;
 161+ };
 162+
 163+ /**
 164+ * Changes format to parse and converts message to string
 165+ *
 166+ * @return {string} String form of parsed message
 167+ */
 168+ Message.prototype.parse = function() {
 169+ this.format = 'parse';
 170+ return this.toString();
 171+ };
 172+
 173+ /**
 174+ * Changes format to plain and converts message to string
 175+ *
 176+ * @return {string} String form of plain message
 177+ */
 178+ Message.prototype.plain = function() {
 179+ this.format = 'plain';
 180+ return this.toString();
 181+ };
 182+
 183+ /**
 184+ * Checks if message exists
 185+ *
 186+ * @return {string} String form of parsed message
 187+ */
 188+ Message.prototype.exists = function() {
 189+ return this.map.exists( this.key );
 190+ };
 191+
 192+ /**
 193+ * User object
 194+ */
 195+ function User() {
 196+ this.options = new Map();
 197+ }
 198+
 199+ /* Public Members */
176200
177 - /* Methods */
178 -
179201 /*
180202 * Dummy function which in debug mode can be replaced with a function that does something clever
181203 */
@@ -185,37 +207,38 @@
186208 *
187209 * In legacy mode the values this object wraps will be in the global space
188210 */
189 - this.config = new this.prototypes.map( LEGACY_GLOBALS );
 211+ this.config = new Map( LEGACY_GLOBALS );
190212
191213 /*
192214 * Information about the current user
193215 */
194 - this.user = new ( function() {
195 -
196 - /* Public Members */
197 -
198 - this.options = new that.prototypes.map();
199 - } )();
200 -
 216+ this.user = new User();
 217+
201218 /*
202 - * Basic parser, can be replaced with something more robust
 219+ * Localization system
203220 */
204 - this.parser = function( text, options ) {
205 - if ( typeof options === 'object' && typeof options.parameters === 'object' ) {
206 - text = text.replace( /\$(\d+)/g, function( str, match ) {
207 - var index = parseInt( match, 10 ) - 1;
208 - return index in options.parameters ? options.parameters[index] : '$' + match;
209 - } );
 221+ this.messages = new Map();
 222+
 223+ /* Public Methods */
 224+
 225+ /**
 226+ * Gets a message object, similar to wfMessage()
 227+ *
 228+ * @param {string} key Key of message to get
 229+ * @param {mixed} params First argument in a list of variadic arguments, each a parameter for $ replacement
 230+ */
 231+ this.message = function( key, parameters ) {
 232+ // Support variadic arguments
 233+ if ( typeof parameters !== 'undefined' ) {
 234+ parameters = $.makeArray( arguments);
 235+ parameters.shift();
 236+ } else {
 237+ parameters = [];
210238 }
211 - return text;
 239+ return new Message( mediaWiki.messages, key, parameters );
212240 };
213 -
214 - /*
215 - * Localization system
216 - */
217 - this.msg = new that.prototypes.map( false, this.parser, function( key ) { return '<' + key + '>'; } );
218 -
219 - /*
 241+
 242+ /**
220243 * Client-side module loader which integrates with the MediaWiki ResourceLoader
221244 */
222245 this.loader = new ( function() {
@@ -223,7 +246,7 @@
224247 /* Private Members */
225248
226249 var that = this;
227 - /*
 250+ /**
228251 * Mapping of registered modules
229252 *
230253 * The jquery module is pre-registered, because it must have already been provided for this object to have
@@ -256,6 +279,23 @@
257280
258281 /* Private Methods */
259282
 283+ function compare( a, b ) {
 284+ if ( a.length != b.length ) {
 285+ return false;
 286+ }
 287+ for ( var i = 0; i < b.length; i++ ) {
 288+ if ( $.isArray( a[i] ) ) {
 289+ if ( !compare( a[i], b[i] ) ) {
 290+ return false;
 291+ }
 292+ }
 293+ if ( a[i] !== b[i] ) {
 294+ return false;
 295+ }
 296+ }
 297+ return true;
 298+ };
 299+
260300 /**
261301 * Generates an ISO8601 "basic" string from a UNIX timestamp
262302 */
@@ -275,7 +315,9 @@
276316 * Recursively resolves dependencies and detects circular references
277317 */
278318 function recurse( module, resolved, unresolved ) {
279 - unresolved[unresolved.length] = module;
 319+ if ( typeof registry[module] === 'undefined' ) {
 320+ throw new Error( 'Unknown dependency: ' + module );
 321+ }
280322 // Resolves dynamic loader function and replaces it with it's own results
281323 if ( typeof registry[module].dependencies === 'function' ) {
282324 registry[module].dependencies = registry[module].dependencies();
@@ -286,8 +328,8 @@
287329 }
288330 // Tracks down dependencies
289331 for ( var n = 0; n < registry[module].dependencies.length; n++ ) {
290 - if ( resolved.indexOf( registry[module].dependencies[n] ) === -1 ) {
291 - if ( unresolved.indexOf( registry[module].dependencies[n] ) !== -1 ) {
 332+ if ( $.inArray( registry[module].dependencies[n], resolved ) === -1 ) {
 333+ if ( $.inArray( registry[module].dependencies[n], unresolved ) !== -1 ) {
292334 throw new Error(
293335 'Circular reference detected: ' + module + ' -> ' + registry[module].dependencies[n]
294336 );
@@ -296,7 +338,7 @@
297339 }
298340 }
299341 resolved[resolved.length] = module;
300 - unresolved.splice( unresolved.indexOf( module ), 1 );
 342+ unresolved.splice( $.inArray( module, unresolved ), 1 );
301343 }
302344
303345 /**
@@ -391,7 +433,7 @@
392434 }
393435 // Add localizations to message system
394436 if ( typeof registry[module].messages === 'object' ) {
395 - mediaWiki.msg.set( registry[module].messages );
 437+ mediaWiki.messages.set( registry[module].messages );
396438 }
397439 // Execute script
398440 try {
@@ -399,7 +441,7 @@
400442 registry[module].state = 'ready';
401443 // Run jobs who's dependencies have just been met
402444 for ( var j = 0; j < jobs.length; j++ ) {
403 - if ( filter( 'ready', jobs[j].dependencies ).compare( jobs[j].dependencies ) ) {
 445+ if ( compare( filter( 'ready', jobs[j].dependencies ), jobs[j].dependencies ) ) {
404446 if ( typeof jobs[j].ready === 'function' ) {
405447 jobs[j].ready();
406448 }
@@ -410,7 +452,7 @@
411453 // Execute modules who's dependencies have just been met
412454 for ( r in registry ) {
413455 if ( registry[r].state == 'loaded' ) {
414 - if ( filter( ['ready'], registry[r].dependencies ).compare( registry[r].dependencies ) ) {
 456+ if ( compare( filter( ['ready'], registry[r].dependencies ), registry[r].dependencies ) ) {
415457 execute( r );
416458 }
417459 }
@@ -421,7 +463,7 @@
422464 registry[module].state = 'error';
423465 // Run error callbacks of jobs affected by this condition
424466 for ( var j = 0; j < jobs.length; j++ ) {
425 - if ( jobs[j].dependencies.indexOf( module ) !== -1 ) {
 467+ if ( $.inArray( module, jobs[j].dependencies ) !== -1 ) {
426468 if ( typeof jobs[j].error === 'function' ) {
427469 jobs[j].error();
428470 }
@@ -460,7 +502,7 @@
461503 // Queue up any dependencies that are undefined or registered
462504 dependencies = filter( ['undefined', 'registered'], dependencies );
463505 for ( var n = 0; n < dependencies.length; n++ ) {
464 - if ( queue.indexOf( dependencies[n] ) === -1 ) {
 506+ if ( $.inArray( dependencies[n], queue ) === -1 ) {
465507 queue[queue.length] = dependencies[n];
466508 }
467509 }
@@ -493,7 +535,7 @@
494536 // Only request modules which are undefined or registered
495537 if ( !( queue[q] in registry ) || registry[queue[q]].state == 'registered' ) {
496538 // Prevent duplicate entries
497 - if ( batch.indexOf( queue[q] ) === -1 ) {
 539+ if ( $.inArray( queue[q], batch ) === -1 ) {
498540 batch[batch.length] = queue[q];
499541 // Mark registered modules as loading
500542 if ( queue[q] in registry ) {
@@ -633,7 +675,7 @@
634676 registry[module].messages = localization;
635677 }
636678 // Execute or queue callback
637 - if ( filter( ['ready'], registry[module].dependencies ).compare( registry[module].dependencies ) ) {
 679+ if ( compare( filter( ['ready'], registry[module].dependencies ), registry[module].dependencies ) ) {
638680 execute( module );
639681 } else {
640682 request( module );
@@ -660,7 +702,7 @@
661703 // Resolve entire dependency map
662704 dependencies = resolve( dependencies );
663705 // If all dependencies are met, execute ready immediately
664 - if ( filter( ['ready'], dependencies ).compare( dependencies ) ) {
 706+ if ( compare( filter( ['ready'], dependencies ), dependencies ) ) {
665707 if ( typeof ready === 'function' ) {
666708 ready();
667709 }
@@ -714,7 +756,7 @@
715757 // Resolve entire dependency map
716758 modules = resolve( modules );
717759 // If all modules are ready, nothing dependency be done
718 - if ( filter( ['ready'], modules ).compare( modules ) ) {
 760+ if ( compare( filter( ['ready'], modules ), modules ) ) {
719761 return true;
720762 }
721763 // If any modules have errors return false
Index: trunk/phase3/resources/mediawiki.language/mediawiki.language.js
@@ -0,0 +1,99 @@
 2+/**
 3+ * Base language object
 4+ *
 5+ * Localized Language support attempts to mirror some of the functionality of Language.php in MediaWiki. This object
 6+ * contains methods for loading and transforming message text.
 7+ */
 8+
 9+mediaWiki.language = {
 10+ /**
 11+ * Process the PLURAL template substitution
 12+ *
 13+ * @param {object} template Template object
 14+ * @format template
 15+ * {
 16+ * 'title': [title of template],
 17+ * 'parameters': [template parameters]
 18+ * }
 19+ * @example {{Template:title|params}}
 20+ */
 21+ 'procPLURAL': function( template ) {
 22+ if( template.title && template.parameters && mediaWiki.language.convertPlural) {
 23+ // Check if we have forms to replace
 24+ if ( template.parameters.length == 0 ) {
 25+ return '';
 26+ }
 27+ // Restore the count into a Number ( if it got converted earlier )
 28+ var count = mediaWiki.language.convertNumber( template.title, true );
 29+ // Do convertPlural call
 30+ return mediaWiki.language.convertPlural( parseInt( count ), template.parameters );
 31+ }
 32+ // Could not process plural return first form or nothing
 33+ if( template.parameters[0] ) {
 34+ return template.parameters[0];
 35+ }
 36+ return '';
 37+ },
 38+ /**
 39+ * Plural form transformations, needed for some languages.
 40+ *
 41+ * @param {integer} count Non-localized quantifier
 42+ * @param {array} forms List of plural forms
 43+ * @return {string} Correct form for quantifier in this language
 44+ */
 45+ 'convertPlural': function( count, forms ){
 46+ if ( !forms || forms.length == 0 ) {
 47+ return '';
 48+ }
 49+ return ( parseInt( count ) == 1 ) ? forms[0] : forms[1];
 50+ },
 51+ /**
 52+ * Pads an array to a specific length by copying the last one element.
 53+ *
 54+ * @param {array} forms Number of forms given to convertPlural
 55+ * @param {integer} count Number of forms required
 56+ * @return {array} Padded array of forms
 57+ */
 58+ 'preConvertPlural': function( forms, count ) {
 59+ while ( forms.length < count ) {
 60+ forms.push( forms[ forms.length-1 ] );
 61+ }
 62+ return forms;
 63+ },
 64+ /**
 65+ * Converts a number using digitTransformTable.
 66+ *
 67+ * @param {number} number Value to be converted
 68+ * @param {boolean} integer Convert the return value to an integer
 69+ */
 70+ 'convertNumber': function( number, integer ) {
 71+ if ( !mediaWiki.language.digitTransformTable ) {
 72+ return number;
 73+ }
 74+ // Set the target Transform table:
 75+ var transformTable = mediaWiki.language.digitTransformTable;
 76+ // Check if the "restore" to Latin number flag is set:
 77+ if ( integer ) {
 78+ if ( parseInt( number ) == number ) {
 79+ return number;
 80+ }
 81+ var tmp = [];
 82+ for ( var i in transformTable ) {
 83+ tmp[ transformTable[ i ] ] = i;
 84+ }
 85+ transformTable = tmp;
 86+ }
 87+ var numberString = '' + number;
 88+ var convertedNumber = '';
 89+ for ( var i = 0; i < numberString.length; i++ ) {
 90+ if ( transformTable[ numberString[i] ] ) {
 91+ convertedNumber += transformTable[numberString[i]];
 92+ } else {
 93+ convertedNumber += numberString[i];
 94+ }
 95+ }
 96+ return integer ? parseInt( convertedNumber) : convertedNumber;
 97+ },
 98+ // Digit Transform Table, populated by language classes where applicable
 99+ 'digitTransformTable': null
 100+};
Property changes on: trunk/phase3/resources/mediawiki.language/mediawiki.language.js
___________________________________________________________________
Added: svn:mime-type
1101 + text/plain
Added: svn:eol-style
2102 + native
Index: trunk/phase3/resources/mediawiki.language/languages/bs.js
@@ -0,0 +1,20 @@
 2+/**
 3+ * Bosnian (bosanski) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 8+ if ( count > 10 && Math.floor( ( count % 100 ) / 10 ) == 1 ) {
 9+ return forms[2];
 10+ }
 11+ switch ( count % 10 ) {
 12+ case 1:
 13+ return forms[0];
 14+ case 2:
 15+ case 3:
 16+ case 4:
 17+ return forms[1];
 18+ default:
 19+ return forms[2];
 20+ }
 21+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/bs.js
___________________________________________________________________
Added: svn:mime-type
122 + text/plain
Added: svn:eol-style
223 + native
Index: trunk/phase3/resources/mediawiki.language/languages/cs.js
@@ -0,0 +1,19 @@
 2+/**
 3+ * Czech (ƒçe≈°tina [subst.], ƒçesk√Ω [adj.], ƒçesky [adv.]) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 8+ switch ( count ) {
 9+ case 1:
 10+ return forms[0];
 11+ break;
 12+ case 2:
 13+ case 3:
 14+ case 4:
 15+ return forms[1];
 16+ break;
 17+ default:
 18+ return forms[2];
 19+ }
 20+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/cs.js
___________________________________________________________________
Added: svn:mime-type
121 + text/plain
Added: svn:eol-style
222 + native
Index: trunk/phase3/resources/mediawiki.language/languages/mk.js
@@ -0,0 +1,8 @@
 2+/**
 3+ * Macedonian (Македонски) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 2 );
 8+ return ( count % 10 === 1 ) ? forms[0] : forms[1];
 9+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/mk.js
___________________________________________________________________
Added: svn:mime-type
110 + text/plain
Added: svn:eol-style
211 + native
Index: trunk/phase3/resources/mediawiki.language/languages/cu.js
@@ -0,0 +1,18 @@
 2+/**
 3+ * Old Church Slavonic (—®–∑—ã–∫—ä —Å–ª–æ–≤—£–Ω—å—Å–∫—ä) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 4 );
 8+ switch ( count % 10 ) {
 9+ case 1:
 10+ return forms[0];
 11+ case 2:
 12+ return forms[1];
 13+ case 3:
 14+ case 4:
 15+ return forms[2];
 16+ default:
 17+ return forms[3];
 18+ }
 19+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/cu.js
___________________________________________________________________
Added: svn:mime-type
120 + text/plain
Added: svn:eol-style
221 + native
Index: trunk/phase3/resources/mediawiki.language/languages/se.js
@@ -0,0 +1,17 @@
 2+/**
 3+ * Northern Sami (Sámegiella) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ if ( count == 0 ) {
 8+ return '';
 9+ }
 10+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 11+ if ( count == 1 ) {
 12+ return forms[1];
 13+ }
 14+ if ( count == 2 ) {
 15+ return forms[2];
 16+ }
 17+ return ''
 18+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/se.js
___________________________________________________________________
Added: svn:mime-type
119 + text/plain
Added: svn:eol-style
220 + native
Index: trunk/phase3/resources/mediawiki.language/languages/wa.js
@@ -0,0 +1,8 @@
 2+/**
 3+ * Walloon (Walon) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 2 );
 8+ return ( count <= 1 ) ? forms[0] : forms[1];
 9+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/wa.js
___________________________________________________________________
Added: svn:mime-type
110 + text/plain
Added: svn:eol-style
211 + native
Index: trunk/phase3/resources/mediawiki.language/languages/dsb.js
@@ -0,0 +1,18 @@
 2+/**
 3+ * Lower Sorbian (Dolnoserbski) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 4 );
 8+ switch ( Math.abs( count ) % 100 ) {
 9+ case 1:
 10+ return forms[0];
 11+ case 2:
 12+ return forms[1];
 13+ case 3:
 14+ case 4:
 15+ return forms[2];
 16+ default:
 17+ return forms[3];
 18+ }
 19+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/dsb.js
___________________________________________________________________
Added: svn:mime-type
120 + text/plain
Added: svn:eol-style
221 + native
Index: trunk/phase3/resources/mediawiki.language/languages/be-tarask.js
@@ -0,0 +1,23 @@
 2+/**
 3+ * Belarusian in Tara≈°kievica orthography (–ë–µ–ª–∞—Ä—É—Å–∫–∞—è —Ç–∞—Ä–∞—à–∫–µ–≤—ñ—Ü–∞) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ if ( forms.length === 2 ) {
 8+ return count == 1 ? forms[0] : forms[1];
 9+ }
 10+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 11+ if ( count > 10 && Math.floor( ( count % 100 ) / 10 ) == 1 ) {
 12+ return forms[2];
 13+ }
 14+ switch ( count % 10 ) {
 15+ case 1:
 16+ return forms[0];
 17+ case 2:
 18+ case 3:
 19+ case 4:
 20+ return forms[1];
 21+ default:
 22+ return forms[2];
 23+ }
 24+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/be-tarask.js
___________________________________________________________________
Added: svn:mime-type
125 + text/plain
Added: svn:eol-style
226 + native
Index: trunk/phase3/resources/mediawiki.language/languages/sr-ec.js
@@ -0,0 +1,20 @@
 2+/**
 3+ * Serbian (cyrillic script) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 8+ if ( count > 10 && Math.floor( ( count % 100 ) / 10 ) == 1 ) {
 9+ return forms[2];
 10+ }
 11+ switch ( count % 10 ) {
 12+ case 1:
 13+ return forms[0];
 14+ case 2:
 15+ case 3:
 16+ case 4:
 17+ return forms[1];
 18+ default:
 19+ return forms[2];
 20+ }
 21+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/sr-ec.js
___________________________________________________________________
Added: svn:mime-type
122 + text/plain
Added: svn:eol-style
223 + native
Index: trunk/phase3/resources/mediawiki.language/languages/mo.js
@@ -0,0 +1,14 @@
 2+/**
 3+ * Moldavian (Молдовеняскэ) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 8+ if ( count == 1 ) {
 9+ return forms[0];
 10+ }
 11+ if ( count == 0 || count % 100 < 20 ) {
 12+ return forms[1];
 13+ }
 14+ return forms[2];
 15+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/mo.js
___________________________________________________________________
Added: svn:mime-type
116 + text/plain
Added: svn:eol-style
217 + native
Index: trunk/phase3/resources/mediawiki.language/languages/cy.js
@@ -0,0 +1,15 @@
 2+/**
 3+ * Welsh (Cymraeg) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 6 );
 8+ count = Math.abs( count );
 9+ if ( count >= 0 && count <= 3 ) {
 10+ return forms[count];
 11+ }
 12+ if ( count == 6 ) {
 13+ return forms[4];
 14+ }
 15+ return forms[5];
 16+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/cy.js
___________________________________________________________________
Added: svn:mime-type
117 + text/plain
Added: svn:eol-style
218 + native
Index: trunk/phase3/resources/mediawiki.language/languages/hsb.js
@@ -0,0 +1,18 @@
 2+/**
 3+ * Upper Sorbian (Hornjoserbsce) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 4 );
 8+ switch ( Math.abs( count ) % 100 ) {
 9+ case 1:
 10+ return forms[0];
 11+ case 2:
 12+ return forms[1];
 13+ case 3:
 14+ case 4:
 15+ return forms[2];
 16+ default:
 17+ return forms[3];
 18+ }
 19+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/hsb.js
___________________________________________________________________
Added: svn:mime-type
120 + text/plain
Added: svn:eol-style
221 + native
Index: trunk/phase3/resources/mediawiki.language/languages/ti.js
@@ -0,0 +1,8 @@
 2+/**
 3+ * Tigrinya (ትግርኛ) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural(forms, 2);
 8+ return (count <= 1) ? forms[0] : forms[1];
 9+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/ti.js
___________________________________________________________________
Added: svn:mime-type
110 + text/plain
Added: svn:eol-style
211 + native
Index: trunk/phase3/resources/mediawiki.language/languages/sk.js
@@ -0,0 +1,14 @@
 2+/**
 3+ * Slovak (Slovenƒçina) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 8+ if ( count == 1 ) {
 9+ return forms[0];
 10+ }
 11+ if ( count == 2 || count == 3 || count == 4 ) {
 12+ return forms[1];
 13+ }
 14+ return forms[2];
 15+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/sk.js
___________________________________________________________________
Added: svn:mime-type
116 + text/plain
Added: svn:eol-style
217 + native
Index: trunk/phase3/resources/mediawiki.language/languages/uk.js
@@ -0,0 +1,23 @@
 2+/**
 3+ * Ukrainian (—É–∫—Ä–∞—ó–Ω—Å—å–∫–∞ –º–æ–≤–∞) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ if ( forms.length === 2 ) {
 8+ return count == 1 ? forms[0] : forms[1];
 9+ }
 10+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 11+ if ( count > 10 && Math.floor( ( count % 100 ) / 10 ) == 1 ) {
 12+ return forms[2];
 13+ }
 14+ switch ( count % 10 ) {
 15+ case 1:
 16+ return forms[0];
 17+ case 2:
 18+ case 3:
 19+ case 4:
 20+ return forms[1];
 21+ default:
 22+ return forms[2];
 23+ }
 24+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/uk.js
___________________________________________________________________
Added: svn:mime-type
125 + text/plain
Added: svn:eol-style
226 + native
Index: trunk/phase3/resources/mediawiki.language/languages/sma.js
@@ -0,0 +1,14 @@
 2+/**
 3+ * Southern Sami (Åarjelsaemien) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 4 );
 8+ if ( count == 1 ) {
 9+ return forms[1];
 10+ }
 11+ if ( count == 2 ) {
 12+ return forms[2];
 13+ }
 14+ return forms[3];
 15+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/sma.js
___________________________________________________________________
Added: svn:mime-type
116 + text/plain
Added: svn:eol-style
217 + native
Index: trunk/phase3/resources/mediawiki.language/languages/hy.js
@@ -0,0 +1,8 @@
 2+/**
 3+ * Armenian (’Ä’°’µ’•÷Ä’•’∂) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 2 );
 8+ return ( Math.abs( count ) <= 1 ) ? forms[0] : forms[1];
 9+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/hy.js
___________________________________________________________________
Added: svn:mime-type
110 + text/plain
Added: svn:eol-style
211 + native
Index: trunk/phase3/resources/mediawiki.language/languages/ro.js
@@ -0,0 +1,14 @@
 2+/**
 3+ * Romanian (Română) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 8+ if ( count == 1 ) {
 9+ return forms[0];
 10+ }
 11+ if ( count == 0 || count % 100 < 20 ) {
 12+ return forms[1];
 13+ }
 14+ return forms[2];
 15+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/ro.js
___________________________________________________________________
Added: svn:mime-type
116 + text/plain
Added: svn:eol-style
217 + native
Index: trunk/phase3/resources/mediawiki.language/languages/pt-br.js
@@ -0,0 +1,8 @@
 2+/**
 3+ * Brazilian Portugese (Portugu√™si do Brasil) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 2 );
 8+ return ( count <= 1 ) ? forms[0] : forms[1];
 9+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/pt-br.js
___________________________________________________________________
Added: svn:mime-type
110 + text/plain
Added: svn:eol-style
211 + native
Index: trunk/phase3/resources/mediawiki.language/languages/ru.js
@@ -0,0 +1,23 @@
 2+/**
 3+ * Russian (—Ä—É—Å—Å–∫–∏–π —è–∑—ã–∫) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ if ( forms.length === 2 ) {
 8+ return count == 1 ? forms[0] : forms[1];
 9+ }
 10+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 11+ if ( count > 10 && Math.floor( ( count % 100 ) / 10 ) == 1 ) {
 12+ return forms[2];
 13+ }
 14+ switch ( count % 10 ) {
 15+ case 1:
 16+ return forms[0];
 17+ case 2:
 18+ case 3:
 19+ case 4:
 20+ return forms[1];
 21+ default:
 22+ return forms[2];
 23+ }
 24+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/ru.js
___________________________________________________________________
Added: svn:mime-type
125 + text/plain
Added: svn:eol-style
226 + native
Index: trunk/phase3/resources/mediawiki.language/languages/bh.js
@@ -0,0 +1,8 @@
 2+/**
 3+ * Bihari (भोजपुरी) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 2 );
 8+ return ( count <= 1 ) ? forms[0] : forms[1];
 9+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/bh.js
___________________________________________________________________
Added: svn:mime-type
110 + text/plain
Added: svn:eol-style
211 + native
Index: trunk/phase3/resources/mediawiki.language/languages/gd.js
@@ -0,0 +1,18 @@
 2+/**
 3+ * Scots Gaelic (G√†idhlig) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 4 );
 8+ count = Math.abs( count );
 9+ if ( count === 1 ) {
 10+ return forms[0];
 11+ }
 12+ if ( count === 2 ) {
 13+ return forms[1];
 14+ }
 15+ if ( count >= 3 && count <= 10 ) {
 16+ return forms[2];
 17+ }
 18+ return forms[3];
 19+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/gd.js
___________________________________________________________________
Added: svn:mime-type
120 + text/plain
Added: svn:eol-style
221 + native
Index: trunk/phase3/resources/mediawiki.language/languages/ar.js
@@ -0,0 +1,38 @@
 2+/**
 3+ * Arabic (ÿߟÑÿπÿ±ÿ®Ÿäÿ©) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 6 );
 8+ if ( count == 0 ) {
 9+ return forms[0];
 10+ }
 11+ if ( count == 1 ) {
 12+ return forms[1];
 13+ }
 14+ if ( count == 2 ) {
 15+ return forms[2];
 16+ }
 17+ if ( count % 100 >= 3 && count % 100 <= 10 ) {
 18+ return forms[3];
 19+ }
 20+ if ( count % 100 >= 11 && count % 100 <= 99 ) {
 21+ return forms[4];
 22+ }
 23+ return forms[5];
 24+}
 25+
 26+mediaWiki.language.digitTransformTable = {
 27+ '0': 'Ÿ†', // &#x0660;
 28+ '1': 'Ÿ°', // &#x0661;
 29+ '2': 'Ÿ¢', // &#x0662;
 30+ '3': 'Ÿ£', // &#x0663;
 31+ '4': 'Ÿ§', // &#x0664;
 32+ '5': 'Ÿ•', // &#x0665;
 33+ '6': 'Ÿ¶', // &#x0666;
 34+ '7': 'Ÿß', // &#x0667;
 35+ '8': 'Ÿ®', // &#x0668;
 36+ '9': 'Ÿ©', // &#x0669;
 37+ '.': 'Ÿ´', // &#x066b; wrong table ?
 38+ ',': 'Ÿ¨' // &#x066c;
 39+};
Property changes on: trunk/phase3/resources/mediawiki.language/languages/ar.js
___________________________________________________________________
Added: svn:mime-type
140 + text/plain
Added: svn:eol-style
241 + native
Index: trunk/phase3/resources/mediawiki.language/languages/fr.js
@@ -0,0 +1,8 @@
 2+/**
 3+ * French (Fran√ßais) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 2 );
 8+ return ( count <= 1 ) ? forms[0] : forms[1];
 9+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/fr.js
___________________________________________________________________
Added: svn:mime-type
110 + text/plain
Added: svn:eol-style
211 + native
Index: trunk/phase3/resources/mediawiki.language/languages/hr.js
@@ -0,0 +1,20 @@
 2+/**
 3+ * Croatian (hrvatski) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 8+ if ( count > 10 && Math.floor( ( count % 100 ) / 10 ) == 1 ) {
 9+ return forms[2];
 10+ }
 11+ switch ( count % 10 ) {
 12+ case 1:
 13+ return forms[0];
 14+ case 2:
 15+ case 3:
 16+ case 4:
 17+ return forms[1];
 18+ default:
 19+ return forms[2];
 20+ }
 21+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/hr.js
___________________________________________________________________
Added: svn:mime-type
122 + text/plain
Added: svn:eol-style
223 + native
Index: trunk/phase3/resources/mediawiki.language/languages/ln.js
@@ -0,0 +1,8 @@
 2+/**
 3+ * Lingala (Lingála) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 2 );
 8+ return ( count <= 1 ) ? forms[0] : forms[1];
 9+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/ln.js
___________________________________________________________________
Added: svn:mime-type
110 + text/plain
Added: svn:eol-style
211 + native
Index: trunk/phase3/resources/mediawiki.language/languages/sh.js
@@ -0,0 +1,23 @@
 2+/**
 3+ * Serbo-Croatian (Srpskohrvatski / Српскохрватски) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ if ( forms.length === 2 ) {
 8+ return count == 1 ? forms[0] : forms[1];
 9+ }
 10+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 11+ if ( count > 10 && Math.floor( ( count % 100 ) / 10 ) == 1 ) {
 12+ return forms[2];
 13+ }
 14+ switch ( count % 10 ) {
 15+ case 1:
 16+ return forms[0];
 17+ case 2:
 18+ case 3:
 19+ case 4:
 20+ return forms[1];
 21+ default:
 22+ return forms[2];
 23+ }
 24+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/sh.js
___________________________________________________________________
Added: svn:mime-type
125 + text/plain
Added: svn:eol-style
226 + native
Index: trunk/phase3/resources/mediawiki.language/languages/pl.js
@@ -0,0 +1,21 @@
 2+/**
 3+ * Polish (polski) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 8+ count = Math.abs( count );
 9+ if ( count == 1 ) {
 10+ return forms[0];
 11+ }
 12+ switch ( count % 10 ) {
 13+ case 2:
 14+ case 3:
 15+ case 4:
 16+ if ( count / 10 % 10 != 1 ) {
 17+ return forms[1];
 18+ }
 19+ default:
 20+ return forms[2];
 21+ }
 22+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/pl.js
___________________________________________________________________
Added: svn:mime-type
123 + text/plain
Added: svn:eol-style
224 + native
Index: trunk/phase3/resources/mediawiki.language/languages/gv.js
@@ -0,0 +1,18 @@
 2+/**
 3+ * Manx (Gaelg) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 4 );
 8+ if ( count > 0 && ( count % 20 ) === 0 ) {
 9+ return forms[0];
 10+ }
 11+ switch ( count % 10 ) {
 12+ case 1:
 13+ return forms[1];
 14+ case 2:
 15+ return forms[2];
 16+ default:
 17+ return forms[3];
 18+ }
 19+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/gv.js
___________________________________________________________________
Added: svn:mime-type
120 + text/plain
Added: svn:eol-style
221 + native
Index: trunk/phase3/resources/mediawiki.language/languages/sl.js
@@ -0,0 +1,20 @@
 2+/**
 3+ * Slovenian (Sloven≈°ƒçina) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 5 );
 8+ if ( count % 100 == 1 ) {
 9+ return forms[0];
 10+ }
 11+ if ( count % 100 == 2 ) {
 12+ return forms[1];
 13+ }
 14+ if ( count % 100 == 3 || count % 100 == 4 ) {
 15+ return forms[2];
 16+ }
 17+ if ( count != 0 ) {
 18+ return forms[3];
 19+ }
 20+ return forms[4];
 21+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/sl.js
___________________________________________________________________
Added: svn:mime-type
122 + text/plain
Added: svn:eol-style
223 + native
Index: trunk/phase3/resources/mediawiki.language/languages/tl.js
@@ -0,0 +1,7 @@
 2+/**
 3+ * Tagalog (Tagalog) language functions
 4+ */
 5+mediaWiki.language.convertPlural = function( count, forms ) {
 6+ forms = mediaWiki.language.preConvertPlural( forms, 2 );
 7+ return ( count <= 1 ) ? forms[0] : forms[1];
 8+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/tl.js
___________________________________________________________________
Added: svn:mime-type
19 + text/plain
Added: svn:eol-style
210 + native
Index: trunk/phase3/resources/mediawiki.language/languages/lt.js
@@ -0,0 +1,17 @@
 2+/**
 3+ * Lithuanian (Lietuvi≈≥) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ if ( forms.length == 2 ) {
 8+ return count == 1 ? forms[0] : forms[1];
 9+ }
 10+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 11+ if ( count % 10 == 1 && count % 100 != 11 ) {
 12+ return forms[0];
 13+ }
 14+ if ( count % 10 >= 2 && ( count % 100 < 10 || count % 100 >= 20 ) ) {
 15+ return forms[1];
 16+ }
 17+ return forms[2];
 18+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/lt.js
___________________________________________________________________
Added: svn:mime-type
119 + text/plain
Added: svn:eol-style
220 + native
Index: trunk/phase3/resources/mediawiki.language/languages/mt.js
@@ -0,0 +1,17 @@
 2+/**
 3+ * Maltese (Malti) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 4 );
 8+ if ( count == 1 ) {
 9+ return forms[0];
 10+ }
 11+ if ( count == 0 || ( count % 100 > 1 && count % 100 < 11 ) ) {
 12+ return forms[1];
 13+ }
 14+ if ( count % 100 > 10 && count % 100 < 20 ) {
 15+ return forms[2];
 16+ }
 17+ return forms[3];
 18+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/mt.js
___________________________________________________________________
Added: svn:mime-type
119 + text/plain
Added: svn:eol-style
220 + native
Index: trunk/phase3/resources/mediawiki.language/languages/lv.js
@@ -0,0 +1,8 @@
 2+/**
 3+ * Latvian (Latvie≈°u) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 2 );
 8+ return ( ( count % 10 == 1 ) && ( count % 100 != 11 ) ) ? forms[0] : forms[1];
 9+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/lv.js
___________________________________________________________________
Added: svn:mime-type
110 + text/plain
Added: svn:eol-style
211 + native
Index: trunk/phase3/resources/mediawiki.language/languages/sr-el.js
@@ -0,0 +1,20 @@
 2+/**
 3+ * Serbian (latin script) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 8+ if ( count > 10 && Math.floor( ( count % 100 ) / 10 ) == 1 ) {
 9+ return forms[2];
 10+ }
 11+ switch ( count % 10 ) {
 12+ case 1:
 13+ return forms[0];
 14+ case 2:
 15+ case 3:
 16+ case 4:
 17+ return forms[1];
 18+ default:
 19+ return forms[2];
 20+ }
 21+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/sr-el.js
___________________________________________________________________
Added: svn:mime-type
122 + text/plain
Added: svn:eol-style
223 + native
Index: trunk/phase3/resources/mediawiki.language/languages/sr.js
@@ -0,0 +1,23 @@
 2+/**
 3+ * Serbian (Српски / Srpski) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ if ( forms.length === 2 ) {
 8+ return ( count == 1 ) ? forms[0] : forms[1];
 9+ }
 10+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 11+ if ( count > 10 && Math.floor( ( count % 100 ) / 10 ) == 1 ) {
 12+ return forms[2];
 13+ }
 14+ switch ( count % 10 ) {
 15+ case 1:
 16+ return forms[0];
 17+ case 2:
 18+ case 3:
 19+ case 4:
 20+ return forms[1];
 21+ default:
 22+ return forms[2];
 23+ }
 24+};
Property changes on: trunk/phase3/resources/mediawiki.language/languages/sr.js
___________________________________________________________________
Added: svn:mime-type
125 + text/plain
Added: svn:eol-style
226 + native
Index: trunk/phase3/resources/mediawiki.language/languages/ksh.js
@@ -0,0 +1,14 @@
 2+/**
 3+ * Ripuarian (Ripoarƒósh) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 8+ if ( count == 1 ) {
 9+ return forms[0];
 10+ }
 11+ if ( count == 0 ) {
 12+ return forms[2];
 13+ }
 14+ return forms[1];
 15+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/ksh.js
___________________________________________________________________
Added: svn:mime-type
116 + text/plain
Added: svn:eol-style
217 + native
Index: trunk/phase3/resources/mediawiki.language/languages/be.js
@@ -0,0 +1,20 @@
 2+/**
 3+ * Belarusian normative (–ë–µ–ª–∞—Ä—É—Å–∫–∞—è –º–æ–≤–∞) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function convertPlural( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 8+ if ( count > 10 && Math.floor( ( count % 100 ) / 10 ) == 1 ) {
 9+ return forms[2];
 10+ }
 11+ switch ( count % 10 ) {
 12+ case 1:
 13+ return forms[0];
 14+ case 2:
 15+ case 3:
 16+ case 4:
 17+ return forms[1];
 18+ default:
 19+ return forms[2];
 20+ }
 21+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/be.js
___________________________________________________________________
Added: svn:mime-type
122 + text/plain
Added: svn:eol-style
223 + native
Index: trunk/phase3/resources/mediawiki.language/languages/ga.js
@@ -0,0 +1,14 @@
 2+/**
 3+ * Irish (Gaeilge) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 8+ if ( count == 1 ) {
 9+ return forms[0];
 10+ }
 11+ if ( count == 2 ) {
 12+ return forms[1];
 13+ }
 14+ return forms[2];
 15+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/ga.js
___________________________________________________________________
Added: svn:mime-type
116 + text/plain
Added: svn:eol-style
217 + native
Index: trunk/phase3/resources/mediawiki.language/languages/bat-smg.js
@@ -0,0 +1,18 @@
 2+/**
 3+ * Samogitian (≈Ωemaitƒó≈°ka) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 4 );
 8+ count = Math.abs( count );
 9+ if ( count === 0 || ( count % 100 === 0 || ( count % 100 >= 10 && count % 100 < 20 ) ) ) {
 10+ return forms[2];
 11+ }
 12+ if ( count % 10 === 1 ) {
 13+ return forms[0];
 14+ }
 15+ if ( count % 10 === 2 ) {
 16+ return forms[1];
 17+ }
 18+ return forms[3];
 19+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/bat-smg.js
___________________________________________________________________
Added: svn:mime-type
120 + text/plain
Added: svn:eol-style
221 + native
Index: trunk/phase3/resources/mediawiki.language/languages/he.js
@@ -0,0 +1,14 @@
 2+/**
 3+ * Hebrew (◊¢◊ë◊®◊ô◊™) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 3 );
 8+ if ( count == 1 ) {
 9+ return forms[0];
 10+ }
 11+ if ( count == 2 && forms[2] ) {
 12+ return forms[2];
 13+ }
 14+ return forms[1];
 15+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/he.js
___________________________________________________________________
Added: svn:mime-type
116 + text/plain
Added: svn:eol-style
217 + native
Index: trunk/phase3/resources/mediawiki.language/languages/am.js
@@ -0,0 +1,8 @@
 2+/**
 3+ * Amharic (አማርኛ) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 2 );
 8+ return ( count <= 1 ) ? forms[0] : forms[1];
 9+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/am.js
___________________________________________________________________
Added: svn:mime-type
110 + text/plain
Added: svn:eol-style
211 + native
Index: trunk/phase3/resources/mediawiki.language/languages/nso.js
@@ -0,0 +1,8 @@
 2+/**
 3+ * Northern Sotho (Sesotho sa Leboa) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 2 );
 8+ return ( count <= 1 ) ? forms[0] : forms[1];
 9+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/nso.js
___________________________________________________________________
Added: svn:mime-type
110 + text/plain
Added: svn:eol-style
211 + native
Index: trunk/phase3/resources/mediawiki.language/languages/hi.js
@@ -0,0 +1,8 @@
 2+/**
 3+ * Hindi (हिन्दी) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 2 );
 8+ return ( count <= 1 ) ? forms[0] : forms[1];
 9+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/hi.js
___________________________________________________________________
Added: svn:mime-type
110 + text/plain
Added: svn:eol-style
211 + native
Index: trunk/phase3/resources/mediawiki.language/languages/mg.js
@@ -0,0 +1,8 @@
 2+/**
 3+ * Malagasy (Malagasy) language functions
 4+ */
 5+
 6+mediaWiki.language.convertPlural = function( count, forms ) {
 7+ forms = mediaWiki.language.preConvertPlural( forms, 2 );
 8+ return ( count <= 1 ) ? forms[0] : forms[1];
 9+}
Property changes on: trunk/phase3/resources/mediawiki.language/languages/mg.js
___________________________________________________________________
Added: svn:mime-type
110 + text/plain
Added: svn:eol-style
211 + native
Index: trunk/phase3/resources/mediawiki.specials/mediawiki.specials.preferences.js
@@ -0,0 +1,40 @@
 2+/*
 3+ * JavaScript for Special:Preferences
 4+ */
 5+
 6+$( '#prefsubmit' ).attr( 'id', 'prefcontrol' );
 7+$( '#preferences' )
 8+ .addClass( 'jsprefs' )
 9+ .before( $( '<ul id="preftoc"></ul>' ) )
 10+ .children( 'fieldset' )
 11+ .hide()
 12+ .addClass( 'prefsection' )
 13+ .children( 'legend' )
 14+ .addClass( 'mainLegend' )
 15+ .each( function( i ) {
 16+ $(this).parent().attr( 'id', 'prefsection-' + i );
 17+ if ( i === 0 ) {
 18+ $(this).parent().show();
 19+ }
 20+ $( '#preftoc' ).append(
 21+ $( '<li></li>' )
 22+ .addClass( i === 0 ? 'selected' : null )
 23+ .append(
 24+ $( '<a></a>')
 25+ .text( $(this).text() )
 26+ .attr( 'href', '#prefsection-' + i )
 27+ .mousedown( function( e ) {
 28+ $(this).parent().parent().find( 'li' ).removeClass( 'selected' );
 29+ $(this).parent().addClass( 'selected' );
 30+ e.preventDefault();
 31+ return false;
 32+ } )
 33+ .click( function( e ) {
 34+ $( '#preferences > fieldset' ).hide();
 35+ $( '#prefsection-' + i ).show();
 36+ e.preventDefault();
 37+ return false;
 38+ } )
 39+ )
 40+ );
 41+ } );
Property changes on: trunk/phase3/resources/mediawiki.specials/mediawiki.specials.preferences.js
___________________________________________________________________
Added: svn:eol-style
142 + native
Index: trunk/phase3/resources/mediawiki.specials/mediawiki.specials.search.js
@@ -0,0 +1,8 @@
 2+/*
 3+ * JavaScript for Specical:Search
 4+ */
 5+
 6+// Emulate HTML5 autofocus behavior in non HTML5 compliant browsers
 7+if ( !( 'autofocus' in document.createElement( 'input' ) ) ) {
 8+ $( 'input[autofocus]' ).focus();
 9+}
Property changes on: trunk/phase3/resources/mediawiki.specials/mediawiki.specials.search.js
___________________________________________________________________
Added: svn:eol-style
110 + native

Follow-up revisions

RevisionCommit summaryAuthorDate
r75555Whitespace fixes for r75486catrope15:51, 27 October 2010
r76072Fixed Macintosh mojibake from r75486tstarling04:34, 5 November 2010
r76320As per r 75486 CR comments, no prototyping in mw core....krinkle18:13, 8 November 2010

Comments

#Comment by Trevor Parscal (WMF) (talk | contribs)   23:41, 26 October 2010

This commit also reorganizes some scripts in the resources folder.

#Comment by Nikerabbit (talk | contribs)   11:04, 27 October 2010

Where did you get these language files from? They seem to have an character encoding problems. Do we have an automated way to update them if the PHP counterparts change?

#Comment by Trevor Parscal (WMF) (talk | contribs)   17:04, 27 October 2010

Michael Dale wrote them, I just cleaned them up. No we have no automated way of keeping them in sync - how often are the plural rules really changed? I'm not sure what encoding issues you are seeing, anything specific?

#Comment by Catrope (talk | contribs)   17:17, 27 October 2010
 * French (Français) language functions
#Comment by Hashar (talk | contribs)   07:02, 28 October 2010

Same for russian:

  • Russian (—Ä—É—Å—Å–∫–∏–π —è–∑—ã–∫) language functions

It looks like a double encoding issue but I have not been able to guess them :/

#Comment by He7d3r (talk | contribs)   14:52, 7 June 2011

how often are the plural rules really changed?

Not very often, I think, but take a look at bug 29299.

#Comment by Siebrand (talk | contribs)   11:10, 27 October 2010

Haven't checked the JS plural code, but is fallback in place? Does for example language code 'szl' inherit the plurals from 'pl'? If not, this should be fixed somehow.

Marking FIXME because of the encoding issue Nikerabbit addressed in #c10487.

#Comment by Mdale (talk | contribs)   21:15, 27 October 2010

the commit is missing some stuff ... So I assume the rest if forthcoming? Trevor? Also I committed the working version of the test cases, which we should keep around and integrate with selenium.

#Comment by Catrope (talk | contribs)   13:38, 27 October 2010

The architecture used here (one JS file per language, each setting the same function to something different) is not nice and does not allow for doing PLURAL in forcontent messages correctly.

What the heck does procPLURAL() do? It's barely documented and the documentation that is there is confusing. Generally, the documentation of the language class is lacking and cryptic.

			var tmp = [];
			for ( var i in transformTable ) {
				tmp[ transformTable[ i ] ] = i;
			}
			transformTable = tmp;

I'm guessing this inverts transformTable? Does it? Why? Not documented or commented at all.

The language class is missing functionality akin to that of Language::commafy() (code that turns (int)1234567 into '1,234,567' that convertNumber can then turn into '1.234.567' for certain languages) and a formatNum-like function that integrates these two. Without that, it's close to useless.

#Comment by Trevor Parscal (WMF) (talk | contribs)   17:06, 27 October 2010

This commit only cleans up the code that Michael sent me in a patch and brings it into core. It of course needs more documentation and cleaning. It also is not meant to be a 100% matching of Language.php functions, just a subset.

#Comment by Mdale (talk | contribs)   22:08, 27 October 2010

How does forcontent messages work? Would we package in the transform for every language on the request? The idea is you have a single language packaged in with your resource loader request. Perhaps we don't support forcontent messages in javascript for now?

Another advantage of using the same name function is that we can manage the fallback mappings without having to tell the client what that fallback mapping key is. It seems like it would be non trivial to extend the resource loader api to package in multiple language transforms while keeping a single language message values.

I support adding in something like commafy, since we already have/had the number formatter.

#Comment by Catrope (talk | contribs)   22:10, 27 October 2010

Currently we don't support forcontent in JS, no, but we do want to. And yes, implementing that isn't gonna be trivial, neither client-side nor server-side.

#Comment by Krinkle (talk | contribs)   15:24, 27 October 2010

@Trevor: Why remove [].indexOf() ? Most modern browsers have it but older browser (IE6, perhaps IE7) don't. And lots of script authors use it (either they dont know IE7 doesn't have it, or they putted it in Common.js)

#Comment by Trevor Parscal (WMF) (talk | contribs)   16:48, 27 October 2010

Extending the array prototype was causing people to freak out because they can't seem to get the for ( var key in object ) and for ( var i = 0; i < array.length; i++ ) looping techniques straight, using for in with arrays, which, when extended with array prototype tricks results in iteration over the extended methods. I originally wanted to take a "fix your scripts then!" approach, but given we are hoping to support remote embedding in the future, this purist approach simply can't hold up.

#Comment by Krinkle (talk | contribs)   19:46, 27 October 2010

Hm... So you would be against any sort of prototype extending Objects and Array's in core javascript ?

#Comment by Trevor Parscal (WMF) (talk | contribs)   19:53, 27 October 2010

As long as we are not extending the prototype of Object or Array we should be safe. I'm interested in revisiting this, but at this time it seems like we don't get much benefit (syntax is nice?) for the cost (might break if remotely embedded).

#Comment by Dantman (talk | contribs)   19:53, 27 October 2010

Anyone using bad for..in looping over arrays is going to run into more issues than just us adding standard methods to older browsers. IMHO anyone incorrectly using the language like that deserves whatever bugs they get when we add compat code to allow ES5 methods to be used in ES3.

#Comment by Trevor Parscal (WMF) (talk | contribs)   19:55, 27 October 2010

This was my argument exactly. Michael Dale is who you should be stating your points with.

#Comment by Mdale (talk | contribs)   21:12, 27 October 2010

When running jQuery getJSON calls I was running into an issue with array prototyping. ie in buildParams, line 5435 hits the array prototype function and was erroring out because the add function was calling value() without required parameters.

I think extending base prototypes should exclusively target functionality introduced in later version of the native javascript language rather than convenience functions. There are already lots of convenience functions in jQuery and standardizing around jQuery convenience functions will be more manageable then a hybrid of base object prototype extending and jQuery helpers. For example, the jQuery helpers are known to call their native counterparts as browsers are updated. If we 'roll our own' we will recreate that work of keeping in sync with browser implementations of these prototypes.

And finally, Yes if people use our javascript on pages outside of wikipedia projects in a mashup, its a reality that people write crappy code that uses the for( var i in [] ) call. i.e you don't see google maps, adds or youtube api extending any base prototypes.

Its also sucks in respect to "globals", in that other libraries (prototype, moo-tools etc ) have their own global array object prototype extending ( targeting the same convenience function names) that may have a different conflicting implementation with what we do.

#Comment by Dantman (talk | contribs)   00:11, 28 October 2010

Right now I believe we "are" talking about functionality that is part of later versions of the native language into non Object.prototype prototypes. indexOf, forEach, some, etc... are part of ES5. Well, at least I'm talking about that since that's what in this case was removed.

#Comment by Mdale (talk | contribs)   23:40, 29 October 2010

is Array.prototype.compare added in ES5? If the functionality is added natively later in shipping browsers, I don't see a problem with that eventually being included. Since it will have a consistent interface with any other implementation.

I would promote doing this at some later date once the next version of jQuery does not have that issue, and the functionality is more commonly expected to be present. Since in the meantime a jQuery wrapper for the same functionally accomplishes pretty much the same thing.

#Comment by Dantman (talk | contribs)   00:14, 30 October 2010

Array.isArray, Array.prototype.indexOf, Array.prototype.lastIndexOf, Array.prototype.every, Array.prototype.some, Array.prototype.forEach, Array.prototype.map, Array.prototype.filter, Array.prototype.reduce, Array.prototype.reduceRight, String.prototype.trim, JSON.parse, JSON.stringify are ES5 methods (MDC has ES3 compat code for most of these to prototype them onto browsers that haven't implemented them natively yet). I've never heard of Array.prototype.compare before.

#Comment by Krinkle (talk | contribs)   00:23, 30 October 2010

Though I agree adding self-invented prototypes to jQuery is better (like jQuery has $.inArray). I think if we're gonna do that, we shouldn't add any prototypes at all (not even those later natively implemented). Atleast not for the reasons addressed above ("unwanted prototypes in loops and empty objects appearing non-empty"). Since those apply wether the prototype was later implemented natively or not.

If for whatever reason we do build in support for later natively implemented prototypes, I still agree with Mdale that self-invented ones should all be added to jQuery then (if not in jQuery by core already).

The difference in number of characters is limited: "lorem".trim() vs. $.trim("lorem")

#Comment by Trevor Parscal (WMF) (talk | contribs)   18:16, 1 November 2010

Which is the stance I ended up taking. It balances things reasonably.

#Comment by Tim Starling (talk | contribs)   04:38, 5 November 2010

Fix your editor, MediaWiki files should be in UTF-8, not UTF-8 converted to Macintosh converted to UTF-8 mojibake. Fixed this instance in r76072.

Status & tagging log