From 51e3fb9a716f3ccd3b114109e5a5045a09864ff0 Mon Sep 17 00:00:00 2001 From: Krinkle Date: Sat, 23 Oct 2010 17:24:07 +0000 Subject: [PATCH] adding begin of mediaWiki.util and loading it by default + trailing whitespace cleanup in mediawiki.js --- includes/OutputPage.php | 1 + resources/Resources.php | 3 + resources/mediawiki/mediawiki.js | 40 ++--- resources/mediawiki/mediawiki.util.js | 228 ++++++++++++++++++++++++++ 4 files changed, 252 insertions(+), 20 deletions(-) create mode 100644 resources/mediawiki/mediawiki.util.js diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 2a6030d04f..1baf8e248e 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -1613,6 +1613,7 @@ class OutputPage { // Add base resources $this->addModules( array( 'mediawiki.legacy.wikibits' ) ); + $this->addModules( array( 'mediawiki.util' ) ); // Add various resources if required if ( $wgUseAjax ) { diff --git a/resources/Resources.php b/resources/Resources.php index f213061fd5..ba15dd352b 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -326,6 +326,9 @@ return array( 'scripts' => 'resources/mediawiki/mediawiki.views.history.js', 'dependencies' => 'mediawiki.legacy.history', ) ), + 'mediawiki.util' => new ResourceLoaderFileModule( array( + 'scripts' => 'resources/mediawiki/mediawiki.util.js', + ) ), /* MediaWiki Legacy */ diff --git a/resources/mediawiki/mediawiki.js b/resources/mediawiki/mediawiki.js index 0eef7d750c..3350bb21ad 100644 --- a/resources/mediawiki/mediawiki.js +++ b/resources/mediawiki/mediawiki.js @@ -3,7 +3,7 @@ */ // Make calling .indexOf() on an array work on older browsers -if ( typeof Array.prototype.indexOf === 'undefined' ) { +if ( typeof Array.prototype.indexOf === 'undefined' ) { Array.prototype.indexOf = function( needle ) { for ( var i = 0; i < this.length; i++ ) { if ( this[i] === needle ) { @@ -14,13 +14,13 @@ if ( typeof Array.prototype.indexOf === 'undefined' ) { }; } // Add array comparison functionality -if ( typeof Array.prototype.compare === 'undefined' ) { +if ( typeof Array.prototype.compare === 'undefined' ) { Array.prototype.compare = function( against ) { if ( this.length != against.length ) { return false; } for ( var i = 0; i < against.length; i++ ) { - if ( this[i].compare ) { + if ( this[i].compare ) { if ( !this[i].compare( against[i] ) ) { return false; } @@ -53,7 +53,7 @@ window.mediaWiki = new ( function( $ ) { this.prototypes = { /* * An object which allows single and multiple get/set/exists functionality on a list of key / value pairs - * + * * @param {boolean} global whether to get/set/exists values on the window object or a private object * @param {function} parser function to perform extra processing; in the form of function( value, options ) * @param {function} fallback function to format default fallback; in the form of function( key ) @@ -70,10 +70,10 @@ window.mediaWiki = new ( function( $ ) { /** * Gets one or more values - * + * * If called with no arguments, all values will be returned. If a parser is in use, no parsing will take * place when calling with no arguments or calling with an array of names. - * + * * @param {mixed} selection string name of value to get, array of string names of values to get, or object * of name/option pairs * @param {object} options optional set of options which are also passed to a parser if in use; only used @@ -120,7 +120,7 @@ window.mediaWiki = new ( function( $ ) { /** * Sets one or multiple configuration values using a key and a value or an object of keys and values - * + * * @param {mixed} key string of name by which value will be made accessible, or object of name/value pairs * @param {mixed} value optional value to set, only in use when key is a string */ @@ -161,7 +161,7 @@ window.mediaWiki = new ( 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 ); @@ -204,11 +204,11 @@ window.mediaWiki = new ( function( $ ) { var that = this; /* * Mapping of registered modules - * + * * The jquery module is pre-registered, because it must have already been provided for this object to have * been built, and in debug mode jquery would have been provided through a unique loader request, making it * impossible to hold back registration of jquery until after mediawiki. - * + * * Format: * { * 'moduleName': { @@ -258,7 +258,7 @@ window.mediaWiki = new ( function( $ ) { // Resolves dynamic loader function and replaces it with it's own results if ( typeof registry[module].dependencies === 'function' ) { registry[module].dependencies = registry[module].dependencies(); - // Ensures the module's dependencies are always in an array + // Ensures the module's dependencies are always in an array if ( typeof registry[module].dependencies !== 'object' ) { registry[module].dependencies = [registry[module].dependencies]; } @@ -280,7 +280,7 @@ window.mediaWiki = new ( function( $ ) { /** * Gets a list of modules names that a module dependencies in their proper dependency order - * + * * @param mixed string module name or array of string module names * @return list of dependencies * @throws Error if circular reference is detected @@ -311,7 +311,7 @@ window.mediaWiki = new ( function( $ ) { /** * Narrows a list of module names down to those matching a specific state. Possible states are 'undefined', * 'registered', 'loading', 'loaded', or 'ready' - * + * * @param mixed string or array of strings of module states to filter by * @param array list of module names to filter (optional, all modules will be used by default) * @return array list of filtered module names @@ -345,7 +345,7 @@ window.mediaWiki = new ( function( $ ) { /** * Executes a loaded module, making it ready to use - * + * * @param string module name to execute */ function execute( module ) { @@ -413,7 +413,7 @@ window.mediaWiki = new ( function( $ ) { /** * Adds a dependencies to the queue with optional callbacks to be run when the dependencies are ready or fail - * + * * @param mixed string moulde name or array of string module names * @param function ready callback to execute when all dependencies are ready * @param function error callback to execute when any dependency fails @@ -621,7 +621,7 @@ window.mediaWiki = new ( function( $ ) { /** * Executes a function as soon as one or more required modules are ready - * + * * @param mixed string or array of strings of modules names the callback dependencies to be ready before * executing * @param function callback to execute when all dependencies are ready (optional) @@ -658,7 +658,7 @@ window.mediaWiki = new ( function( $ ) { /** * Loads an external script or one or more modules for future use - * + * * @param {mixed} modules either the name of a module, array of modules, or a URL of an external script or style * @param {string} type mime-type to use if calling with a URL of an external script or style; acceptable values * are "text/css" and "text/javascript"; if no type is provided, text/javascript is assumed @@ -717,7 +717,7 @@ window.mediaWiki = new ( function( $ ) { /** * Changes the state of a module - * + * * @param mixed module string module name or object of module name/state pairs * @param string state string state name */ @@ -736,7 +736,7 @@ window.mediaWiki = new ( function( $ ) { /** * Gets the version of a module - * + * * @param string module name of module to get version for */ this.version = function( module ) { @@ -753,7 +753,6 @@ window.mediaWiki = new ( function( $ ) { /* Extension points */ - this.util = {}; this.legacy = {}; } )( jQuery ); @@ -767,3 +766,4 @@ if ( typeof startUp === 'function' ) { // Alias $j to jQuery for backwards compatibility window.$j = jQuery; +window.mw = mediaWiki; \ No newline at end of file diff --git a/resources/mediawiki/mediawiki.util.js b/resources/mediawiki/mediawiki.util.js new file mode 100644 index 0000000000..45655e33d4 --- /dev/null +++ b/resources/mediawiki/mediawiki.util.js @@ -0,0 +1,228 @@ +/*jslint white: true, browser: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true */ +/* + * Utilities + */ + +(function ($, mw) { + + mediaWiki.util = { + + /* Initialisation */ + 'initialised' : false, + 'init' : function () { + if (this.initialised === false){ + this.initialised = true; + + + // Set tooltipAccessKeyPrefix + if ( is_opera ) { + this.tooltipAccessKeyPrefix = 'shift-esc-'; + } else if ( is_chrome ) { + this.tooltipAccessKeyPrefix = is_chrome_mac ? 'ctrl-option-' : 'alt-'; + } else if ( !is_safari_win && is_safari && webkit_version > 526 ) { + this.tooltipAccessKeyPrefix = 'ctrl-alt-'; + } else if ( !is_safari_win && ( is_safari + || clientPC.indexOf('mac') != -1 + || clientPC.indexOf('konqueror') != -1 ) ) { + this.tooltipAccessKeyPrefix = 'ctrl-'; + } else if ( is_ff2 ) { + this.tooltipAccessKeyPrefix = 'alt-shift-'; + } + + + return true; + } + return false; + }, + + /* Main body */ + + /** + * Encodes the string like PHP's rawurlencode + * + * @param String str string to be encoded + */ + 'rawurlencode' : function (str) { + str = (str + '').toString(); + return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28') + .replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/~/g, '%7E'); + }, + + /** + * Encode pagetitles for use in a URL + * We want / and : to be included as literal characters in our title URLs + * as they otherwise fatally break the title + * + * @param String str string to be encoded + */ + 'wikiUrlencode' : function (str) { + return this.rawurlencode(str).replace(/%20/g, '_').replace(/%3A/g, ':').replace(/%2F/g, '/'); + }, + + + /** + * Grabs the url parameter value for the given parameter + * Returns null if not found + * + * @param String param paramter name + * @param String url url to search through (optional) + */ + 'getParamValue' : function (param, url) { + url = url ? url : document.location.href; + var re = new RegExp('[^#]*[&?]' + param + '=([^&#]*)'); // Get last match, stop at hash + var m = re.exec(url); + if (m && m.length > 1) { + return decodeURIComponent(m[1]); + } + return null; + }, + + /** + * Converts special characters to their HTML entities + * + * @param String str text to escape + * @param Bool quotes if true escapes single and double quotes aswell (by default false) + */ + 'htmlEscape' : function (str, quotes) { + str = $('
').text(str).html(); + if (typeof quotes === 'undefined') { + quotes = false; + } + if (quotes === true) { + str = str.replace(/'/g, ''').replace(/"/g, '"'); + } + return str; + }, + + /** + * Converts HTML entities back to text + * + * @param String str text to unescape + */ + 'htmlUnescape' : function (str) { + return $('
').html(str).text(); + }, + + // Access key prefix + // will be re-defined based on browser/operating system detection in mw.util.init() + 'tooltipAccessKeyPrefix' : 'alt-', + + // Regex to match accesskey tooltips + 'tooltipAccessKeyRegexp': /\[(ctrl-)?(alt-)?(shift-)?(esc-)?(.)\]$/, + + /** + * Add the appropriate prefix to the accesskey shown in the tooltip. + * If the nodeList parameter is given, only those nodes are updated; + * otherwise, all the nodes that will probably have accesskeys by + * default are updated. + * + * @param Mixed nodeList jQuery object, or array of elements + */ + 'updateTooltipAccessKeys' : function (nodeList) { + var $nodes; + if (nodeList instanceof jQuery) { + $nodes = nodeList; + } else if (nodeList) { + $nodes = $(nodeList); + } else { + // Rather than scanning all links, just + $("#column-one a, #mw-head a, #mw-panel a, #p-logo a"); + + // these are rare enough that no such optimization is needed + this.updateTooltipAccessKeys($('input')); + this.updateTooltipAccessKeys($('label')); + return; + } + + $nodes.each(function (i) { + var tip = $(this).attr('title'); + if (!!tip && mw.util.tooltipAccessKeyRegexp.exec(tip)) { + tip = tip.replace(mw.util.tooltipAccessKeyRegexp, '[' + tooltipAccessKeyPrefix + "$5]"); + $(this).attr('title', tip); + } + }); + }, + + + /** + * Add a link to a portlet menu on the page, such as: + * + * p-cactions (Content actions), p-personal (Personal tools), p-navigation (Navigation), p-tb (Toolbox) + * + * The first three paramters are required, others are optionals. Though + * providing an id and tooltip is recommended. + * + * By default the new link will be added to the end of the list. To add the link before a given existing item, + * pass the DOM node (document.getElementById('foobar') or the jQuery-selector ('#foobar') of that item. + * + * @example mw.util.addPortletLink('p-tb', 'http://mediawiki.org/', 'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org ', 'm', '#t-print') + * + * @param String portlet id of the target portlet ("p-cactions" or "p-personal" etc.) + * @param String href link URL + * @param String text link text (will be automatically lowercased by CSS for p-cactions in Monobook) + * @param String id id of the new item, should be unique and preferably have the appropriate prefix ("ca-", "pt-", "n-" or "t-") + * @param String tooltip text to show when hovering over the link, without accesskey suffix + * @param String accesskey accesskey to activate this link (one character, try to avoid conflicts) + * @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 + * + * @return Node the DOM node of the new item (a LI element) or null + */ + 'addPortletLink' : function (portlet, href, text, id, tooltip, accesskey, nextnode) { + var $portlet = $('#' + portlet); + if ($portlet.length === 0) { + return null; + } + var $ul = $portlet.find('ul').eq(0); + if ($ul.length === 0) { + if ($portlet.find('div').length === 0) { + $portlet.append('