MediaWiki:LAPI.js: Difference between revisions

Content deleted Content added
mNo edit summary
per tper
 
(3 intermediate revisions by 3 users not shown)
Line 1:
// <source lang=javascript">
 
/*
Small JS library containing stuff I use often.
Line 39 ⟶ 37:
// Note: adding these to the prototype may break other code that assumes that
// {} has no properties at all.
if (!Object.clone) {
Object.clone = function (source, includeInherited)
{
if (!source) return null;
var result = {};
for (var key in source) {
if (includeInherited || source.hasOwnProperty (key)) result[key] = source[key];
}
return result;
};
}
 
if (!Object.merge) {
Object.merge = function (from, into, includeInherited)
{
if (!from) return into;
for (var key in from) {
if (includeInherited || from.hasOwnProperty (key)) into[key] = from[key];
}
return into;
};
}
 
if (!Object.mergeSome) {
Object.mergeSome = function (from, into, includeInherited, predicate)
{
if (!from) return into;
if (typeof (predicate) == 'undefined')
return Object.merge (from, into, includeInherited);
for (var key in from) {
if ((includeInherited || from.hasOwnProperty (key)) && predicate (from, into, key))
into[key] = from[key];
}
return into;
};
 
Object.mergeSet = function (from, into, includeInherited)
{
return Object.mergeSome
(from, into, includeInherited, function (src, tgt, key) {return src[key] != null;});
}
 
if (!Object.mergeSet) {
Object.mergeSet = function (from, into, includeInherited)
{
return Object.mergeSome
(from, into, includeInherited, function (src, tgt, key) {return src[key] !== null;});
};
}
/** String enhancements (Javascript 1.6) ************/
 
Line 95 ⟶ 100:
};
}
if (!String.prototype.trimFront)
String.prototype.trimFront = String.prototype.trimLeft; // Synonym
 
// Removes given characters from the end of the string.
Line 105 ⟶ 111:
};
}
if (!String.prototype.trimEnd)
String.prototype.trimEnd = String.prototype.trimRight; // Synonym
 
/** Further String enhancements ************/
 
// Returns true if the string begins with prefix.
if (!String.prototype.startsWith = function (prefix) {
return thisString.indexOfprototype.startsWith = function (prefix) == 0;{
return this.indexOf (prefix) === 0;
};
};
}
 
// Returns true if the string ends in suffix
if (!String.prototype.endsWith = function (suffix) {
String.prototype.endsWith = function (suffix) {
return this.lastIndexOf (suffix) + suffix.length == this.length;
var last = this.lastIndexOf (suffix);
};
 
return last !== -1 && last + suffix.length == this.length;
};
}
 
// Returns true if the string contains s.
if (!String.prototype.contains = function (s) {
String.prototype.contains = function (s) {
return this.indexOf (s) >= 0;
return this.indexOf (s) >= 0;
};
};
}
 
// Replace all occurrences of a string pattern by replacement.
if (!String.prototype.replaceAll) {
String.prototype.replaceAll = function (pattern, replacement) {
return this.split (pattern).join (replacement);
};
}
 
// Escape all backslashes and single or double quotes such that the result can
// be used in Javascript inside quotes or double quotes.
if (!String.prototype.stringifyJS = function () {
String.prototype.stringifyJS = function () {
return this.replace (/([\\\'\"]|%5C|%27|%22)/g, '\\$1') // ' // Fix syntax coloring
return this.replace (/([\n\\'\"]|%5C|%27|%22)/g, '\\n$1'); // ' // Fix syntax coloring
.replace (/\n/g, '\\n');
};
}
 
// Escape all RegExp special characters such that the result can be safely used
// in a RegExp as a literal.
if (!String.prototype.escapeRE = function () {
String.prototype.escapeRE = function () {
return this.replace (/([\\{}()|.?*+^$\[\]])/g, "\\$1");
return this.replace (/([\\{}()|.?*+^$\[\]])/g, "\\$1");
};
};
}
 
if (!String.prototype.escapeXML = function (quot, apos) {
String.prototype.escapeXML = function (quot, apos) {
var s = this.replace (/&/g, '&amp;')
var s = this.replace (/\xa0&/g, '&nbspamp;')
.replace (/<\xa0/g, '&ltnbsp;')
.replace (/></g, '&gtlt;');
.replace (/>/g, '&gt;');
if (quot) s = s.replace (/\"/g, '&quot;'); // " // Fix syntax coloring
if (apos) s = s.replace (/\'/g, '&apos;'); // ' // Fix syntax coloring
return s;
};
}
 
if (!String.prototype.decodeXML = function () {
String.prototype.decodeXML = function () {
return this.replace(/&quot;/g, '"')
return this.replace(/&aposquot;/g, '"'")
.replace(/&gtapos;/g, '>"'")
.replace(/&ltgt;/g, '<>')
.replace(/&nbsplt;/g, '\xa0<')
.replace(/&ampnbsp;/g, '&\xa0');
.replace(/&amp;/g, '&');
};
};
}
 
if (!String.prototype.capitalizeFirst = function () {
String.prototype.capitalizeFirst = function () {
return this.substring (0, 1).toUpperCase() + this.substring (1);
return this.substring (0, 1).toUpperCase() + this.substring (1);
};
};
}
 
if (!String.prototype.lowercaseFirst = function () {
String.prototype.lowercaseFirst = function () {
return this.substring (0, 1).toLowerCase() + this.substring (1);
return this.substring (0, 1).toLowerCase() + this.substring (1);
};
};
}
 
// This is actually a function on URLs, but since URLs typically are strings in
// Javascript, let's include this one here, too.
if (!String.prototype.getParamValue = function (param) {
String.prototype.getParamValue = function (param) {
var re = new RegExp ('[&?]' + param.escapeRE () + '=([^&#]*)');
var re = new RegExp ('[&?]' + param.escapeRE () + '=([^&#]*)');
var m = re.exec (this);
var m = re.exec (this);
if (m && m.length >= 2) return decodeURIComponent (m[1]);
return null;
};
 
String.getParamValue = function (param, url)
{
if (typeof (url) == 'undefined' || url === null) url = document.___location.href;
try {
return url.getParamValue (param);
} catch (e) {
return null;
};
};
 
if (!String.getParamValue) {
String.getParamValue = function (param, url)
{
if (typeof (url) == 'undefined' || url === null) url = document.___location.href;
try {
return url.getParamValue (param);
} catch (e) {
return null;
}
};
}
 
/** Function enhancements ************/
 
if (!Function.prototype.bind) {
// Return a function that calls the function with 'this' bound to 'thisObject'
// Return a function that calls the function with 'this' bound to 'thisObject'
if (!Function.prototype.bind) { // JS 1.8.5 has bind()
Function.prototype.bind = function (thisObject) {
var f = this, obj = thisObject, slice = Array.prototype.slice, prefixedArgs = slice.call (arguments, 1);
return function () { return f.apply (obj, prefixedArgs.concat (slice.call (arguments))); };
};
}
Line 224 ⟶ 257:
};
}
if (!Array.select)
Array.select = Array.filter; // Synonym
 
// Calls iterator on all elements of the array
Line 261 ⟶ 295:
};
}
if (!Array.forAll)
Array.forAll = Array.every; // Synonym
 
// Returns true if predicate is true for at least one element of the array, false otherwise.
Line 279 ⟶ 314:
};
}
if (!Array.exists)
Array.exists = Array.some; // Synonym
 
// Returns a new array built by applying mapper to all elements.
Line 338 ⟶ 374:
/** Additional Array enhancements ************/
 
if (!Array.remove) {
Array.remove = function (target, elem) {
var i = Array.indexOf (target, elem);
if (i >= 0) target.splice (i, 1);
};
}
 
if (!Array.contains) {
Array.contains = function (target, elem) {
return Array.indexOf (target, elem) >= 0;
};
}
 
if (!Array.flatten = function (target) {
Array.flatten = function (target) {
var result = [];
var result = [];
Array.forEach (target, function (elem) {result = result.concat (elem);});
return result;
};
}
 
// Calls selector on the array elements until it returns a non-null object
// and then returns that object. If selector always returns null, any also
// returns null. See also Array.map.
if (!Array.any) {
Array.any = function (target, selector, thisObject)
{
if (target === null) return null;
if (typeof (selector) != 'function')
throw new Error ('Array.any: selector must be a function');
var l = target.length;
var result = null;
if (thisObject) selector = selector.bind (thisObject);
for (var i=0; l && i < l; i++) {
if (i in target) {
result = selector (target[i], i, target);
if (result != null) return result;
}
}
return null;
}
return null};
};
 
// Return a contiguous array of the contents of source, which may be an array or pseudo-array,
// basically anything that has a length and can be indexed. (E.g. live HTMLCollections, but also
// Strings, or objects, or the arguments "variable".
if (!Array.make) = function (source){
Array.make = function (source)
{
{
if (!source || typeof (source.length) == 'undefined') return null;
if (!source || typeof (source.length) == 'undefined') return null;
var result = [];
var l var result = source.length[];
for ( var i=0;l i < l; i++) { = source.length;
for (var i=0; i < l; i++) {
if (i in source) result[result.length] = source[i];
}
return result;
};
}
 
if (typeof (window.LAPI) == 'undefined') {
Line 468 ⟶ 514:
if (name || msg) {
if (!asDOM) {
return (
'Exception ' + name + ': ' + msg
+ (file ? '\nFile ' + file + (line ? ' (' + line + ')' : "") : "")
);
} else {
var ex_msg = LAPI.make ('div');
Line 873 ⟶ 919:
{ // Gecko etc.
if (property == 'cssFloat') property = 'float';
return element.ownerDocument.defaultView.getComputedStyle (element, null).getPropertyValue (property);
return
element.ownerDocument.defaultView.getComputedStyle (element, null).getPropertyValue (property);
} else {
var result;
Line 2,066 ⟶ 2,111:
 
} // end if (guard)
 
// </source>