adding begin of mediaWiki.util and loading it by default + trailing whitespace cleanu...
authorKrinkle <krinkle@users.mediawiki.org>
Sat, 23 Oct 2010 17:24:07 +0000 (17:24 +0000)
committerKrinkle <krinkle@users.mediawiki.org>
Sat, 23 Oct 2010 17:24:07 +0000 (17:24 +0000)
includes/OutputPage.php
resources/Resources.php
resources/mediawiki/mediawiki.js
resources/mediawiki/mediawiki.util.js [new file with mode: 0644]

index 2a6030d..1baf8e2 100644 (file)
@@ -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 ) {
index f213061..ba15dd3 100644 (file)
@@ -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 */
        
index 0eef7d7..3350bb2 100644 (file)
@@ -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 (file)
index 0000000..45655e3
--- /dev/null
@@ -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 = $('<div/>').text(str).html();
+                       if (typeof quotes === 'undefined') {
+                               quotes = false;
+                       }
+                       if (quotes === true) {
+                               str = str.replace(/'/g, '&#039;').replace(/"/g, '&quot;');
+                       }
+                       return str;
+               },
+
+               /**
+               * Converts HTML entities back to text
+               *
+               * @param String str             text to unescape
+               */
+               'htmlUnescape' : function (str) {
+                       return $('<div/>').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('<ul />');
+                               } else {
+                                       $portlet.find('div').eq(-1).append('<ul />');
+                               }
+                               $ul = $portlet.find('ul').eq(0);
+                       }
+                       if ($ul.length === 0) {
+                               return null;
+                       }
+
+                       // unhide portlet if it was hidden before
+                       $portlet.removeClass('emptyPortlet');
+
+                       var $link = $('<a />').attr('href', href).text(text);
+                       var $item = $link.wrap('<li><span /></li>').parent().parent();
+
+                       if (id) {
+                               $item.attr('id', id);
+                       }
+                       if (accesskey) {
+                               $link.attr('accesskey', accesskey);
+                               tooltip += ' [' + accesskey + ']';
+                       }
+                       if (tooltip) {
+                               $link.attr('title', tooltip);
+                       }
+                       if (accesskey && tooltip) {
+                               this.updateTooltipAccessKeys($link);
+                       }
+
+                       // Append using DOM-element passing
+                       if (nextnode && nextnode.parentNode == $ul.get(0)) {
+                               $(nextnode).before($item);
+                       } else {
+                               // If the jQuery selector isn't found within the <ul>, just append it at the end
+                               if ($ul.find(nextnode).length === 0) {
+                                       $ul.append($item);
+                               } else {
+                                       // Append using jQuery CSS selector
+                                       $ul.find(nextnode).eq(0).before($item);
+                               }
+                       }
+
+                       return $item.get(0);
+               }
+
+       };
+
+})(jQuery, mediaWiki);
+
+mediaWiki.util.init();
\ No newline at end of file