{
"preset": "wikimedia",
- "disallowKeywordsOnNewLine": null,
"disallowQuotedKeysInObjects": null,
- "disallowImplicitTypeConversion": null,
- "requireLineBreakAfterVariableAssignment": null,
- "requireSpaceAfterLineComment": null,
"requireSpacesInsideParentheses": null,
- "requireSpacesInsideArrayBrackets": null,
- "validateIndentation": null
+ "requireSpacesInsideArrayBrackets": null
}
$.fn.badge = function ( text, inline, displayZero ) {
var $badge = this.find( '.mw-badge' ),
badgeStyleClass = 'mw-badge-' + ( inline ? 'inline' : 'overlay' ),
- isImportant = true, displayBadge = true;
+ isImportant = true,
+ displayBadge = true;
// If we're displaying zero, ensure style to be non-important
if ( mw.language.convertNumber( text, true ) === 0 ) {
}
}
// compare will be -1, 0 or 1, depending on comparison result
- if ( !( eval( '' + compare + op + '0' ) ) ) {
+ if ( !( eval( String( compare + op + '0' ) ) ) ) {
return false;
}
} else if ( typeof val === 'number' ) {
*/
function serializeControls( controls ) {
- var i, data = {}, len = controls.length;
+ var i,
+ data = {},
+ len = controls.length;
for ( i = 0; i < len; i++ ) {
data[ controls[i].name ] = controls[i].value;
return '99999999';
}
} else if ( ( match = s.match( ts.dateRegex[1] ) ) !== null ) {
- s = [ match[3], '' + ts.monthNames[match[2]], match[1] ];
+ s = [ match[3], String( ts.monthNames[match[2]] ), match[1] ];
} else if ( ( match = s.match( ts.dateRegex[2] ) ) !== null ) {
- s = [ match[3], '' + ts.monthNames[match[1]], match[2] ];
+ s = [ match[3], String( ts.monthNames[match[1]] ), match[2] ];
} else {
// Should never get here
return '99999999';
// Apply defaults
switch ( command ) {
- //case 'getContents': // no params
- //case 'setContents': // no params with defaults
- //case 'getSelection': // no params
+ // case 'getContents': // no params
+ // case 'setContents': // no params with defaults
+ // case 'getSelection': // no params
case 'encapsulateSelection':
options = $.extend( {
pre: '', // Text to insert before the cursor/selection
if ( word.match( /wiki$/i ) ) {
aou = false;
}
- //append i after final consonant
+ // append i after final consonant
if ( word.match( /[bcdfghjklmnpqrstvwxz]$/i ) ) {
word += 'i';
}
case 'lokatiw': // lokatiw
word = 'wo ' + word;
break;
- }
+ }
return word;
};
word = word + 'ի';
}
break;
- }
+ }
return word;
};
if ( word.match( /тæ$/i ) ) {
word = word.slice( 0, -1 );
endAllative = 'æм';
- }
- // Works if word is in singular form.
- // Checking if word ends on one of the vowels: е, ё, и, о, ы, э, ю, я.
- else if ( word.match( /[аæеёиоыэюя]$/i ) ) {
+ } else if ( word.match( /[аæеёиоыэюя]$/i ) ) {
+ // Works if word is in singular form.
+ // Checking if word ends on one of the vowels: е, ё, и, о, ы, э, ю, я.
jot = 'й';
- }
- // Checking if word ends on 'у'. 'У' can be either consonant 'W' or vowel 'U' in cyrillic Ossetic.
- // Examples: {{grammar:genitive|аунеу}} = аунеуы, {{grammar:genitive|лæппу}} = лæппуйы.
- else if ( word.match( /у$/i ) ) {
+ } else if ( word.match( /у$/i ) ) {
+ // Checking if word ends on 'у'. 'У' can be either consonant 'W' or vowel 'U' in cyrillic Ossetic.
+ // Examples: {{grammar:genitive|аунеу}} = аунеуы, {{grammar:genitive|лæппу}} = лæппуйы.
+
if ( !word.slice( -2, -1 ).match( /[аæеёиоыэюя]$/i ) ) {
jot = 'й';
}
case 'ablative':
if ( jot === 'й' ) {
ending = hyphen + jot + 'æ';
- }
- else {
+ } else {
ending = hyphen + jot + 'æй';
}
break;
* @return {string}
*/
listToText: function ( list ) {
- var text = '', i = 0;
+ var text = '',
+ i = 0;
+
for ( ; i < list.length; i++ ) {
text += list[i];
if ( list.length - 2 === i ) {
tmp[ transformTable[ i ] ] = i;
}
transformTable = tmp;
- numberString = num + '';
+ numberString = String( num );
} else {
numberString = mw.language.commafy( num, pattern );
}
/*global alert */
( function ( mw ) {
-/**
- * if sajax_debug_mode is true, this function outputs given the message into
- * the element with id = sajax_debug; if no such element exists in the document,
- * it is injected.
- */
-function debug( text ) {
- if ( !window.sajax_debug_mode ) {
- return false;
- }
+ /**
+ * if sajax_debug_mode is true, this function outputs given the message into
+ * the element with id = sajax_debug; if no such element exists in the document,
+ * it is injected.
+ */
+ function debug( text ) {
+ if ( !window.sajax_debug_mode ) {
+ return false;
+ }
- var b, m,
- e = document.getElementById( 'sajax_debug' );
+ var b, m,
+ e = document.getElementById( 'sajax_debug' );
- if ( !e ) {
- e = document.createElement( 'p' );
- e.className = 'sajax_debug';
- e.id = 'sajax_debug';
+ if ( !e ) {
+ e = document.createElement( 'p' );
+ e.className = 'sajax_debug';
+ e.id = 'sajax_debug';
- b = document.getElementsByTagName( 'body' )[0];
+ b = document.getElementsByTagName( 'body' )[0];
- if ( b.firstChild ) {
- b.insertBefore( e, b.firstChild );
- } else {
- b.appendChild( e );
+ if ( b.firstChild ) {
+ b.insertBefore( e, b.firstChild );
+ } else {
+ b.appendChild( e );
+ }
}
- }
- m = document.createElement( 'div' );
- m.appendChild( document.createTextNode( text ) );
+ m = document.createElement( 'div' );
+ m.appendChild( document.createTextNode( text ) );
- e.appendChild( m );
+ e.appendChild( m );
- return true;
-}
+ return true;
+ }
-/**
- * Compatibility wrapper for creating a new XMLHttpRequest object.
- */
-function createXhr() {
- debug( 'sajax_init_object() called..' );
- var a;
- try {
- // Try the new style before ActiveX so we don't
- // unnecessarily trigger warnings in IE 7 when
- // set to prompt about ActiveX usage
- a = new XMLHttpRequest();
- } catch ( xhrE ) {
+ /**
+ * Compatibility wrapper for creating a new XMLHttpRequest object.
+ */
+ function createXhr() {
+ debug( 'sajax_init_object() called..' );
+ var a;
try {
- a = new window.ActiveXObject( 'Msxml2.XMLHTTP' );
- } catch ( msXmlE ) {
+ // Try the new style before ActiveX so we don't
+ // unnecessarily trigger warnings in IE 7 when
+ // set to prompt about ActiveX usage
+ a = new XMLHttpRequest();
+ } catch ( xhrE ) {
try {
- a = new window.ActiveXObject( 'Microsoft.XMLHTTP' );
- } catch ( msXhrE ) {
- a = null;
+ a = new window.ActiveXObject( 'Msxml2.XMLHTTP' );
+ } catch ( msXmlE ) {
+ try {
+ a = new window.ActiveXObject( 'Microsoft.XMLHTTP' );
+ } catch ( msXhrE ) {
+ a = null;
+ }
}
}
- }
- if ( !a ) {
- debug( 'Could not create connection object.' );
- }
+ if ( !a ) {
+ debug( 'Could not create connection object.' );
+ }
- return a;
-}
+ return a;
+ }
-/**
- * Perform an AJAX call to MediaWiki. Calls are handled by AjaxDispatcher.php
- * func_name - the name of the function to call. Must be registered in $wgAjaxExportList
- * args - an array of arguments to that function
- * target - the target that will handle the result of the call. If this is a function,
- * if will be called with the XMLHttpRequest as a parameter; if it's an input
- * element, its value will be set to the resultText; if it's another type of
- * element, its innerHTML will be set to the resultText.
- *
- * Example:
- * sajax_do_call( 'doFoo', [1, 2, 3], document.getElementById( 'showFoo' ) );
- *
- * This will call the doFoo function via MediaWiki's AjaxDispatcher, with
- * (1, 2, 3) as the parameter list, and will show the result in the element
- * with id = showFoo
- */
-function doAjaxRequest( func_name, args, target ) {
- var i, x, uri, post_data;
- uri = mw.util.wikiScript() + '?action=ajax';
- if ( window.sajax_request_type === 'GET' ) {
- if ( uri.indexOf( '?' ) === -1 ) {
- uri = uri + '?rs=' + encodeURIComponent( func_name );
+ /**
+ * Perform an AJAX call to MediaWiki. Calls are handled by AjaxDispatcher.php
+ * func_name - the name of the function to call. Must be registered in $wgAjaxExportList
+ * args - an array of arguments to that function
+ * target - the target that will handle the result of the call. If this is a function,
+ * if will be called with the XMLHttpRequest as a parameter; if it's an input
+ * element, its value will be set to the resultText; if it's another type of
+ * element, its innerHTML will be set to the resultText.
+ *
+ * Example:
+ * sajax_do_call( 'doFoo', [1, 2, 3], document.getElementById( 'showFoo' ) );
+ *
+ * This will call the doFoo function via MediaWiki's AjaxDispatcher, with
+ * (1, 2, 3) as the parameter list, and will show the result in the element
+ * with id = showFoo
+ */
+ function doAjaxRequest( func_name, args, target ) {
+ var i, x, uri, post_data;
+ uri = mw.util.wikiScript() + '?action=ajax';
+ if ( window.sajax_request_type === 'GET' ) {
+ if ( uri.indexOf( '?' ) === -1 ) {
+ uri = uri + '?rs=' + encodeURIComponent( func_name );
+ } else {
+ uri = uri + '&rs=' + encodeURIComponent( func_name );
+ }
+ for ( i = 0; i < args.length; i++ ) {
+ uri = uri + '&rsargs[]=' + encodeURIComponent( args[i] );
+ }
+ // uri = uri + '&rsrnd=' + new Date().getTime();
+ post_data = null;
} else {
- uri = uri + '&rs=' + encodeURIComponent( func_name );
- }
- for ( i = 0; i < args.length; i++ ) {
- uri = uri + '&rsargs[]=' + encodeURIComponent( args[i] );
+ post_data = 'rs=' + encodeURIComponent( func_name );
+ for ( i = 0; i < args.length; i++ ) {
+ post_data = post_data + '&rsargs[]=' + encodeURIComponent( args[i] );
+ }
}
- //uri = uri + '&rsrnd=' + new Date().getTime();
- post_data = null;
- } else {
- post_data = 'rs=' + encodeURIComponent( func_name );
- for ( i = 0; i < args.length; i++ ) {
- post_data = post_data + '&rsargs[]=' + encodeURIComponent( args[i] );
+ x = createXhr();
+ if ( !x ) {
+ alert( 'AJAX not supported' );
+ return false;
}
- }
- x = createXhr();
- if ( !x ) {
- alert( 'AJAX not supported' );
- return false;
- }
- try {
- x.open( window.sajax_request_type, uri, true );
- } catch ( e ) {
- if ( location.hostname === 'localhost' ) {
- alert( 'Your browser blocks XMLHttpRequest to "localhost", try using a real hostname for development/testing.' );
+ try {
+ x.open( window.sajax_request_type, uri, true );
+ } catch ( e ) {
+ if ( location.hostname === 'localhost' ) {
+ alert( 'Your browser blocks XMLHttpRequest to "localhost", try using a real hostname for development/testing.' );
+ }
+ throw e;
}
- throw e;
- }
- if ( window.sajax_request_type === 'POST' ) {
- x.setRequestHeader( 'Method', 'POST ' + uri + ' HTTP/1.1' );
- x.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
- }
- x.setRequestHeader( 'Pragma', 'cache=yes' );
- x.setRequestHeader( 'Cache-Control', 'no-transform' );
- x.onreadystatechange = function () {
- if ( x.readyState !== 4 ) {
- return;
+ if ( window.sajax_request_type === 'POST' ) {
+ x.setRequestHeader( 'Method', 'POST ' + uri + ' HTTP/1.1' );
+ x.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
}
+ x.setRequestHeader( 'Pragma', 'cache=yes' );
+ x.setRequestHeader( 'Cache-Control', 'no-transform' );
+ x.onreadystatechange = function () {
+ if ( x.readyState !== 4 ) {
+ return;
+ }
- debug( 'received (' + x.status + ' ' + x.statusText + ') ' + x.responseText );
+ debug( 'received (' + x.status + ' ' + x.statusText + ') ' + x.responseText );
- //if ( x.status != 200 )
- // alert( 'Error: ' + x.status + ' ' + x.statusText + ': ' + x.responseText );
- //else
+ // if ( x.status != 200 )
+ // alert( 'Error: ' + x.status + ' ' + x.statusText + ': ' + x.responseText );
+ // else
- if ( typeof target === 'function' ) {
- target( x );
- } else if ( typeof target === 'object' ) {
- if ( target.tagName === 'INPUT' ) {
- if ( x.status === 200 ) {
- target.value = x.responseText;
- }
- //else alert( 'Error: ' + x.status + ' ' + x.statusText + ' (' + x.responseText + ')' );
- } else {
- if ( x.status === 200 ) {
- target.innerHTML = x.responseText;
+ if ( typeof target === 'function' ) {
+ target( x );
+ } else if ( typeof target === 'object' ) {
+ if ( target.tagName === 'INPUT' ) {
+ if ( x.status === 200 ) {
+ target.value = x.responseText;
+ }
+ // else alert( 'Error: ' + x.status + ' ' + x.statusText + ' (' + x.responseText + ')' );
} else {
- target.innerHTML = '<div class="error">Error: ' + x.status +
- ' ' + x.statusText + ' (' + x.responseText + ')</div>';
+ if ( x.status === 200 ) {
+ target.innerHTML = x.responseText;
+ } else {
+ target.innerHTML = '<div class="error">Error: ' + x.status +
+ ' ' + x.statusText + ' (' + x.responseText + ')</div>';
+ }
}
+ } else {
+ alert( 'Bad target for sajax_do_call: not a function or object: ' + target );
}
- } else {
- alert( 'Bad target for sajax_do_call: not a function or object: ' + target );
- }
- };
+ };
+
+ debug( func_name + ' uri = ' + uri + ' / post = ' + post_data );
+ x.send( post_data );
+ debug( func_name + ' waiting..' );
- debug( func_name + ' uri = ' + uri + ' / post = ' + post_data );
- x.send( post_data );
- debug( func_name + ' waiting..' );
+ return true;
+ }
- return true;
-}
+ /**
+ * @return {boolean} Whether the browser supports AJAX
+ */
+ function wfSupportsAjax() {
+ var request = createXhr(),
+ supportsAjax = request ? true : false;
-/**
- * @return {boolean} Whether the browser supports AJAX
- */
-function wfSupportsAjax() {
- var request = createXhr(),
- supportsAjax = request ? true : false;
-
- request = undefined;
- return supportsAjax;
-}
-
-// Expose + Mark as deprecated
-var deprecationNotice = 'Sajax is deprecated, use jQuery.ajax or mediawiki.api instead.';
-
-// Variables
-mw.log.deprecate( window, 'sajax_debug_mode', false, deprecationNotice );
-mw.log.deprecate( window, 'sajax_request_type', 'GET', deprecationNotice );
-// Methods
-mw.log.deprecate( window, 'sajax_debug', debug, deprecationNotice );
-mw.log.deprecate( window, 'sajax_init_object', createXhr, deprecationNotice );
-mw.log.deprecate( window, 'sajax_do_call', doAjaxRequest, deprecationNotice );
-mw.log.deprecate( window, 'wfSupportsAjax', wfSupportsAjax, deprecationNotice );
+ request = undefined;
+ return supportsAjax;
+ }
+
+ // Expose + Mark as deprecated
+ var deprecationNotice = 'Sajax is deprecated, use jQuery.ajax or mediawiki.api instead.';
+
+ // Variables
+ mw.log.deprecate( window, 'sajax_debug_mode', false, deprecationNotice );
+ mw.log.deprecate( window, 'sajax_request_type', 'GET', deprecationNotice );
+ // Methods
+ mw.log.deprecate( window, 'sajax_debug', debug, deprecationNotice );
+ mw.log.deprecate( window, 'sajax_init_object', createXhr, deprecationNotice );
+ mw.log.deprecate( window, 'sajax_do_call', doAjaxRequest, deprecationNotice );
+ mw.log.deprecate( window, 'wfSupportsAjax', wfSupportsAjax, deprecationNotice );
}( mediaWiki ) );
* on the protection form
*/
init: function () {
- var $cell = $( '<td>' ), $row = $( '<tr>' ).append( $cell );
+ var $cell = $( '<td>' ),
+ $row = $( '<tr>' ).append( $cell );
if ( !$( '#mwProtectSet' ).length ) {
return false;
ua = navigator.userAgent.toLowerCase(),
onloadFuncts = [];
-/**
- * User-agent sniffing.
- *
- * @deprecated since 1.17 Use jquery.client instead
- */
-
-msg = 'Use feature detection or module jquery.client instead.';
-
-mw.log.deprecate( win, 'clientPC', ua, msg );
-
-// Ignored dummy values
-mw.log.deprecate( win, 'is_gecko', false, msg );
-mw.log.deprecate( win, 'is_chrome_mac', false, msg );
-mw.log.deprecate( win, 'is_chrome', false, msg );
-mw.log.deprecate( win, 'webkit_version', false, msg );
-mw.log.deprecate( win, 'is_safari_win', false, msg );
-mw.log.deprecate( win, 'is_safari', false, msg );
-mw.log.deprecate( win, 'webkit_match', false, msg );
-mw.log.deprecate( win, 'is_ff2', false, msg );
-mw.log.deprecate( win, 'ff2_bugs', false, msg );
-mw.log.deprecate( win, 'is_ff2_win', false, msg );
-mw.log.deprecate( win, 'is_ff2_x11', false, msg );
-mw.log.deprecate( win, 'opera95_bugs', false, msg );
-mw.log.deprecate( win, 'opera7_bugs', false, msg );
-mw.log.deprecate( win, 'opera6_bugs', false, msg );
-mw.log.deprecate( win, 'is_opera_95', false, msg );
-mw.log.deprecate( win, 'is_opera_preseven', false, msg );
-mw.log.deprecate( win, 'is_opera', false, msg );
-mw.log.deprecate( win, 'ie6_bugs', false, msg );
-
-/**
- * DOM utilities for handling of events, text nodes and selecting elements
- *
- * @deprecated since 1.17 Use jQuery instead
- */
-msg = 'Use jQuery instead.';
-
-// Ignored dummy values
-mw.log.deprecate( win, 'doneOnloadHook', undefined, msg );
-mw.log.deprecate( win, 'onloadFuncts', [], msg );
-mw.log.deprecate( win, 'runOnloadHook', $.noop, msg );
-mw.log.deprecate( win, 'changeText', $.noop, msg );
-mw.log.deprecate( win, 'killEvt', $.noop, msg );
-mw.log.deprecate( win, 'addHandler', $.noop, msg );
-mw.log.deprecate( win, 'hookEvent', $.noop, msg );
-mw.log.deprecate( win, 'addClickHandler', $.noop, msg );
-mw.log.deprecate( win, 'removeHandler', $.noop, msg );
-mw.log.deprecate( win, 'getElementsByClassName', function () { return []; }, msg );
-mw.log.deprecate( win, 'getInnerText', function () { return ''; }, msg );
-
-// Run a function after the window onload event is fired
-mw.log.deprecate( win, 'addOnloadHook', function ( hookFunct ) {
- if ( onloadFuncts ) {
- onloadFuncts.push( hookFunct );
- } else {
- // If func queue is gone the event has happened already,
- // run immediately instead of queueing.
- hookFunct();
- }
-}, msg );
-
-$( win ).on( 'load', function () {
- var i, functs;
-
- // Don't run twice
- if ( !onloadFuncts ) {
- return;
- }
-
- // Deference and clear onloadFuncts before running any
- // hooks to make sure we don't miss any addOnloadHook
- // calls.
- functs = onloadFuncts.slice();
- onloadFuncts = undefined;
-
- // Execute the queued functions
- for ( i = 0; i < functs.length; i++ ) {
- functs[i]();
- }
-} );
-
-/**
- * Toggle checkboxes with shift selection
- *
- * @deprecated since 1.17 Use jquery.checkboxShiftClick instead
- */
-msg = 'Use jquery.checkboxShiftClick instead.';
-mw.log.deprecate( win, 'checkboxes', [], msg );
-mw.log.deprecate( win, 'lastCheckbox', null, msg );
-mw.log.deprecate( win, 'setupCheckboxShiftClick', $.noop, msg );
-mw.log.deprecate( win, 'addCheckboxClickHandlers', $.noop, msg );
-mw.log.deprecate( win, 'checkboxClickHandler', $.noop, msg );
-
-/**
- * Add a button to the default editor toolbar
- *
- * @deprecated since 1.17 Use mw.toolbar instead
- */
-mw.log.deprecate( win, 'mwEditButtons', [], 'Use mw.toolbar instead.' );
-mw.log.deprecate( win, 'mwCustomEditButtons', [], 'Use mw.toolbar instead.' );
-
-/**
- * Spinner creation, injection and removal
- *
- * @deprecated since 1.18 Use jquery.spinner instead
- */
-mw.log.deprecate( win, 'injectSpinner', $.noop, 'Use jquery.spinner instead.' );
-mw.log.deprecate( win, 'removeSpinner', $.noop, 'Use jquery.spinner instead.' );
-
-/**
- * Escape utilities
- *
- * @deprecated since 1.18 Use mw.html instead
- */
-mw.log.deprecate( win, 'escapeQuotes', $.noop, 'Use mw.html instead.' );
-mw.log.deprecate( win, 'escapeQuotesHTML', $.noop, 'Use mw.html instead.' );
-
-/**
- * Display a message to the user
- *
- * @deprecated since 1.17 Use mediawiki.notify instead
- * @param {string|HTMLElement} message To be put inside the message box
- */
-mw.log.deprecate( win, 'jsMsg', function ( message ) {
- if ( !arguments.length || message === '' || message === null ) {
+ /**
+ * User-agent sniffing.
+ *
+ * @deprecated since 1.17 Use jquery.client instead
+ */
+
+ msg = 'Use feature detection or module jquery.client instead.';
+
+ mw.log.deprecate( win, 'clientPC', ua, msg );
+
+ // Ignored dummy values
+ mw.log.deprecate( win, 'is_gecko', false, msg );
+ mw.log.deprecate( win, 'is_chrome_mac', false, msg );
+ mw.log.deprecate( win, 'is_chrome', false, msg );
+ mw.log.deprecate( win, 'webkit_version', false, msg );
+ mw.log.deprecate( win, 'is_safari_win', false, msg );
+ mw.log.deprecate( win, 'is_safari', false, msg );
+ mw.log.deprecate( win, 'webkit_match', false, msg );
+ mw.log.deprecate( win, 'is_ff2', false, msg );
+ mw.log.deprecate( win, 'ff2_bugs', false, msg );
+ mw.log.deprecate( win, 'is_ff2_win', false, msg );
+ mw.log.deprecate( win, 'is_ff2_x11', false, msg );
+ mw.log.deprecate( win, 'opera95_bugs', false, msg );
+ mw.log.deprecate( win, 'opera7_bugs', false, msg );
+ mw.log.deprecate( win, 'opera6_bugs', false, msg );
+ mw.log.deprecate( win, 'is_opera_95', false, msg );
+ mw.log.deprecate( win, 'is_opera_preseven', false, msg );
+ mw.log.deprecate( win, 'is_opera', false, msg );
+ mw.log.deprecate( win, 'ie6_bugs', false, msg );
+
+ /**
+ * DOM utilities for handling of events, text nodes and selecting elements
+ *
+ * @deprecated since 1.17 Use jQuery instead
+ */
+ msg = 'Use jQuery instead.';
+
+ // Ignored dummy values
+ mw.log.deprecate( win, 'doneOnloadHook', undefined, msg );
+ mw.log.deprecate( win, 'onloadFuncts', [], msg );
+ mw.log.deprecate( win, 'runOnloadHook', $.noop, msg );
+ mw.log.deprecate( win, 'changeText', $.noop, msg );
+ mw.log.deprecate( win, 'killEvt', $.noop, msg );
+ mw.log.deprecate( win, 'addHandler', $.noop, msg );
+ mw.log.deprecate( win, 'hookEvent', $.noop, msg );
+ mw.log.deprecate( win, 'addClickHandler', $.noop, msg );
+ mw.log.deprecate( win, 'removeHandler', $.noop, msg );
+ mw.log.deprecate( win, 'getElementsByClassName', function () { return []; }, msg );
+ mw.log.deprecate( win, 'getInnerText', function () { return ''; }, msg );
+
+ // Run a function after the window onload event is fired
+ mw.log.deprecate( win, 'addOnloadHook', function ( hookFunct ) {
+ if ( onloadFuncts ) {
+ onloadFuncts.push( hookFunct );
+ } else {
+ // If func queue is gone the event has happened already,
+ // run immediately instead of queueing.
+ hookFunct();
+ }
+ }, msg );
+
+ $( win ).on( 'load', function () {
+ var i, functs;
+
+ // Don't run twice
+ if ( !onloadFuncts ) {
+ return;
+ }
+
+ // Deference and clear onloadFuncts before running any
+ // hooks to make sure we don't miss any addOnloadHook
+ // calls.
+ functs = onloadFuncts.slice();
+ onloadFuncts = undefined;
+
+ // Execute the queued functions
+ for ( i = 0; i < functs.length; i++ ) {
+ functs[i]();
+ }
+ } );
+
+ /**
+ * Toggle checkboxes with shift selection
+ *
+ * @deprecated since 1.17 Use jquery.checkboxShiftClick instead
+ */
+ msg = 'Use jquery.checkboxShiftClick instead.';
+ mw.log.deprecate( win, 'checkboxes', [], msg );
+ mw.log.deprecate( win, 'lastCheckbox', null, msg );
+ mw.log.deprecate( win, 'setupCheckboxShiftClick', $.noop, msg );
+ mw.log.deprecate( win, 'addCheckboxClickHandlers', $.noop, msg );
+ mw.log.deprecate( win, 'checkboxClickHandler', $.noop, msg );
+
+ /**
+ * Add a button to the default editor toolbar
+ *
+ * @deprecated since 1.17 Use mw.toolbar instead
+ */
+ mw.log.deprecate( win, 'mwEditButtons', [], 'Use mw.toolbar instead.' );
+ mw.log.deprecate( win, 'mwCustomEditButtons', [], 'Use mw.toolbar instead.' );
+
+ /**
+ * Spinner creation, injection and removal
+ *
+ * @deprecated since 1.18 Use jquery.spinner instead
+ */
+ mw.log.deprecate( win, 'injectSpinner', $.noop, 'Use jquery.spinner instead.' );
+ mw.log.deprecate( win, 'removeSpinner', $.noop, 'Use jquery.spinner instead.' );
+
+ /**
+ * Escape utilities
+ *
+ * @deprecated since 1.18 Use mw.html instead
+ */
+ mw.log.deprecate( win, 'escapeQuotes', $.noop, 'Use mw.html instead.' );
+ mw.log.deprecate( win, 'escapeQuotesHTML', $.noop, 'Use mw.html instead.' );
+
+ /**
+ * Display a message to the user
+ *
+ * @deprecated since 1.17 Use mediawiki.notify instead
+ * @param {string|HTMLElement} message To be put inside the message box
+ */
+ mw.log.deprecate( win, 'jsMsg', function ( message ) {
+ if ( !arguments.length || message === '' || message === null ) {
+ return true;
+ }
+ if ( typeof message !== 'object' ) {
+ message = $.parseHTML( message );
+ }
+ mw.notify( message, { autoHide: true, tag: 'legacy' } );
return true;
- }
- if ( typeof message !== 'object' ) {
- message = $.parseHTML( message );
- }
- mw.notify( message, { autoHide: true, tag: 'legacy' } );
- return true;
-}, 'Use mediawiki.notify instead.' );
-
-/**
- * Misc. utilities
- *
- * @deprecated since 1.17 Use mediawiki.util or jquery.accessKeyLabel instead
- */
-msg = 'Use mediawiki.util instead.';
-mw.log.deprecate( win, 'addPortletLink', mw.util.addPortletLink, msg );
-mw.log.deprecate( win, 'appendCSS', mw.util.addCSS, msg );
-msg = 'Use jquery.accessKeyLabel instead.';
-mw.log.deprecate( win, 'tooltipAccessKeyPrefix', 'alt-', msg );
-mw.log.deprecate( win, 'tooltipAccessKeyRegexp', /\[(alt-)?(.)\]$/, msg );
-// mw.util.updateTooltipAccessKeys already generates a deprecation message.
-win.updateTooltipAccessKeys = function () {
- return mw.util.updateTooltipAccessKeys.apply( null, arguments );
-};
-
-/**
- * Wikipage import methods
- */
-
-// included-scripts tracker
-win.loadedScripts = {};
-
-win.importScript = function ( page ) {
- var uri = mw.config.get( 'wgScript' ) + '?title=' +
- mw.util.wikiUrlencode( page ) +
- '&action=raw&ctype=text/javascript';
- return win.importScriptURI( uri );
-};
-
-win.importScriptURI = function ( url ) {
- if ( win.loadedScripts[url] ) {
- return null;
- }
- win.loadedScripts[url] = true;
- var s = document.createElement( 'script' );
- s.setAttribute( 'src', url );
- s.setAttribute( 'type', 'text/javascript' );
- document.getElementsByTagName( 'head' )[0].appendChild( s );
- return s;
-};
-
-win.importStylesheet = function ( page ) {
- var uri = mw.config.get( 'wgScript' ) + '?title=' +
- mw.util.wikiUrlencode( page ) +
- '&action=raw&ctype=text/css';
- return win.importStylesheetURI( uri );
-};
-
-win.importStylesheetURI = function ( url, media ) {
- var l = document.createElement( 'link' );
- l.rel = 'stylesheet';
- l.href = url;
- if ( media ) {
- l.media = media;
- }
- document.getElementsByTagName( 'head' )[0].appendChild( l );
- return l;
-};
+ }, 'Use mediawiki.notify instead.' );
+
+ /**
+ * Misc. utilities
+ *
+ * @deprecated since 1.17 Use mediawiki.util or jquery.accessKeyLabel instead
+ */
+ msg = 'Use mediawiki.util instead.';
+ mw.log.deprecate( win, 'addPortletLink', mw.util.addPortletLink, msg );
+ mw.log.deprecate( win, 'appendCSS', mw.util.addCSS, msg );
+ msg = 'Use jquery.accessKeyLabel instead.';
+ mw.log.deprecate( win, 'tooltipAccessKeyPrefix', 'alt-', msg );
+ mw.log.deprecate( win, 'tooltipAccessKeyRegexp', /\[(alt-)?(.)\]$/, msg );
+ // mw.util.updateTooltipAccessKeys already generates a deprecation message.
+ win.updateTooltipAccessKeys = function () {
+ return mw.util.updateTooltipAccessKeys.apply( null, arguments );
+ };
+
+ /**
+ * Wikipage import methods
+ */
+
+ // included-scripts tracker
+ win.loadedScripts = {};
+
+ win.importScript = function ( page ) {
+ var uri = mw.config.get( 'wgScript' ) + '?title=' +
+ mw.util.wikiUrlencode( page ) +
+ '&action=raw&ctype=text/javascript';
+ return win.importScriptURI( uri );
+ };
+
+ win.importScriptURI = function ( url ) {
+ if ( win.loadedScripts[url] ) {
+ return null;
+ }
+ win.loadedScripts[url] = true;
+ var s = document.createElement( 'script' );
+ s.setAttribute( 'src', url );
+ s.setAttribute( 'type', 'text/javascript' );
+ document.getElementsByTagName( 'head' )[0].appendChild( s );
+ return s;
+ };
+
+ win.importStylesheet = function ( page ) {
+ var uri = mw.config.get( 'wgScript' ) + '?title=' +
+ mw.util.wikiUrlencode( page ) +
+ '&action=raw&ctype=text/css';
+ return win.importStylesheetURI( uri );
+ };
+
+ win.importStylesheetURI = function ( url, media ) {
+ var l = document.createElement( 'link' );
+ l.rel = 'stylesheet';
+ l.href = url;
+ if ( media ) {
+ l.media = media;
+ }
+ document.getElementsByTagName( 'head' )[0].appendChild( l );
+ return l;
+ };
}( mediaWiki, jQuery ) );
*/
( function ( mw, $ ) {
var jqXhr, $multipageimage, $spinner,
- cache = {}, cacheOrder = [];
+ cache = {},
+ cacheOrder = [];
/* Fetch the next page, caching up to 10 last-loaded pages.
* @param {string} url
} else {
$( this ).css( 'height', 'auto' );
}
- } ).insertBefore( $preftoc );
+ } ).insertBefore( $preftoc );
/**
* It uses document.getElementById for security reasons (HTML injections in $()).
* @singleton
*/
( function ( mw, $ ) {
- var ajaxUploadDestCheck = mw.config.get( 'wgAjaxUploadDestCheck' ),
- $license = $( '#wpLicense' ), uploadWarning, uploadLicense;
+ var uploadWarning, uploadLicense,
+ ajaxUploadDestCheck = mw.config.get( 'wgAjaxUploadDestCheck' ),
+ $license = $( '#wpLicense' );
window.wgUploadWarningObj = uploadWarning = {
responseCache: { '': ' ' },
set: function ( titles, state ) {
titles = $.isArray( titles ) ? titles : [titles];
state = state === undefined ? true : !!state;
- var pages = this.pages, i, len = titles.length;
+ var i,
+ pages = this.pages,
+ len = titles.length;
+
for ( i = 0; i < len; i++ ) {
pages[ titles[i] ] = state;
}
function humanSize( bytes ) {
if ( !$.isNumeric( bytes ) || bytes === 0 ) { return bytes; }
- var i = 0, units = [ '', ' kB', ' MB', ' GB', ' TB', ' PB' ];
+ var i = 0,
+ units = [ '', ' kB', ' MB', ' GB', ' TB', ' PB' ];
+
for ( ; bytes >= 1024; bytes /= 1024 ) { i++; }
// Maintain one decimal for kB and above, but don't
// add ".0" for bytes.
* two properties, 'requires' and 'requiredBy'.
*/
getDependencyGraph: function () {
- var modules = inspect.getLoadedModules(), graph = {};
+ var modules = inspect.getLoadedModules(),
+ graph = {};
$.each( modules, function ( moduleIndex, moduleName ) {
var dependencies = mw.loader.moduleRegistry[moduleName].dependencies || [];
* @return {string|Array} string of '[key]' if message missing, simple string if possible, array of arrays if needs parsing
*/
getAst: function ( key ) {
- var cacheKey = [key, this.settings.onlyCurlyBraceTransform].join( ':' ), wikiText;
+ var wikiText,
+ cacheKey = [key, this.settings.onlyCurlyBraceTransform].join( ':' );
if ( this.astCache[ cacheKey ] === undefined ) {
wikiText = this.settings.messages.get( key );
* @return {Mixed} abstract syntax tree
*/
wikiTextToAst: function ( input ) {
- var pos, settings = this.settings, concat = Array.prototype.concat,
+ var pos,
regularLiteral, regularLiteralWithoutBar, regularLiteralWithoutSpace, regularLiteralWithSquareBrackets,
doubleQuote, singleQuote, backslash, anyCharacter, asciiAlphabetLiteral,
escapedOrLiteralWithoutSpace, escapedOrLiteralWithoutBar, escapedOrRegularLiteral,
htmlAttributeEquals, openHtmlStartTag, optionalForwardSlash, openHtmlEndTag, closeHtmlTag,
openExtlink, closeExtlink, wikilinkPage, wikilinkContents, openWikilink, closeWikilink, templateName, pipe, colon,
templateContents, openTemplate, closeTemplate,
- nonWhitespaceExpression, paramExpression, expression, curlyBraceTransformExpression, result;
+ nonWhitespaceExpression, paramExpression, expression, curlyBraceTransformExpression, result,
+ settings = this.settings,
+ concat = Array.prototype.concat;
// Indicates current position in input as we parse through it.
// Shared among all parsing functions below.
// Subset of allowed HTML markup.
// Most elements and many attributes allowed on the server are not supported yet.
function html() {
- var result = null, parsedOpenTagResult, parsedHtmlContents,
- parsedCloseTagResult, wrappedAttributes, attributes,
- startTagName, endTagName, startOpenTagPos, startCloseTagPos,
- endOpenTagPos, endCloseTagPos;
+ var parsedOpenTagResult, parsedHtmlContents, parsedCloseTagResult,
+ wrappedAttributes, attributes, startTagName, endTagName, startOpenTagPos,
+ startCloseTagPos, endOpenTagPos, endCloseTagPos,
+ result = null;
// Break into three sequence calls. That should allow accurate reconstruction of the original HTML, and requiring an exact tag name match.
// 1. open through closeHtmlTag
page = nodes[0];
url = mw.util.getUrl( page );
- // [[Some Page]] or [[Namespace:Some Page]]
if ( nodes.length === 1 ) {
+ // [[Some Page]] or [[Namespace:Some Page]]
anchor = page;
- }
-
- /*
- * [[Some Page|anchor text]] or
- * [[Namespace:Some Page|anchor]
- */
- else {
+ } else {
+ // [[Some Page|anchor text]] or [[Namespace:Some Page|anchor]]
anchor = nodes[1];
}
* @return {string} selected pluralized form according to current language
*/
plural: function ( nodes ) {
- var forms, firstChild, firstChildText,
- explicitPluralForms = {}, explicitPluralFormNumber, formIndex, form, count;
+ var forms, firstChild, firstChildText, explicitPluralFormNumber, formIndex, form, count,
+ explicitPluralForms = {};
count = parseFloat( this.language.convertNumber( nodes[0], true ) );
forms = nodes.slice( 1 );
}
function sortQuery( o ) {
- var sorted = {}, key, a = [];
+ var key,
+ sorted = {},
+ a = [];
+
for ( key in o ) {
if ( hasOwn.call( o, key ) ) {
a.push( key );
* @private
*/
function buildModulesString( moduleMap ) {
- var arr = [], p, prefix;
+ var p, prefix,
+ arr = [];
+
for ( prefix in moduleMap ) {
p = prefix === '' ? '' : prefix + '.';
arr.push( p + moduleMap[prefix].join( ',' ) );
// HTML5 defines a string as valid e-mail address if it matches
// the ABNF:
- // 1 * ( atext / "." ) "@" ldh-str 1*( "." ldh-str )
+ // 1 * ( atext / "." ) "@" ldh-str 1*( "." ldh-str )
// With:
// - atext : defined in RFC 5322 section 3.2.3
// - ldh-str : defined in RFC 1034 section 3.5
rfc5322Atext = 'a-z0-9!#$%&\'*+\\-/=?^_`{|}~';
// Next define the RFC 1034 'ldh-str'
- // <domain> ::= <subdomain> | " "
- // <subdomain> ::= <label> | <subdomain> "." <label>
- // <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
- // <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
- // <let-dig-hyp> ::= <let-dig> | "-"
- // <let-dig> ::= <letter> | <digit>
+ // <domain> ::= <subdomain> | " "
+ // <subdomain> ::= <label> | <subdomain> "." <label>
+ // <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
+ // <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
+ // <let-dig-hyp> ::= <let-dig> | "-"
+ // <let-dig> ::= <letter> | <digit>
rfc1034LdhStr = 'a-z0-9\\-';
html5EmailRegexp = new RegExp(
} ) );
var getAccessKeyPrefixTestData = [
- //ua string, platform string, expected prefix
+ // ua string, platform string, expected prefix
// Internet Explorer
['Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', 'Win32', 'alt-'],
['Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)', 'Win32', 'alt-'],
['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_5_8) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.112 Safari/534.30', 'MacIntel', 'ctrl-option-'],
['Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.68 Safari/534.30', 'Linux i686', 'alt-shift-']
],
- //strings appended to title to make sure updateTooltipAccessKeys handles them correctly
+ // strings appended to title to make sure updateTooltipAccessKeys handles them correctly
updateTooltipAccessKeysTestData = [ '', ' [a]', ' [test-a]', ' [alt-b]' ];
function makeInput( title, accessKey ) {
- //The properties aren't escaped, so make sure you don't call this function with values that need to be escaped!
+ // The properties aren't escaped, so make sure you don't call this function with values that need to be escaped!
return '<input title="' + title + '" ' + ( accessKey ? 'accessKey="' + accessKey + '" ' : '' ) + ' />';
}
QUnit.test( 'updateTooltipAccessKeys - current browser', 2, function ( assert ) {
var title = $( makeInput( 'Title', 'a' ) ).updateTooltipAccessKeys().prop( 'title' ),
- //The new title should be something like "Title [alt-a]", but the exact label will depend on the browser.
- //The "a" could be capitalized, and the prefix could be anything, e.g. a simple "^" for ctrl-
- //(no browser is known using such a short prefix, though) or "Alt+Umschalt+" in German Firefox.
+ // The new title should be something like "Title [alt-a]", but the exact label will depend on the browser.
+ // The "a" could be capitalized, and the prefix could be anything, e.g. a simple "^" for ctrl-
+ // (no browser is known using such a short prefix, though) or "Alt+Umschalt+" in German Firefox.
result = /^Title \[(.+)[aA]\]$/.exec( title );
assert.ok( result, 'title should match expected structure.' );
assert.notEqual( result[1], 'test-', 'Prefix used for testing shouldn\'t be used in production.' );
// bug 53211 - exploding rowspans in more complex cases
QUnit.test(
'Rowspan exploding with row headers and colspans', 1, function ( assert ) {
- var $table = $( '<table class="sortable">' +
- '<thead><tr><th rowspan="2">n</th><th colspan="2">foo</th><th rowspan="2">baz</th></tr>' +
- '<tr><th>foo</th><th>bar</th></tr></thead>' +
- '<tbody>' +
- '<tr><td>1</td><td>foo</td><td>bar</td><td>baz</td></tr>' +
- '<tr><td>2</td><td>foo</td><td>bar</td><td>baz</td></tr>' +
- '</tbody></table>' );
+ var $table = $( '<table class="sortable">' +
+ '<thead><tr><th rowspan="2">n</th><th colspan="2">foo</th><th rowspan="2">baz</th></tr>' +
+ '<tr><th>foo</th><th>bar</th></tr></thead>' +
+ '<tbody>' +
+ '<tr><td>1</td><td>foo</td><td>bar</td><td>baz</td></tr>' +
+ '<tr><td>2</td><td>foo</td><td>bar</td><td>baz</td></tr>' +
+ '</tbody></table>' );
$table.tablesorter();
assert.equal( $table.find( 'tr:eq(1) th:eq(1)').data('headerIndex'),
// Note: The ones with # are commented out as those are interpreted as fragment and
// as such end up being valid.
'A é B',
- //'A é B',
- //'A é B',
+ // 'A é B',
+ // 'A é B',
// Subject of NS_TALK does not roundtrip to NS_MAIN
'Talk:File:Example.svg',
// Directory navigation
} );
QUnit.test( 'getRelativeText', 5, function ( assert ) {
- var cases = [
- {
- text: 'asd',
- relativeTo: 123,
- expectedResult: ':Asd'
- },
- {
- text: 'dfg',
- relativeTo: 0,
- expectedResult: 'Dfg'
- },
- {
- text: 'Template:Ghj',
- relativeTo: 0,
- expectedResult: 'Template:Ghj'
- },
- {
- text: 'Template:1',
- relativeTo: 10,
- expectedResult: '1'
- },
- {
- text: 'User:Hi',
- relativeTo: 10,
- expectedResult: 'User:Hi'
- }
- ], i, thisCase, title;
+ var i, thisCase, title,
+ cases = [
+ {
+ text: 'asd',
+ relativeTo: 123,
+ expectedResult: ':Asd'
+ },
+ {
+ text: 'dfg',
+ relativeTo: 0,
+ expectedResult: 'Dfg'
+ },
+ {
+ text: 'Template:Ghj',
+ relativeTo: 0,
+ expectedResult: 'Template:Ghj'
+ },
+ {
+ text: 'Template:1',
+ relativeTo: 10,
+ expectedResult: '1'
+ },
+ {
+ text: 'User:Hi',
+ relativeTo: 10,
+ expectedResult: 'User:Hi'
+ }
+ ];
for ( i = 0; i < cases.length; i++ ) {
thisCase = cases[i];
mw.jqueryMsg.getMessageFunction = oldGMF;
} );
-formatnumTests = [
- {
- lang: 'en',
- number: 987654321.654321,
- result: '987,654,321.654',
- description: 'formatnum test for English, decimal seperator'
- },
- {
- lang: 'ar',
- number: 987654321.654321,
- result: '٩٨٧٬٦٥٤٬٣٢١٫٦٥٤',
- description: 'formatnum test for Arabic, with decimal seperator'
- },
- {
- lang: 'ar',
- number: '٩٨٧٦٥٤٣٢١٫٦٥٤٣٢١',
- result: 987654321,
- integer: true,
- description: 'formatnum test for Arabic, with decimal seperator, reverse'
- },
- {
- lang: 'ar',
- number: -12.89,
- result: '-١٢٫٨٩',
- description: 'formatnum test for Arabic, negative number'
- },
- {
- lang: 'ar',
- number: '-١٢٫٨٩',
- result: -12,
- integer: true,
- description: 'formatnum test for Arabic, negative number, reverse'
- },
- {
- lang: 'nl',
- number: 987654321.654321,
- result: '987.654.321,654',
- description: 'formatnum test for Nederlands, decimal seperator'
- },
- {
- lang: 'nl',
- number: -12.89,
- result: '-12,89',
- description: 'formatnum test for Nederlands, negative number'
- },
- {
- lang: 'nl',
- number: '.89',
- result: '0,89',
- description: 'formatnum test for Nederlands'
- },
- {
- lang: 'nl',
- number: 'invalidnumber',
- result: 'invalidnumber',
- description: 'formatnum test for Nederlands, invalid number'
- },
- {
- lang: 'ml',
- number: '1000000000',
- result: '1,00,00,00,000',
- description: 'formatnum test for Malayalam'
- },
- {
- lang: 'ml',
- number: '-1000000000',
- result: '-1,00,00,00,000',
- description: 'formatnum test for Malayalam, negative number'
- },
- /*
- * This will fail because of wrong pattern for ml in MW(different from CLDR)
- {
- lang: 'ml',
- number: '1000000000.000',
- result: '1,00,00,00,000.000',
- description: 'formatnum test for Malayalam with decimal place'
- },
- */
- {
- lang: 'hi',
- number: '123456789.123456789',
- result: '१२,३४,५६,७८९',
- description: 'formatnum test for Hindi'
- },
- {
- lang: 'hi',
- number: '१२,३४,५६,७८९',
- result: '१२,३४,५६,७८९',
- description: 'formatnum test for Hindi, Devanagari digits passed'
- },
- {
- lang: 'hi',
- number: '१२३४५६,७८९',
- result: '123456',
- integer: true,
- description: 'formatnum test for Hindi, Devanagari digits passed to get integer value'
- }
-];
-
-QUnit.test( 'formatnum', formatnumTests.length, function ( assert ) {
- mw.messages.set( 'formatnum-msg', '{{formatnum:$1}}' );
- mw.messages.set( 'formatnum-msg-int', '{{formatnum:$1|R}}' );
- var queue = $.map( formatnumTests, function ( test ) {
- return function ( next ) {
- getMwLanguage( test.lang )
- .done( function ( langClass ) {
- mw.config.set( 'wgUserLanguage', test.lang );
- var parser = new mw.jqueryMsg.parser( { language: langClass } );
- assert.equal(
- parser.parse( test.integer ? 'formatnum-msg-int' : 'formatnum-msg',
- [ test.number ] ).html(),
- test.result,
- test.description
- );
- } )
- .fail( function () {
- assert.ok( false, 'Language "' + test.lang + '" failed to load' );
- } )
- .always( next );
- };
+ formatnumTests = [
+ {
+ lang: 'en',
+ number: 987654321.654321,
+ result: '987,654,321.654',
+ description: 'formatnum test for English, decimal seperator'
+ },
+ {
+ lang: 'ar',
+ number: 987654321.654321,
+ result: '٩٨٧٬٦٥٤٬٣٢١٫٦٥٤',
+ description: 'formatnum test for Arabic, with decimal seperator'
+ },
+ {
+ lang: 'ar',
+ number: '٩٨٧٦٥٤٣٢١٫٦٥٤٣٢١',
+ result: 987654321,
+ integer: true,
+ description: 'formatnum test for Arabic, with decimal seperator, reverse'
+ },
+ {
+ lang: 'ar',
+ number: -12.89,
+ result: '-١٢٫٨٩',
+ description: 'formatnum test for Arabic, negative number'
+ },
+ {
+ lang: 'ar',
+ number: '-١٢٫٨٩',
+ result: -12,
+ integer: true,
+ description: 'formatnum test for Arabic, negative number, reverse'
+ },
+ {
+ lang: 'nl',
+ number: 987654321.654321,
+ result: '987.654.321,654',
+ description: 'formatnum test for Nederlands, decimal seperator'
+ },
+ {
+ lang: 'nl',
+ number: -12.89,
+ result: '-12,89',
+ description: 'formatnum test for Nederlands, negative number'
+ },
+ {
+ lang: 'nl',
+ number: '.89',
+ result: '0,89',
+ description: 'formatnum test for Nederlands'
+ },
+ {
+ lang: 'nl',
+ number: 'invalidnumber',
+ result: 'invalidnumber',
+ description: 'formatnum test for Nederlands, invalid number'
+ },
+ {
+ lang: 'ml',
+ number: '1000000000',
+ result: '1,00,00,00,000',
+ description: 'formatnum test for Malayalam'
+ },
+ {
+ lang: 'ml',
+ number: '-1000000000',
+ result: '-1,00,00,00,000',
+ description: 'formatnum test for Malayalam, negative number'
+ },
+ /*
+ * This will fail because of wrong pattern for ml in MW(different from CLDR)
+ {
+ lang: 'ml',
+ number: '1000000000.000',
+ result: '1,00,00,00,000.000',
+ description: 'formatnum test for Malayalam with decimal place'
+ },
+ */
+ {
+ lang: 'hi',
+ number: '123456789.123456789',
+ result: '१२,३४,५६,७८९',
+ description: 'formatnum test for Hindi'
+ },
+ {
+ lang: 'hi',
+ number: '१२,३४,५६,७८९',
+ result: '१२,३४,५६,७८९',
+ description: 'formatnum test for Hindi, Devanagari digits passed'
+ },
+ {
+ lang: 'hi',
+ number: '१२३४५६,७८९',
+ result: '123456',
+ integer: true,
+ description: 'formatnum test for Hindi, Devanagari digits passed to get integer value'
+ }
+ ];
+
+ QUnit.test( 'formatnum', formatnumTests.length, function ( assert ) {
+ mw.messages.set( 'formatnum-msg', '{{formatnum:$1}}' );
+ mw.messages.set( 'formatnum-msg-int', '{{formatnum:$1|R}}' );
+ var queue = $.map( formatnumTests, function ( test ) {
+ return function ( next ) {
+ getMwLanguage( test.lang )
+ .done( function ( langClass ) {
+ mw.config.set( 'wgUserLanguage', test.lang );
+ var parser = new mw.jqueryMsg.parser( { language: langClass } );
+ assert.equal(
+ parser.parse( test.integer ? 'formatnum-msg-int' : 'formatnum-msg',
+ [ test.number ] ).html(),
+ test.result,
+ test.description
+ );
+ } )
+ .fail( function () {
+ assert.ok( false, 'Language "' + test.lang + '" failed to load' );
+ } )
+ .always( next );
+ };
+ } );
+ QUnit.stop();
+ process( queue, QUnit.start );
+ } );
+
+ // HTML in wikitext
+ QUnit.test( 'HTML', 26, function ( assert ) {
+ mw.messages.set( 'jquerymsg-italics-msg', '<i>Very</i> important' );
+
+ assertBothModes( assert, ['jquerymsg-italics-msg'], mw.messages.get( 'jquerymsg-italics-msg' ), 'Simple italics unchanged' );
+
+ mw.messages.set( 'jquerymsg-bold-msg', '<b>Strong</b> speaker' );
+ assertBothModes( assert, ['jquerymsg-bold-msg'], mw.messages.get( 'jquerymsg-bold-msg' ), 'Simple bold unchanged' );
+
+ mw.messages.set( 'jquerymsg-bold-italics-msg', 'It is <b><i>key</i></b>' );
+ assertBothModes( assert, ['jquerymsg-bold-italics-msg'], mw.messages.get( 'jquerymsg-bold-italics-msg' ), 'Bold and italics nesting order preserved' );
+
+ mw.messages.set( 'jquerymsg-italics-bold-msg', 'It is <i><b>vital</b></i>' );
+ assertBothModes( assert, ['jquerymsg-italics-bold-msg'], mw.messages.get( 'jquerymsg-italics-bold-msg' ), 'Italics and bold nesting order preserved' );
+
+ mw.messages.set( 'jquerymsg-italics-with-link', 'An <i>italicized [[link|wiki-link]]</i>' );
+
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-italics-with-link' ),
+ 'An <i>italicized <a title="link" href="' + mw.html.escape( mw.util.getUrl( 'link' ) ) + '">wiki-link</i>',
+ 'Italics with link inside in parse mode'
+ );
+
+ assert.equal(
+ formatText( 'jquerymsg-italics-with-link' ),
+ mw.messages.get( 'jquerymsg-italics-with-link' ),
+ 'Italics with link unchanged in text mode'
+ );
+
+ mw.messages.set( 'jquerymsg-italics-id-class', '<i id="foo" class="bar">Foo</i>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-italics-id-class' ),
+ mw.messages.get( 'jquerymsg-italics-id-class' ),
+ 'ID and class are allowed'
+ );
+
+ mw.messages.set( 'jquerymsg-italics-onclick', '<i onclick="alert(\'foo\')">Foo</i>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-italics-onclick' ),
+ '<i onclick="alert(\'foo\')">Foo</i>',
+ 'element with onclick is escaped because it is not allowed'
+ );
+
+ mw.messages.set( 'jquerymsg-script-msg', '<script >alert( "Who put this tag here?" );</script>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-script-msg' ),
+ '<script >alert( "Who put this tag here?" );</script>',
+ 'Tag outside whitelist escaped in parse mode'
+ );
+
+ assert.equal(
+ formatText( 'jquerymsg-script-msg' ),
+ mw.messages.get( 'jquerymsg-script-msg' ),
+ 'Tag outside whitelist unchanged in text mode'
+ );
+
+ mw.messages.set( 'jquerymsg-script-link-msg', '<script>[[Foo|bar]]</script>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-script-link-msg' ),
+ '<script><a title="Foo" href="' + mw.html.escape( mw.util.getUrl( 'Foo' ) ) + '">bar</a></script>',
+ 'Script tag text is escaped because that element is not allowed, but link inside is still HTML'
+ );
+
+ mw.messages.set( 'jquerymsg-mismatched-html', '<i class="important">test</b>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-mismatched-html' ),
+ '<i class="important">test</b>',
+ 'Mismatched HTML start and end tag treated as text'
+ );
+
+ // TODO (mattflaschen, 2013-03-18): It's not a security issue, but there's no real
+ // reason the htmlEmitter span needs to be here. It's an artifact of how emitting works.
+ mw.messages.set( 'jquerymsg-script-and-external-link', '<script>alert( "jquerymsg-script-and-external-link test" );</script> [http://example.com <i>Foo</i> bar]' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-script-and-external-link' ),
+ '<script>alert( "jquerymsg-script-and-external-link test" );</script> <a href="http://example.com"><span class="mediaWiki_htmlEmitter"><i>Foo</i> bar</span></a>',
+ 'HTML tags in external links not interfering with escaping of other tags'
+ );
+
+ mw.messages.set( 'jquerymsg-link-script', '[http://example.com <script>alert( "jquerymsg-link-script test" );</script>]' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-link-script' ),
+ '<a href="http://example.com"><span class="mediaWiki_htmlEmitter"><script>alert( "jquerymsg-link-script test" );</script></span></a>',
+ 'Non-whitelisted HTML tag in external link anchor treated as text'
+ );
+
+ // Intentionally not using htmlEqual for the quote tests
+ mw.messages.set( 'jquerymsg-double-quotes-preserved', '<i id="double">Double</i>' );
+ assert.equal(
+ formatParse( 'jquerymsg-double-quotes-preserved' ),
+ mw.messages.get( 'jquerymsg-double-quotes-preserved' ),
+ 'Attributes with double quotes are preserved as such'
+ );
+
+ mw.messages.set( 'jquerymsg-single-quotes-normalized-to-double', '<i id=\'single\'>Single</i>' );
+ assert.equal(
+ formatParse( 'jquerymsg-single-quotes-normalized-to-double' ),
+ '<i id="single">Single</i>',
+ 'Attributes with single quotes are normalized to double'
+ );
+
+ mw.messages.set( 'jquerymsg-escaped-double-quotes-attribute', '<i style="font-family:"Arial"">Styled</i>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-escaped-double-quotes-attribute' ),
+ mw.messages.get( 'jquerymsg-escaped-double-quotes-attribute' ),
+ 'Escaped attributes are parsed correctly'
+ );
+
+ mw.messages.set( 'jquerymsg-escaped-single-quotes-attribute', '<i style=\'font-family:'Arial'\'>Styled</i>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-escaped-single-quotes-attribute' ),
+ mw.messages.get( 'jquerymsg-escaped-single-quotes-attribute' ),
+ 'Escaped attributes are parsed correctly'
+ );
+
+ mw.messages.set( 'jquerymsg-wikitext-contents-parsed', '<i>[http://example.com Example]</i>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-wikitext-contents-parsed' ),
+ '<i><a href="http://example.com">Example</a></i>',
+ 'Contents of valid tag are treated as wikitext, so external link is parsed'
+ );
+
+ mw.messages.set( 'jquerymsg-wikitext-contents-script', '<i><script>Script inside</script></i>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-wikitext-contents-script' ),
+ '<i><span class="mediaWiki_htmlEmitter"><script>Script inside</script></span></i>',
+ 'Contents of valid tag are treated as wikitext, so invalid HTML element is treated as text'
+ );
+
+ mw.messages.set( 'jquerymsg-unclosed-tag', 'Foo<tag>bar' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-unclosed-tag' ),
+ 'Foo<tag>bar',
+ 'Nonsupported unclosed tags are escaped'
+ );
+
+ mw.messages.set( 'jquerymsg-self-closing-tag', 'Foo<tag/>bar' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-self-closing-tag' ),
+ 'Foo<tag/>bar',
+ 'Self-closing tags don\'t cause a parse error'
+ );
} );
- QUnit.stop();
- process( queue, QUnit.start );
-} );
-
-// HTML in wikitext
-QUnit.test( 'HTML', 26, function ( assert ) {
- mw.messages.set( 'jquerymsg-italics-msg', '<i>Very</i> important' );
-
- assertBothModes( assert, ['jquerymsg-italics-msg'], mw.messages.get( 'jquerymsg-italics-msg' ), 'Simple italics unchanged' );
-
- mw.messages.set( 'jquerymsg-bold-msg', '<b>Strong</b> speaker' );
- assertBothModes( assert, ['jquerymsg-bold-msg'], mw.messages.get( 'jquerymsg-bold-msg' ), 'Simple bold unchanged' );
-
- mw.messages.set( 'jquerymsg-bold-italics-msg', 'It is <b><i>key</i></b>' );
- assertBothModes( assert, ['jquerymsg-bold-italics-msg'], mw.messages.get( 'jquerymsg-bold-italics-msg' ), 'Bold and italics nesting order preserved' );
-
- mw.messages.set( 'jquerymsg-italics-bold-msg', 'It is <i><b>vital</b></i>' );
- assertBothModes( assert, ['jquerymsg-italics-bold-msg'], mw.messages.get( 'jquerymsg-italics-bold-msg' ), 'Italics and bold nesting order preserved' );
-
- mw.messages.set( 'jquerymsg-italics-with-link', 'An <i>italicized [[link|wiki-link]]</i>' );
-
- assert.htmlEqual(
- formatParse( 'jquerymsg-italics-with-link' ),
- 'An <i>italicized <a title="link" href="' + mw.html.escape( mw.util.getUrl( 'link' ) ) + '">wiki-link</i>',
- 'Italics with link inside in parse mode'
- );
-
- assert.equal(
- formatText( 'jquerymsg-italics-with-link' ),
- mw.messages.get( 'jquerymsg-italics-with-link' ),
- 'Italics with link unchanged in text mode'
- );
-
- mw.messages.set( 'jquerymsg-italics-id-class', '<i id="foo" class="bar">Foo</i>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-italics-id-class' ),
- mw.messages.get( 'jquerymsg-italics-id-class' ),
- 'ID and class are allowed'
- );
-
- mw.messages.set( 'jquerymsg-italics-onclick', '<i onclick="alert(\'foo\')">Foo</i>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-italics-onclick' ),
- '<i onclick="alert(\'foo\')">Foo</i>',
- 'element with onclick is escaped because it is not allowed'
- );
-
- mw.messages.set( 'jquerymsg-script-msg', '<script >alert( "Who put this tag here?" );</script>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-script-msg' ),
- '<script >alert( "Who put this tag here?" );</script>',
- 'Tag outside whitelist escaped in parse mode'
- );
-
- assert.equal(
- formatText( 'jquerymsg-script-msg' ),
- mw.messages.get( 'jquerymsg-script-msg' ),
- 'Tag outside whitelist unchanged in text mode'
- );
-
- mw.messages.set( 'jquerymsg-script-link-msg', '<script>[[Foo|bar]]</script>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-script-link-msg' ),
- '<script><a title="Foo" href="' + mw.html.escape( mw.util.getUrl( 'Foo' ) ) + '">bar</a></script>',
- 'Script tag text is escaped because that element is not allowed, but link inside is still HTML'
- );
-
- mw.messages.set( 'jquerymsg-mismatched-html', '<i class="important">test</b>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-mismatched-html' ),
- '<i class="important">test</b>',
- 'Mismatched HTML start and end tag treated as text'
- );
-
- // TODO (mattflaschen, 2013-03-18): It's not a security issue, but there's no real
- // reason the htmlEmitter span needs to be here. It's an artifact of how emitting works.
- mw.messages.set( 'jquerymsg-script-and-external-link', '<script>alert( "jquerymsg-script-and-external-link test" );</script> [http://example.com <i>Foo</i> bar]' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-script-and-external-link' ),
- '<script>alert( "jquerymsg-script-and-external-link test" );</script> <a href="http://example.com"><span class="mediaWiki_htmlEmitter"><i>Foo</i> bar</span></a>',
- 'HTML tags in external links not interfering with escaping of other tags'
- );
-
- mw.messages.set( 'jquerymsg-link-script', '[http://example.com <script>alert( "jquerymsg-link-script test" );</script>]' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-link-script' ),
- '<a href="http://example.com"><span class="mediaWiki_htmlEmitter"><script>alert( "jquerymsg-link-script test" );</script></span></a>',
- 'Non-whitelisted HTML tag in external link anchor treated as text'
- );
-
- // Intentionally not using htmlEqual for the quote tests
- mw.messages.set( 'jquerymsg-double-quotes-preserved', '<i id="double">Double</i>' );
- assert.equal(
- formatParse( 'jquerymsg-double-quotes-preserved' ),
- mw.messages.get( 'jquerymsg-double-quotes-preserved' ),
- 'Attributes with double quotes are preserved as such'
- );
-
- mw.messages.set( 'jquerymsg-single-quotes-normalized-to-double', '<i id=\'single\'>Single</i>' );
- assert.equal(
- formatParse( 'jquerymsg-single-quotes-normalized-to-double' ),
- '<i id="single">Single</i>',
- 'Attributes with single quotes are normalized to double'
- );
-
- mw.messages.set( 'jquerymsg-escaped-double-quotes-attribute', '<i style="font-family:"Arial"">Styled</i>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-escaped-double-quotes-attribute' ),
- mw.messages.get( 'jquerymsg-escaped-double-quotes-attribute' ),
- 'Escaped attributes are parsed correctly'
- );
-
- mw.messages.set( 'jquerymsg-escaped-single-quotes-attribute', '<i style=\'font-family:'Arial'\'>Styled</i>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-escaped-single-quotes-attribute' ),
- mw.messages.get( 'jquerymsg-escaped-single-quotes-attribute' ),
- 'Escaped attributes are parsed correctly'
- );
-
- mw.messages.set( 'jquerymsg-wikitext-contents-parsed', '<i>[http://example.com Example]</i>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-wikitext-contents-parsed' ),
- '<i><a href="http://example.com">Example</a></i>',
- 'Contents of valid tag are treated as wikitext, so external link is parsed'
- );
-
- mw.messages.set( 'jquerymsg-wikitext-contents-script', '<i><script>Script inside</script></i>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-wikitext-contents-script' ),
- '<i><span class="mediaWiki_htmlEmitter"><script>Script inside</script></span></i>',
- 'Contents of valid tag are treated as wikitext, so invalid HTML element is treated as text'
- );
-
- mw.messages.set( 'jquerymsg-unclosed-tag', 'Foo<tag>bar' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-unclosed-tag' ),
- 'Foo<tag>bar',
- 'Nonsupported unclosed tags are escaped'
- );
-
- mw.messages.set( 'jquerymsg-self-closing-tag', 'Foo<tag/>bar' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-self-closing-tag' ),
- 'Foo<tag/>bar',
- 'Self-closing tags don\'t cause a parse error'
- );
-} );
QUnit.test( 'Behavior in case of invalid wikitext', 3, function ( assert ) {
mw.messages.set( 'invalid-wikitext', '<b>{{FAIL}}</b>' );
// Convenience method for asserting the same result for multiple formats
function assertMultipleFormats( messageArguments, formats, expectedResult, assertMessage ) {
- var len = formats.length, format, i;
+ var format, i,
+ len = formats.length;
+
for ( i = 0; i < len; i++ ) {
format = formats[i];
assert.equal( mw.message.apply( null, messageArguments )[format](), expectedResult, assertMessage + ' when format is ' + format );