) ),
'mediawiki.util' => new ResourceLoaderFileModule( array(
'scripts' => 'resources/mediawiki/mediawiki.util.js',
+ 'debugScripts' => 'resources/mediawiki/mediawiki.utiltest.js',
) ),
/* MediaWiki Legacy */
*/
// New fallback String trimming functionality, was introduced natively in JavaScript 1.8.1
-if (typeof String.prototype.trimx === 'undefined') {
+if (typeof String.prototype.trim === 'undefined') {
// Add removing trailing and leading whitespace functionality cross-browser
// See also: http://blog.stevenlevithan.com/archives/faster-trim-javascript
String.prototype.trim = function () {
- return this.replace(/^\s+|\s+$/g, '');
+ return this.replace(/^\s+|\s+$/g, '');
};
}
if (typeof String.prototype.trimLeft === 'undefined') {
return this.replace(/^\s\s*/, "");
};
}
-
+
if (typeof String.prototype.trimRight === 'undefined') {
String.prototype.trimRight = function () {
return this.replace(/\s\s*$/, "");
*/
// Attach to window
window.mediaWiki = new ( function( $ ) {
-
+
/* Constants */
-
+
// This will not change until we are 100% ready to turn off legacy globals
var LEGACY_GLOBALS = true;
-
+
/* Private Members */
-
+
var that = this;
-
+
/* Prototypes */
-
+
this.prototypes = {
/*
* An object which allows single and multiple get/set/exists functionality on a list of key / value pairs
* where value is the data to be parsed and options is additional data passed through to the parser
*/
'map': function( global, parser, fallback ) {
-
+
/* Private Members */
-
+
var that = this;
var values = global === true ? window : {};
-
+
/* Public Methods */
-
+
/**
* Gets one or more values
*
return values;
}
};
-
+
/**
* Sets one or multiple configuration values using a key and a value or an object of keys and values
*
values[selection] = value;
}
};
-
+
/**
* Checks if one or multiple configuration fields exist
*/
};
}
};
-
+
/* Methods */
-
+
/*
* Dummy function which in debug mode can be replaced with a function that does something clever
*/
this.log = function() { };
-
+
/*
* List of configuration values
*
* In legacy mode the values this object wraps will be in the global space
*/
this.config = new this.prototypes.map( LEGACY_GLOBALS );
-
+
/*
* Information about the current user
*/
this.user = new ( function() {
-
+
/* Public Members */
-
+
this.options = new that.prototypes.map();
} )();
-
+
/*
* Basic parser, can be replaced with something more robust
*/
}
return text;
};
-
+
/*
* Localization system
*/
this.msg = new that.prototypes.map( false, this.parser, function( key ) { return '<' + key + '>'; } );
-
+
/*
* Client-side module loader which integrates with the MediaWiki ResourceLoader
*/
this.loader = new ( function() {
-
+
/* Private Members */
-
+
var that = this;
/*
* Mapping of registered modules
var suspended = true;
// Flag inidicating that document ready has occured
var ready = false;
-
+
/* Private Methods */
-
+
/**
* Generates an ISO8601 "basic" string from a UNIX timestamp
*/
pad( d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds() ), 'Z'
].join( '' );
}
-
+
/**
* Recursively resolves dependencies and detects circular references
*/
resolved[resolved.length] = module;
unresolved.splice( unresolved.indexOf( module ), 1 );
}
-
+
/**
* Gets a list of modules names that a module dependencies in their proper dependency order
*
}
throw new Error( 'Invalid module argument: ' + module );
};
-
+
/**
* Narrows a list of module names down to those matching a specific state. Possible states are 'undefined',
* 'registered', 'loading', 'loaded', or 'ready'
}
return list;
}
-
+
/**
* Executes a loaded module, making it ready to use
*
} catch ( e ) {
mediaWiki.log( 'Exception thrown by ' + module + ': ' + e.message );
mediaWiki.log( e );
- registry[module].state = 'error';
+ registry[module].state = 'error';
// Run error callbacks of jobs affected by this condition
for ( var j = 0; j < jobs.length; j++ ) {
if ( jobs[j].dependencies.indexOf( module ) !== -1 ) {
}
}
}
-
+
/**
* Adds a dependencies to the queue with optional callbacks to be run when the dependencies are ready or fail
*
// Work the queue
that.work();
}
-
+
function sortQuery(o) {
var sorted = {}, key, a = [];
for ( key in o ) {
}
return sorted;
}
-
+
/* Public Methods */
-
+
/**
* Requests dependencies from server, loading and executing when things when ready.
*/
}
}
};
-
+
/**
* Registers a module, letting the system know about it and it's dependencies. loader.js files contain calls
* to this function.
registry[module].dependencies = dependencies;
}
};
-
+
/**
* Implements a module, giving the system a course of action to take upon loading. Results of a request for
* one or more modules contain calls to this function.
request( module );
}
};
-
+
/**
* Executes a function as soon as one or more required modules are ready
*
request( dependencies, ready, error );
}
};
-
+
/**
* Loads an external script or one or more modules for future use
*
return true;
}
};
-
+
/**
* Flushes the request queue and begin executing load requests on demand
*/
suspended = false;
that.work();
};
-
+
/**
* Changes the state of a module
*
}
registry[module].state = state;
};
-
+
/**
* Gets the version of a module
*
}
return null;
}
-
+
/* Cache document ready status */
-
+
$(document).ready( function() { ready = true; } );
} )();
-
+
/* Extension points */
-
+
this.legacy = {};
-
+
} )( jQuery );
/* Auto-register from pre-loaded startup scripts */
} else if (is_ff2) {
this.tooltipAccessKeyPrefix = 'alt-shift-';
}
-
+
// Setup CheckboxShiftClick
$.fn.enableCheckboxShiftClick = function () {
var prevCheckbox = null;
});
return $box;
};
-
+
// Prototype enhancements
if (typeof String.prototype.ucFirst === 'undefined') {
String.prototype.ucFirst = function () {
return this.substr(0, 1).toUpperCase() + this.substr(1, this.length);
};
}
-
+
// Any initialisation after the DOM is ready
$(function () {
- $('input[type=checkbox]:not(.noshiftselect)').enableCheckboxShiftClick();
+ $('input[type=checkbox]:not(.noshiftselect)').enableCheckboxShiftClick();
});
/**
* Check is a variable is empty. Support for strings, booleans, arrays and objects.
- * String "0" is considered empty. String containing only whitespace (ie. " ") is considered not empty.
+ * String "0" is considered empty. String containing only whitespace (ie. " ") is considered not empty.
*
* @param Mixed v the variable to check for empty ness
*/
};
-})(jQuery, mediaWiki);
+ mediaWiki.util.init();
-mediaWiki.util.init();
\ No newline at end of file
+})(jQuery, mediaWiki);
\ No newline at end of file
--- /dev/null
+/*
+ * mediaWiki Debug Test Suit on [[Special:MWUtilJSTest]] (only when ?debug=true)
+ */
+
+(function ($, mw) {
+
+ mediaWiki.test = {
+
+ /* Variables */
+ '$bodyContent' : null,
+ '$table' : null,
+ 'addedTests' : [],
+
+ /* Functions */
+
+ /**
+ * Adds a row to the test-table
+ *
+ * @param String code Code of the test to be executed
+ * @param String result Expected result in 'var (vartype)' form.
+ */
+ 'addTest' : function (code, result) {
+ this.addedTests.push([code, result]);
+ this.$table.append('<tr><td>' + mw.util.htmlEscape(code) + '</td><td>' + mw.util.htmlEscape(result) + '<td></td></td><td>?</td></tr>');
+ },
+
+ /* Initialisation */
+ 'initialised' : false,
+ 'init' : function () {
+ if (this.initialised === false) {
+ this.initialised = true;
+ $(function () {
+ if (wgTitle == 'MWUtilJSTest' && wgCanonicalNamespace == 'Special') {
+
+ // Build page
+ document.title = 'mediaWiki.util JavaScript Test - ' + wgSiteName;
+ $('#firstHeading').text('mediaWiki.util JavaScript Test');
+ mw.test.bodyContent = $('#bodyContent');
+ mw.test.bodyContent.html(
+ '<p>Below is a list of tests to confirm proper functionality of the mediaWiki.util functions</p>' +
+ '<hr />' +
+ '<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>'
+ );
+ mw.test.$table = $('table#mw-mwutiltest-table');
+
+ // Populate tests
+ mw.test.addTest('typeof String.prototype.trim',
+ 'function (string)');
+ mw.test.addTest('typeof String.prototype.trimLeft',
+ 'function (string)');
+ mw.test.addTest('typeof String.prototype.trimRight',
+ 'function (string)');
+ mw.test.addTest('typeof Array.prototype.compare',
+ 'function (string)');
+ mw.test.addTest('typeof Array.prototype.indexOf',
+ 'function (string)');
+ mw.test.addTest('4',
+ '4 (number)');
+ mw.test.addTest('typeof mediaWiki',
+ 'object (string)');
+ mw.test.addTest('typeof mw',
+ 'object (string)');
+ mw.test.addTest('typeof mw.util',
+ 'object (string)');
+ mw.test.addTest('typeof String.prototype.ucFirst',
+ 'function (string)');
+ mw.test.addTest('\'mediawiki\'.ucFirst()',
+ 'Mediawiki (string)');
+ mw.test.addTest('typeof $.fn.enableCheckboxShiftClick',
+ 'function (string)');
+ mw.test.addTest('typeof mw.util.rawurlencode',
+ 'function (string)');
+ mw.test.addTest('mw.util.rawurlencode(\'Test: A&B/Here\')',
+ 'Test%3A%20A%26B%2FHere (string)');
+ mw.test.addTest('typeof mw.util.getWikilink',
+ 'function (string)');
+ mw.test.addTest('typeof mw.util.getParamValue',
+ 'function (string)');
+ mw.test.addTest('mw.util.getParamValue(\'debug\')',
+ 'true (string)');
+ mw.test.addTest('typeof mw.util.htmlEscape',
+ 'function (string)');
+ mw.test.addTest('mw.util.htmlEscape(\'<a href="http://mw.org/?a=b&c=d">link</a>\')',
+ '<a href="http://mw.org/?a=b&c=d">link</a> (string)');
+ mw.test.addTest('typeof mw.util.htmlUnescape',
+ 'function (string)');
+ mw.test.addTest('mw.util.htmlUnescape(\'<a href="http://mw.org/?a=b&c=d">link</a>\')',
+ '<a href="http://mw.org/?a=b&c=d">link</a> (string)');
+ mw.test.addTest('typeof mw.util.tooltipAccessKeyRegexp',
+ 'function (string)');
+ mw.test.addTest('typeof mw.util.updateTooltipAccessKeys',
+ 'function (string)');
+ mw.test.addTest('typeof mw.util.addPortletLink',
+ 'function (string)');
+ mw.test.addTest('typeof mw.util.addPortletLink("p-tb", "http://mediawiki.org/", "MediaWiki.org", "t-mworg", "Go to MediaWiki.org ", "m", "#t-print")',
+ 'object (string)');
+ mw.test.addTest('mw.util.addPortletLink("p-tb", "http://mediawiki.org/", "MediaWiki.org", "t-mworg", "Go to MediaWiki.org ", "m", "#t-print").outerHTML',
+ '<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)');
+
+ // Run tests and compare results
+ var exec,
+ result,
+ resulttype,
+ numberoftests = 0,
+ numberoferrors = 0,
+ $testrows;
+ $testrows = mw.test.$table.find('tr');
+ $.each(mw.test.addedTests, (function (i) {
+ numberoftests++;
+
+ exec = mw.test.addedTests[i][0];
+ shouldreturn = mw.test.addedTests[i][1];
+ doesreturn = eval(exec);
+ doesreturn = doesreturn + ' (' + typeof doesreturn + ')';
+ $thisrow = $testrows.eq(i + 1);
+ $thisrow.find('> td').eq(2).text(doesreturn);
+
+ if (shouldreturn === doesreturn) {
+ $thisrow.find('> td').eq(3).css('background', '#EFE').text('OK');
+ } else {
+ $thisrow.find('> td').eq(3).css('background', '#FEE').text('ERROR');
+ numberoferrors++;
+ }
+
+ })
+ );
+ mw.test.$table.before('<p><strong>Ran ' + numberoftests + ' tests. ' + numberoferrors + ' error(s). </p>');
+
+ }
+ });
+ }
+ }
+ };
+
+ mediaWiki.test.init();
+
+})(jQuery, mediaWiki);
\ No newline at end of file