MediaWiki:Utilities.js
Jump to navigation
Jump to search
Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
Documentation for this user script can be added at MediaWiki:Utilities. |
- Report page listing warnings and errors.
// <source lang="javascript">
/*
Utilities - various utility functions
Author: [[User:Lupo]], October 2007 - February 2009
License: Quadruple licensed GFDL, GPL, LGPL and Creative Commons Attribution 3.0 (CC-BY-3.0)
Usage note: script loading through importScript is asynchronous. Therefore, use these
functions only in code that runs once you can be certain that loading this script has
finished. That means: code executed through an addOnloadHandler or even later through
some user interaction (link or button clicked), but not in global inline JS. Doing
importScript ('MediaWiki:Utilities.js');
if (userIsInGroup ('sysop')) {
// Something
}
won't work because at the "if"-statement, this script here has not finished loading yet
and function "userIsInGroup" isn't defined yet. However,
importScript ('MediaWiki:Utilities.js');
function myStuff () {
if (userIsInGroup ('sysop')) {
// Something
}
}
addOnloadHandler (myStuff);
should work.
*/
// makeRawLink
// Creates a link with given url, display name, and target frame name. Equivalent to
// <a href="url" target="target">name</a> in XHTML.
//
// Parameters:
// name String Display text for the link to be created
// url String URL for the HREF of the link
// target optional String If set, defines the target attribute of the link
// tooltip optional String If set, defines the title attribute of the link
function makeRawLink (name, url, target, tooltip)
{
var link = document.createElement('a');
link.href = url;
if (target) link.target = target;
if (tooltip) link.title = tooltip;
link.appendChild(document.createTextNode(name));
return link;
}
// makeWikiLink
// Create a simple link to a wiki page
//
// Parameters:
// name String Display text for the link to be created
// url String Wiki-name of the page to link
function makeWikiLink (name, url, target, tooltip)
{
return makeRawLink (name, mw.config.get('wgArticlePath').replace ('$1', url), target, tooltip);
}
// makeActiveLink
// Create a link that executes some Javascript when clicked
//
// Parameters:
// name String Display text for the link to be created
// script String The Javascript code to be executed
function makeActiveLink (name, script, tooltip)
{
var link = makeRawLink (name, 'javascript:' + script, null, tooltip);
return link;
}
// makeTab
// Create and add a new tab to a page.
//
// Parameters:
// lk DOM element Link for the tab (for instance, obtained using makeRawLink)
// id optional String Optional id for the new tab
function makeTab (lk, id)
{
var li = document.createElement('li');
if (id) li.id = id;
li.appendChild(lk);
var ul = document.getElementById ('p-cactions')
.getElementsByTagName ('div')[0]
.getElementsByTagName ('ul')[0];
ul.appendChild (li);
}
// setEditSummary
// If called on a page containing an editform, set the edit summary to "text"
//
// Parameters:
// text String The edit summary text
function setEditSummary (text)
{
if (document.editform == null || document.editform.wpSummary == null) return;
var summary = document.editform.wpSummary.value;
if (summary == null || summary.length == 0)
document.editform.wpSummary.value = text;
else {
if (/\*\/\s*$/.test (summary)) {
document.editform.wpSummary.value = document.editform.wpSummary.value + text;
} else {
document.editform.wpSummary.value = document.editform.wpSummary.value + " & "
+ new String (text.charAt (0)).toLowerCase ()
+ text.substring (1);
}
}
}
// userIsInGroup
// Returns true if the current user is in the given user group. The function checks
// 'wgUserGroup' to determine this.
//
// Parameters:
// group optional String The user group to test for. If null or an empty string, defaults
// to '*'.
function userIsInGroup (group)
{
var userGroups = mw.config.get('wgUserGroups');
if (userGroups) {
if (!group || group.length == 0) group = '*';
return userGroups.join (' ').indexOf (group) >= 0;
}
return false;
}
// Same for global groups
function userIsInGlobalGroup (group)
{
var globalGroups = mw.config.get('wgGlobalGroups');
if (globalGroups) {
if (!group || group.length == 0) group = '*';
return globalGroups.join (' ').indexOf (group) >= 0;
}
return false;
}
// replaceVars
// Replace all occurrences of a "variable reference" in a string by a given argument and return
// a new string with the replacements made. A variable reference is a string of the form
// "<indicator><selector>": if indicator = '$' and selectors = '123', valid variable references
// are "$1", "$2", and "$3". References for which there is no replacement are not replaced.
//
// If a replacement is a function, that function is called with three parameters, and its return
// value is used as the replacement. The parameters are the original string, the selector that
// matched, and the position of the matching reference's indicator within the original string.
//
// Parameters:
// str String String containing variable references to be replaced
// indicator Character The indicator character for variable references
// selectors String The set of valid selectors
// 0..n Object The replacements
//
// Example: replaceVars ('Hello $1 $X $2 $3 $', '$', '123', 'yo$2u', 'there') results in the string
// "Hello yo$2u $X there $3 3". $3 is not replaced because there is no replacement for it, and the
// trailing $ is not a valid variable reference. Neither is $X (unrecognized selector). Note that
// the "$2" in the *replacement* "yo$2u" is *not* replaced! If you had done that naively with
// str.replace (/\$1/g, 'yo\$2u').replace(/\$2/g, 'there'), you would have gotten the result
// "Hello yothereu $X there $3 $".
function replaceVars (str, indicator, selectors /*, ... */)
{
var result = "";
if (!str || str.length == 0) return result;
var from = 0;
while (from < str.length) {
var i = str.indexOf (indicator, from);
if (i < 0 || i+1 >= str.length) {
// No indicator found, or found at the last character of str: no selector following
result = result + str.substring (from);
break;
}
var j = selectors.indexOf (str.charAt (i+1));
if (j < 0) {
// Unknown selector: not replaced
result = result + str.substring (from, i+1);
from = i+1;
} else {
if (j >= arguments.length - 3) {
// No replacement for known selector
result = result + str.substring (from, i+2);
} else {
result = result
+ str.substring (from, i)
+ (typeof (arguments[j+3]) == 'function'
? arguments[j+3] (str, str.charAt (i+1), i)
: arguments[j+3])
;
}
from = i+2;
}
}
return result;
}
// stringifyJS
// Turn a string into a valid Javascript string: escape all \, ', and " within the string by
// another \ and return the resulting string.
//
// Parameters
// str String The string to JSify
function stringifyJS (str)
{
return str.replace (/([\\'"]|%5C|%27|%22)/g, '\\$1');
}
// scrollTextArea
// Scroll a textarea to the top or to the bottom. Note: doesn't work in Opera < 9.5, because
// such Opera versions *have no way of programatically setting the scroll position of a
// textarea*. As of V9.5, Opera implements the textarea.scrollTop properly. (Also note that
// scrollTop is a non-standard DHTML thing invented by Microsoft, but implemented by other
// major browsers, too.)
// A possibly existing selection is cleared.
//
// Parameters
// textarea String the textarea to scroll. Defaults to 'wpTextbox1' if not
// set or null.
// to_top boolean true to scroll to the top, false to scroll to the bottom.
// no_focus optional boolean if true, doesn't set the focus on the textarea (which may
// or may not make it not work on some browsers). Default is
// false (i.e., *do* set the focus.)
function scrollTextArea (textarea, to_top, no_focus)
{
if (!textarea) textarea = document.getElementById ('wpTextbox1');
if (!textarea) return;
// Give the textbox the focus unless explicitly suppressed
if (!no_focus) textarea.focus();
// For good measure try to set the caret
var offset = 0;
if (!to_top) offset = textarea.value.length;
if (textarea.createTextRange) { // IE, Opera
var rng = textarea.createTextRange ();
rng.collapse (true);
rng.moveEnd ('character', offset);
rng.moveStart ('character', offset);
rng.select ();
} else { // Other browsers
if (textarea.setSelectionRange) {
textarea.setSelectionRange (offset, offset);
} else if (typeof (textarea.selectionStart) != 'undefined') {
textarea.selectionStart = offset;
textarea.selectionEnd = offset;
}
}
if (typeof (textarea.scrollTop) != 'undefined') { // Also on Opera as of 9.5
if (to_top)
textarea.scrollTop = 0;
else {
var h = textarea.scrollHeight - textarea.clientHeight;
textarea.scrollTop = (h < 0 ? 0 : h);
}
}
}
// titleFromHref
// Extract a page title from a href. Works for both types of hrefs:
// http://foo.wikipedia.org/w/index.php?title=PageName and also /wiki/PageName
// The returned title is already decoded, and any blanks are replaced by '_'.
// Returns the empty string if no title can be found.
//
// Parameters
// href String The href from which to extract the page name
function titleFromHref (href)
{
if (!href) return "";
var match = /[&?]title=([^&]*)/.exec (href);
if (match && match.length > 1)
return decodeURIComponent (match[1]).replace (/ /g, '_');
var prefix = mw.config.get('wgArticlePath').replace ('$1', "");
if (href.indexOf (prefix) != 0) prefix = mw.config.get('wgServer') + prefix; // Fully expanded URL?
if (href.indexOf (prefix) != 0 && prefix.indexOf ('//') == 0) prefix = document.location.protocol + prefix; // Protocol-relative wgServer?
if (href.indexOf (prefix) == 0)
return decodeURIComponent (href.substring (prefix.length)).replace (/ /g, '_');
// Yes, use decodeURIComponent, not decodeURI. DecodeURIComponent also will replace "%26" by "&",
// which decodeURI doesn't do.
return "";
}
// titleFromLink
// Extract a page title from a href of a link node. Works for both types of hrefs:
// http://foo.wikipedia.org/w/index.php?title=PageName and also /wiki/PageName
//
// Parameters
// node DOM node The link node from which the page name is to be extracted
function titleFromLink (node)
{
if (!node || typeof (node.getAttribute) != 'function') return "";
return titleFromHref (node.getAttribute ('href', 2));
// The ", 2" is for IE. IE sometimes has problems with encoded UTF-8 characters: using any other
// way to get the href, it insists to decode the value, but does do so wrongly. For more info,
// see commons.wikimedia.org/wiki/MediaWiki_talk:Gadget-HotCat.js/Archive01#Questions
}
// </source>