308 lines
10 KiB
JavaScript
308 lines
10 KiB
JavaScript
/**
|
|
* $Id: string.js 370 2007-11-25 01:39:30Z wingedfox $
|
|
* $HeadURL: https://svn.debugger.ru/repos/jslibs/BrowserExtensions/tags/BrowserExtensions.018/ext/string.js $
|
|
*
|
|
* @author Ildar Shaimordanov
|
|
* @author Ilya Lebedev
|
|
* @license LGPL
|
|
* @version $Rev: 370 $
|
|
*/
|
|
|
|
/**
|
|
* Decodes html entities
|
|
*
|
|
* @return {String} string with decoded entities
|
|
* @scope public
|
|
*/
|
|
String.prototype.entityDecode = function() {
|
|
if (!arguments.callee.span) arguments.callee.span = document.createElement('span');
|
|
var s = arguments.callee.span;
|
|
s.innerHTML = this;
|
|
return s.firstChild?s.firstChild.nodeValue:"";
|
|
}
|
|
|
|
/**
|
|
* Method is used to trim specified chars from the left of the string
|
|
*
|
|
* @param {String, Array} c char or char list to be trimmed, default is \s
|
|
* @return {String}
|
|
* @scope public
|
|
*/
|
|
String.prototype.ltrim = function(c) {
|
|
if (isString(c)) c=c.split("");
|
|
if (isArray(c) || isUndefined(c)) {
|
|
c = isEmpty(c)?"\\s":RegExp.escape(c);
|
|
c = new RegExp("^(?:"+c+")+", "g");
|
|
return this.replace(c, "");
|
|
}
|
|
return this;
|
|
}
|
|
/**
|
|
* Method is used to trim specified list from the right of the string
|
|
*
|
|
* @param {String, Array} c char or char sequence to be trimmed, default is \s
|
|
* @return {String}
|
|
* @scope public
|
|
*/
|
|
String.prototype.rtrim = function(c) {
|
|
if (isString(c)) c=c.split("");
|
|
if (isArray(c) || isUndefined(c)) {
|
|
c = isEmpty(c)?"\\s":RegExp.escape(c);
|
|
c = new RegExp("(?:"+c+")+$", "g");
|
|
return this.replace(c, "");
|
|
}
|
|
return this;
|
|
}
|
|
/**
|
|
* Method is used to trim specified chars from the left and the right of the string
|
|
*
|
|
* @param {String, Array} c char or char list to be trimmed, default is \s
|
|
* @return {String}
|
|
* @scope public
|
|
*/
|
|
String.prototype.trim = function(c) {
|
|
if (isString(c)) c=c.split("");
|
|
if (isArray(c) || isUndefined(c)) {
|
|
c = isEmpty(c)?"\\s":RegExp.escape(c);
|
|
c = new RegExp("^(?:"+c+")+|(?:"+c+")+$", "g");
|
|
return this.replace(c, "");
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Duplicates the string
|
|
*
|
|
* @return {String}
|
|
* @scope public
|
|
*/
|
|
String.prototype.dup = function() {
|
|
var val = this.valueOf();
|
|
return [val,val].join("");
|
|
}
|
|
/**
|
|
* Repeats string specified number of times
|
|
*
|
|
* @param {Number} n number of times to repeat the string
|
|
* @return {String}
|
|
* @scope public
|
|
*/
|
|
String.prototype.repeat = function(n /* :Number */) /* :String */ {
|
|
if (isNaN(n=parseInt(n)) || n<0) return "";
|
|
return Array(n+1).join(this.valueOf());
|
|
}
|
|
/**
|
|
* Pads the string to the specified length
|
|
*
|
|
* @param {Number} n number of times to repeat c
|
|
* positive - on the right side
|
|
* negative - on the left side
|
|
* @param {String} c fill char, space is default
|
|
* @return {String}
|
|
* @scope public
|
|
*/
|
|
String.prototype.padding = function(n, c) {
|
|
var val = this.valueOf();
|
|
n = parseInt(n);
|
|
if (!n) return val;
|
|
if (isUndefined(c)) c = " ";
|
|
var pad = String(c).charAt(0).repeat(Math.abs(n) - this.length);
|
|
return (n < 0) ? pad + val : val + pad;
|
|
}
|
|
/**
|
|
* Pads the string on the right side
|
|
*
|
|
* @param {Number} n number of times to repeat c
|
|
* @param {String} c fill char
|
|
* @return {String}
|
|
* @scope public
|
|
*/
|
|
String.prototype.padLeft = function(n, c) {
|
|
return this.padding(-Math.abs(n), c);
|
|
}
|
|
/**
|
|
* Pads the string on the left side
|
|
*
|
|
* @param {Number} n number of times to repeat c
|
|
* @param {String} c fill char
|
|
* @return {String}
|
|
* @scope public
|
|
*/
|
|
String.prototype.padRight = function(n, c) {
|
|
return this.padding(Math.abs(n), c);
|
|
}
|
|
|
|
/**
|
|
* sprintf(format, argument_list)
|
|
*
|
|
* The string format function like the one in C/C++, PHP, Perl
|
|
* Each conversion specification is defined as below:
|
|
*
|
|
* %[index][alignment][padding][width][precision]type
|
|
*
|
|
* index An optional index specifier that changes the order of the
|
|
* arguments in the list to be displayed.
|
|
* alignment An optional alignment specifier that says if the result should be
|
|
* left-justified or right-justified. The default is
|
|
* right-justified; a "-" character here will make it left-justified.
|
|
* padding An optional padding specifier that says what character will be
|
|
* used for padding the results to the right string size. This may
|
|
* be a space character or a "0" (zero character). The default is to
|
|
* pad with spaces. An alternate padding character can be specified
|
|
* by prefixing it with a single quote ('). See the examples below.
|
|
* width An optional number, a width specifier that says how many
|
|
* characters (minimum) this conversion should result in.
|
|
* precision An optional precision specifier that says how many decimal digits
|
|
* should be displayed for floating-point numbers. This option has
|
|
* no effect for other types than float.
|
|
* type A type specifier that says what type the argument data should be
|
|
* treated as. Possible types:
|
|
*
|
|
* % - a literal percent character. No argument is required.
|
|
* b - the argument is treated as an integer, and presented as a binary number.
|
|
* c - the argument is treated as an integer, and presented as the character
|
|
* with that ASCII value.
|
|
* d - the argument is treated as an integer, and presented as a decimal number.
|
|
* u - the same as "d".
|
|
* f - the argument is treated as a float, and presented as a floating-point.
|
|
* o - the argument is treated as an integer, and presented as an octal number.
|
|
* s - the argument is treated as and presented as a string.
|
|
* x - the argument is treated as an integer and presented as a hexadecimal
|
|
* number (with lowercase letters).
|
|
* X - the argument is treated as an integer and presented as a hexadecimal
|
|
* number (with uppercase letters).
|
|
*
|
|
* @return {String}
|
|
* @scope public
|
|
*/
|
|
String.prototype.sprintf = function() {
|
|
var args = isArray(arguments[0])?arguments[0]:arguments
|
|
,index = 0
|
|
,frmt = this.replace(/%%/g, "\0\0")
|
|
,re = /%((?:\d+\$)?)((?:[-0+# ])?)((?:\d+|\*(?:\d+\$)?)?)((?:.(?:\d+|\*(?:\d+\$)?))?)([bcdeEfosuxX])/g;
|
|
/*
|
|
* The re.exec() method returns the array with the following properties
|
|
* wich are used in this function
|
|
* x.index contains the substring position found at the origin string
|
|
* x[0] contains the found substring
|
|
* x[1] contains the explicit parameter number
|
|
* x[2] contains the flags
|
|
* x[3] contains the minwidth
|
|
* x[4] contains the precision
|
|
* x[5] contains the type specifier (as [bcdfosuxX])
|
|
*/
|
|
frmt = frmt.replace(re, function() {
|
|
var x = arguments
|
|
,sign = false
|
|
,ins;
|
|
|
|
/*
|
|
* calculate min width
|
|
*/
|
|
if (!isUndefined(x[3]) && x[3].indexOf("*")==0) {
|
|
x[3] = parseInt(x[3].replace(/\D/g,""))
|
|
if (isNaN(x[3])) {
|
|
x[3] = args[index];
|
|
/*
|
|
* increment
|
|
*/
|
|
index++;
|
|
} else {
|
|
x[3] = args[x[3]]
|
|
}
|
|
}
|
|
/*
|
|
* calculate precision
|
|
*/
|
|
if ("" != x[4]) {
|
|
if (x[4].indexOf("*")==1) {
|
|
x[4] = parseInt(x[4].replace(/\D/g,""))
|
|
if (isNaN(x[4])) {
|
|
x[4] = args[index];
|
|
/*
|
|
* increment
|
|
*/
|
|
index++;
|
|
} else {
|
|
x[4] = args[x[4]]
|
|
}
|
|
} else {
|
|
x[4] = x[4].replace(/\D/,"")
|
|
}
|
|
x[4] = Math.abs(x[4]);
|
|
}
|
|
/*
|
|
* calculate insertion value
|
|
*/
|
|
x[1] = parseInt(x[1]);
|
|
var ins;
|
|
if (isNumeric(x[1])) {
|
|
ins = args[x[1]];
|
|
} else {
|
|
ins = args[index];
|
|
/*
|
|
* index should be incremented only when no explicit parameter number is specified
|
|
*/
|
|
index++;
|
|
}
|
|
switch (x[5]) {
|
|
case "b":
|
|
if (ins<0) ins = 0x10000000000000000+parseInt(ins);
|
|
ins = Number(ins).bin(x[4]);
|
|
if (x[4]) ins = ins.substr(0,x[4]);
|
|
if (x[2]=='#') ins = '0b'+ins;
|
|
break;
|
|
case "c":
|
|
ins = String.fromCharCode(ins);
|
|
break;
|
|
case "u":
|
|
ins = Math.abs(ins);
|
|
case "d":
|
|
ins = Math.round(ins);
|
|
if (ins<0) {
|
|
ins = "-"+Math.abs(ins).dec(x[4]);
|
|
} else {
|
|
ins = Number(ins).dec(x[4]);
|
|
sign = (x[2] == ' ' || x[2] == '+');
|
|
}
|
|
break;
|
|
case "e":
|
|
case "E":
|
|
if (ins>0) {
|
|
sign = (x[2] == ' ' || x[2] == '+');
|
|
}
|
|
ins = Number(ins).toExponential(x[4]?x[4]:6);
|
|
if (x[5]=='E') ins=ins.toUpperCase();
|
|
break;
|
|
case "f":
|
|
if (ins>0) {
|
|
sign = (x[2] == ' ' || x[2] == '+');
|
|
}
|
|
ins = Number(ins).toFixed(isNumeric(x[4])?x[4]:6);
|
|
break;
|
|
case "o":
|
|
if (ins<0) ins = 0x10000000000000000+parseInt(ins);
|
|
ins = Number(ins).toString(8);
|
|
if (x[4]) ins = ins.substr(0,x[4]);
|
|
if (x[2]=='#' && ins != 0) ins = '0'+ins;
|
|
break;
|
|
case "s":
|
|
ins = String(ins);
|
|
if (x[4]) ins = ins.substr(0,x[4]);
|
|
break;
|
|
case "x":
|
|
case "X":
|
|
if (ins<0) ins = 0x10000000000000000+parseInt(ins);
|
|
ins = Number(ins).hex(-x[4]);
|
|
if (x[4]) ins = ins.substr(0,x[4]);
|
|
if (x[2]=='#') ins = '0x'+ins;
|
|
if (x[5]=='X') ins = ins.toUpperCase();
|
|
break;
|
|
}
|
|
if (sign) ins = x[2]+ins;
|
|
if (x[3]) ins = (x[2]=='-' || x[3]<0)?ins.padRight(x[3]):ins.padLeft(x[3],x[2]=='0'?0:" ");
|
|
return ins;
|
|
})
|
|
return frmt.replace(/\0\0/g, "%");
|
|
}
|