10 'initialised' : false,
11 'init' : function () {
12 if (this.initialised === false) {
13 this.initialised = true;
15 // Set tooltipAccessKeyPrefix
17 this.tooltipAccessKeyPrefix = 'shift-esc-';
18 } else if (is_chrome) {
19 this.tooltipAccessKeyPrefix = is_chrome_mac ? 'ctrl-option-' : 'alt-';
20 } else if (!is_safari_win && is_safari && webkit_version > 526) {
21 this.tooltipAccessKeyPrefix = 'ctrl-alt-';
22 } else if (!is_safari_win &&
23 (is_safari || clientPC.indexOf('mac') !== -1 || clientPC.indexOf('konqueror') !== -1)) {
24 this.tooltipAccessKeyPrefix = 'ctrl-';
26 this.tooltipAccessKeyPrefix = 'alt-shift-';
29 // Setup CheckboxShiftClick
30 $.fn.enableCheckboxShiftClick = function () {
31 var prevCheckbox = null;
33 $box.click(function (e) {
34 if (prevCheckbox !== null && e.shiftKey) {
36 Math.min($box.index(prevCheckbox), $box.index(e.target)),
37 Math.max($box.index(prevCheckbox), $box.index(e.target)) + 1
38 ).attr({checked: e.target.checked ? 'checked' : ''});
40 prevCheckbox = e.target;
45 // Prototype enhancements
46 if (typeof String.prototype.ucFirst === 'undefined') {
47 String.prototype.ucFirst = function () {
48 return this.substr(0, 1).toUpperCase() + this.substr(1, this.length);
52 // Any initialisation after the DOM is ready
55 // Enable CheckboxShiftClick
56 $('input[type=checkbox]:not(.noshiftselect)').enableCheckboxShiftClick();
58 // Fill bodyContant var
59 if ($('#bodyContent').length) {
60 mw.util.$content = $('#bodyContent');
61 } else if ($('#article').length) {
62 mw.util.$content = $('#article');
64 mw.util.$content = $('#content');
77 * Encodes the string like PHP's rawurlencode
79 * @param String str string to be encoded
81 'rawurlencode' : function (str) {
82 str = (str + '').toString();
83 return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28')
84 .replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/~/g, '%7E');
88 * Encode pagetitles for use in a URL
89 * We want / and : to be included as literal characters in our title URLs
90 * as they otherwise fatally break the title
92 * @param String str string to be encoded
94 'wikiUrlencode' : function (str) {
95 return this.rawurlencode(str).replace(/%20/g, '_').replace(/%3A/g, ':').replace(/%2F/g, '/');
99 * Get the full url to a pagename
101 * @param String str pagename to link to
103 'getWikilink' : function (str) {
104 return wgServer + wgArticlePath.replace('$1', this.wikiUrlencode(str));
108 * Check is a variable is empty. Support for strings, booleans, arrays and objects.
109 * String "0" is considered empty. String containing only whitespace (ie. " ") is considered not empty.
111 * @param Mixed v the variable to check for empty ness
113 'isEmpty' : function (v) {
115 if (v === "" || v === 0 || v === "0" || v === null || v === false || typeof v === 'undefined') {
118 if (v.length === 0) {
121 if (typeof v === 'object') {
132 * Grabs the url parameter value for the given parameter
133 * Returns null if not found
135 * @param String param paramter name
136 * @param String url url to search through (optional)
138 'getParamValue' : function (param, url) {
139 url = url ? url : document.location.href;
140 var re = new RegExp('[^#]*[&?]' + param + '=([^&#]*)'); // Get last match, stop at hash
141 var m = re.exec(url);
142 if (m && m.length > 1) {
143 return decodeURIComponent(m[1]);
149 * Converts special characters to their HTML entities
151 * @param String str text to escape
152 * @param Bool quotes if true escapes single and double quotes aswell (by default false)
154 'htmlEscape' : function (str, quotes) {
155 str = $('<div/>').text(str).html();
156 if (typeof quotes === 'undefined') {
159 if (quotes === true) {
160 str = str.replace(/'/g, ''').replace(/"/g, '"');
166 * Converts HTML entities back to text
168 * @param String str text to unescape
170 'htmlUnescape' : function (str) {
171 return $('<div/>').html(str).text();
175 // will be re-defined based on browser/operating system detection in mw.util.init()
176 'tooltipAccessKeyPrefix' : 'alt-',
178 // Regex to match accesskey tooltips
179 'tooltipAccessKeyRegexp': /\[(ctrl-)?(alt-)?(shift-)?(esc-)?(.)\]$/,
182 * Add the appropriate prefix to the accesskey shown in the tooltip.
183 * If the nodeList parameter is given, only those nodes are updated;
184 * otherwise, all the nodes that will probably have accesskeys by
185 * default are updated.
187 * @param Mixed nodeList jQuery object, or array of elements
189 'updateTooltipAccessKeys' : function (nodeList) {
191 if (nodeList instanceof jQuery) {
193 } else if (nodeList) {
194 $nodes = $(nodeList);
196 // Rather than scanning all links, just
197 $('#column-one a, #mw-head a, #mw-panel a, #p-logo a');
199 // these are rare enough that no such optimization is needed
200 this.updateTooltipAccessKeys($('input'));
201 this.updateTooltipAccessKeys($('label'));
205 $nodes.each(function (i) {
206 var tip = $(this).attr('title');
207 if (!!tip && mw.util.tooltipAccessKeyRegexp.exec(tip)) {
208 tip = tip.replace(mw.util.tooltipAccessKeyRegexp, '[' + mw.util.tooltipAccessKeyPrefix + "$5]");
209 $(this).attr('title', tip);
214 // jQuery object that refers to the page-content element
215 // Populated by init()
220 * Add a link to a portlet menu on the page, such as:
222 * p-cactions (Content actions), p-personal (Personal tools), p-navigation (Navigation), p-tb (Toolbox)
224 * The first three paramters are required, others are optionals. Though
225 * providing an id and tooltip is recommended.
227 * By default the new link will be added to the end of the list. To add the link before a given existing item,
228 * pass the DOM node (document.getElementById('foobar') or the jQuery-selector ('#foobar') of that item.
230 * @example mw.util.addPortletLink('p-tb', 'http://mediawiki.org/', 'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org ', 'm', '#t-print')
232 * @param String portlet id of the target portlet ('p-cactions' or 'p-personal' etc.)
233 * @param String href link URL
234 * @param String text link text (will be automatically lowercased by CSS for p-cactions in Monobook)
235 * @param String id id of the new item, should be unique and preferably have the appropriate prefix ('ca-', 'pt-', 'n-' or 't-')
236 * @param String tooltip text to show when hovering over the link, without accesskey suffix
237 * @param String accesskey accesskey to activate this link (one character, try to avoid conflicts. Use $('[accesskey=x').get() in the console to see if 'x' is already used.
238 * @param mixed nextnode DOM node or jQuery-selector of the item that the new item should be added before, should be another item in the same list will be ignored if not the so
240 * @return Node the DOM node of the new item (a LI element, or A element for older skins) or null
242 'addPortletLink' : function (portlet, href, text, id, tooltip, accesskey, nextnode) {
243 var $link = $('<a />').attr('href', href).text(text);
245 // Some skins don't have portlets
246 // Just add it to the bottom of their 'sidebar' element ignoring the specified portlet target
250 $("#quickbar").append($link.after('<br />'));
253 $("#searchform").before($link).before(' | ');
255 default : // chick, modern, monobook, myskin, simple, vector...
257 var $portlet = $('#' + portlet);
258 if ($portlet.length === 0) {
261 var $ul = $portlet.find('ul').eq(0);
262 if ($ul.length === 0) {
263 if ($portlet.find('div').length === 0) {
264 $portlet.append('<ul />');
266 $portlet.find('div').eq(-1).append('<ul />');
268 $ul = $portlet.find('ul').eq(0);
270 if ($ul.length === 0) {
274 // unhide portlet if it was hidden before
275 $portlet.removeClass('emptyPortlet');
277 var $item = $link.wrap('<li><span /></li>').parent().parent();
280 $item.attr('id', id);
283 $link.attr('accesskey', accesskey);
284 tooltip += ' [' + accesskey + ']';
287 $link.attr('title', tooltip);
289 if (accesskey && tooltip) {
290 this.updateTooltipAccessKeys($link);
293 // Append using DOM-element passing
294 if (nextnode && nextnode.parentNode == $ul.get(0)) {
295 $(nextnode).before($item);
297 // If the jQuery selector isn't found within the <ul>, just append it at the end
298 if ($ul.find(nextnode).length === 0) {
301 // Append using jQuery CSS selector
302 $ul.find(nextnode).eq(0).before($item);
312 mediaWiki.util.init();
314 })(jQuery, mediaWiki);