function array_filter (arr, func) {
// http://kevin.vanzonneveld.net
// + original by: Brett Zamir (http://brett-zamir.me)
// + input by: max4ever
// + improved by: Brett Zamir (http://brett-zamir.me)
// % note 1: Takes a function as an argument, not a function's name
// * example 1: var odd = function (num) {return (num & 1);};
// * example 1: array_filter({"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}, odd);
// * returns 1: {"a": 1, "c": 3, "e": 5}
// * example 2: var even = function (num) {return (!(num & 1));}
// * example 2: array_filter([6, 7, 8, 9, 10, 11, 12], even);
// * returns 2: {0: 6, 2: 8, 4: 10, 6: 12}
// * example 3: var arr = array_filter({"a": 1, "b": false, "c": -1, "d": 0, "e": null, "f":'', "g":undefined});
// * returns 3: {"a":1, "c":-1};
var retObj = {},
k;
func = func || function (v) {return v;};
for (k in arr) {
if (func(arr[k])) {
retObj[k] = arr[k];
}
}
return retObj;
}
function array_intersect (arr1) {
// http://kevin.vanzonneveld.net
// + original by: Brett Zamir (http://brett-zamir.me)
// % note 1: These only output associative arrays (would need to be
// % note 1: all numeric and counting from zero to be numeric)
// * example 1: $array1 = {'a' : 'green', 0:'red', 1: 'blue'};
// * example 1: $array2 = {'b' : 'green', 0:'yellow', 1:'red'};
// * example 1: $array3 = ['green', 'red'];
// * example 1: $result = array_intersect($array1, $array2, $array3);
// * returns 1: {0: 'red', a: 'green'}
var retArr = {},
argl = arguments.length,
arglm1 = argl - 1,
k1 = '',
arr = {},
i = 0,
k = '';
arr1keys: for (k1 in arr1) {
arrs: for (i = 1; i < argl; i++) {
arr = arguments[i];
for (k in arr) {
if (arr[k] === arr1[k1]) {
if (i === arglm1) {
retArr[k1] = arr1[k1];
}
// If the innermost loop always leads at least once to an equal value, continue the loop until done
continue arrs;
}
}
// If it reaches here, it wasn't found in at least one array, so try next value
continue arr1keys;
}
}
return retArr;
}
function array_key_exists (key, search) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Felix Geisendoerfer (http://www.debuggable.com/felix)
// * example 1: array_key_exists('kevin', {'kevin': 'van Zonneveld'});
// * returns 1: true
// input sanitation
if (!search || (search.constructor !== Array && search.constructor !== Object)) {
return false;
}
return key in search;
}
function array_map (callback) {
// http://kevin.vanzonneveld.net
// + original by: Andrea Giammarchi (http://webreflection.blogspot.com)
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Brett Zamir (http://brett-zamir.me)
// % note 1: Takes a function as an argument, not a function's name
// % note 2: If the callback is a string, it can only work if the function name is in the global context
// * example 1: array_map( function (a){return (a * a * a)}, [1, 2, 3, 4, 5] );
// * returns 1: [ 1, 8, 27, 64, 125 ]
var argc = arguments.length,
argv = arguments;
var j = argv[1].length,
i = 0,
k = 1,
m = 0;
var tmp = [],
tmp_ar = [];
while (i < j) {
while (k < argc) {
tmp[m++] = argv[k++][i];
}
m = 0;
k = 1;
if (callback) {
if (typeof callback === 'string') {
callback = this.window[callback];
}
tmp_ar[i++] = callback.apply(null, tmp);
} else {
tmp_ar[i++] = tmp;
}
tmp = [];
}
return tmp_ar;
}
function array_merge () {
// http://kevin.vanzonneveld.net
// + original by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Nate
// + input by: josh
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// * example 1: arr1 = {"color": "red", 0: 2, 1: 4}
// * example 1: arr2 = {0: "a", 1: "b", "color": "green", "shape": "trapezoid", 2: 4}
// * example 1: array_merge(arr1, arr2)
// * returns 1: {"color": "green", 0: 2, 1: 4, 2: "a", 3: "b", "shape": "trapezoid", 4: 4}
// * example 2: arr1 = []
// * example 2: arr2 = {1: "data"}
// * example 2: array_merge(arr1, arr2)
// * returns 2: {0: "data"}
var args = Array.prototype.slice.call(arguments),
argl = args.length,
arg,
retObj = {},
k = '',
argil = 0,
j = 0,
i = 0,
ct = 0,
toStr = Object.prototype.toString,
retArr = true;
for (i = 0; i < argl; i++) {
if (toStr.call(args[i]) !== '[object Array]') {
retArr = false;
break;
}
}
if (retArr) {
retArr = [];
for (i = 0; i < argl; i++) {
retArr = retArr.concat(args[i]);
}
return retArr;
}
for (i = 0, ct = 0; i < argl; i++) {
arg = args[i];
if (toStr.call(arg) === '[object Array]') {
for (j = 0, argil = arg.length; j < argil; j++) {
retObj[ct++] = arg[j];
}
}
else {
for (k in arg) {
if (arg.hasOwnProperty(k)) {
if (parseInt(k, 10) + '' === k) {
retObj[ct++] = arg[k];
}
else {
retObj[k] = arg[k];
}
}
}
}
}
return retObj;
}
function array_pop (inputArr) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// + input by: Theriault
// % note 1: While IE (and other browsers) support iterating an object's
// % note 1: own properties in order, if one attempts to add back properties
// % note 1: in IE, they may end up in their former position due to their position
// % note 1: being retained. So use of this function with "associative arrays"
// % note 1: (objects) may lead to unexpected behavior in an IE environment if
// % note 1: you add back properties with the same keys that you removed
// * example 1: array_pop([0,1,2]);
// * returns 1: 2
// * example 2: data = {firstName: 'Kevin', surName: 'van Zonneveld'};
// * example 2: lastElem = array_pop(data);
// * returns 2: 'van Zonneveld'
// * results 2: data == {firstName: 'Kevin'}
var key = '',
lastKey = '';
if (inputArr.hasOwnProperty('length')) {
// Indexed
if (!inputArr.length) {
// Done popping, are we?
return null;
}
return inputArr.pop();
} else {
// Associative
for (key in inputArr) {
if (inputArr.hasOwnProperty(key)) {
lastKey = key;
}
}
if (lastKey) {
var tmp = inputArr[lastKey];
delete(inputArr[lastKey]);
return tmp;
} else {
return null;
}
}
}
function array_shift (inputArr) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Martijn Wieringa
// % note 1: Currently does not handle objects
// * example 1: array_shift(['Kevin', 'van', 'Zonneveld']);
// * returns 1: 'Kevin'
var props = false,
shift = undefined,
pr = '',
allDigits = /^\d$/,
int_ct = -1,
_checkToUpIndices = function (arr, ct, key) {
// Deal with situation, e.g., if encounter index 4 and try to set it to 0, but 0 exists later in loop (need to
// increment all subsequent (skipping current key, since we need its value below) until find unused)
if (arr[ct] !== undefined) {
var tmp = ct;
ct += 1;
if (ct === key) {
ct += 1;
}
ct = _checkToUpIndices(arr, ct, key);
arr[ct] = arr[tmp];
delete arr[tmp];
}
return ct;
};
if (inputArr.length === 0) {
return null;
}
if (inputArr.length > 0) {
return inputArr.shift();
}
/*
UNFINISHED FOR HANDLING OBJECTS
for (pr in inputArr) {
if (inputArr.hasOwnProperty(pr)) {
props = true;
shift = inputArr[pr];
delete inputArr[pr];
break;
}
}
for (pr in inputArr) {
if (inputArr.hasOwnProperty(pr)) {
if (pr.search(allDigits) !== -1) {
int_ct += 1;
if (parseInt(pr, 10) === int_ct) { // Key is already numbered ok, so don't need to change key for value
continue;
}
_checkToUpIndices(inputArr, int_ct, pr);
arr[int_ct] = arr[pr];
delete arr[pr];
}
}
}
if (!props) {
return null;
}
return shift;
*/
}
function current (arr) {
// http://kevin.vanzonneveld.net
// + original by: Brett Zamir (http://brett-zamir.me)
// % note 1: Uses global: php_js to store the array pointer
// * example 1: transport = ['foot', 'bike', 'car', 'plane'];
// * example 1: current(transport);
// * returns 1: 'foot'
// BEGIN REDUNDANT
this.php_js = this.php_js || {};
this.php_js.pointers = this.php_js.pointers || [];
var indexOf = function (value) {
for (var i = 0, length = this.length; i < length; i++) {
if (this[i] === value) {
return i;
}
}
return -1;
};
// END REDUNDANT
var pointers = this.php_js.pointers;
if (!pointers.indexOf) {
pointers.indexOf = indexOf;
}
if (pointers.indexOf(arr) === -1) {
pointers.push(arr, 0);
}
var arrpos = pointers.indexOf(arr);
var cursor = pointers[arrpos + 1];
if (Object.prototype.toString.call(arr) === '[object Array]') {
return arr[cursor] || false;
}
var ct = 0;
for (var k in arr) {
if (ct === cursor) {
return arr[k];
}
ct++;
}
return false; // Empty
}
function end (arr) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Legaev Andrey
// + revised by: J A R
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + restored by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + revised by: Brett Zamir (http://brett-zamir.me)
// % note 1: Uses global: php_js to store the array pointer
// * example 1: end({0: 'Kevin', 1: 'van', 2: 'Zonneveld'});
// * returns 1: 'Zonneveld'
// * example 2: end(['Kevin', 'van', 'Zonneveld']);
// * returns 2: 'Zonneveld'
// BEGIN REDUNDANT
this.php_js = this.php_js || {};
this.php_js.pointers = this.php_js.pointers || [];
var indexOf = function (value) {
for (var i = 0, length = this.length; i < length; i++) {
if (this[i] === value) {
return i;
}
}
return -1;
};
// END REDUNDANT
var pointers = this.php_js.pointers;
if (!pointers.indexOf) {
pointers.indexOf = indexOf;
}
if (pointers.indexOf(arr) === -1) {
pointers.push(arr, 0);
}
var arrpos = pointers.indexOf(arr);
if (Object.prototype.toString.call(arr) !== '[object Array]') {
var ct = 0;
for (var k in arr) {
ct++;
var val = arr[k];
}
if (ct === 0) {
return false; // Empty
}
pointers[arrpos + 1] = ct - 1;
return val;
}
if (arr.length === 0) {
return false;
}
pointers[arrpos + 1] = arr.length - 1;
return arr[pointers[arrpos + 1]];
}
function in_array (needle, haystack, argStrict) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: vlado houba
// + input by: Billy
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// * example 1: in_array('van', ['Kevin', 'van', 'Zonneveld']);
// * returns 1: true
// * example 2: in_array('vlado', {0: 'Kevin', vlado: 'van', 1: 'Zonneveld'});
// * returns 2: false
// * example 3: in_array(1, ['1', '2', '3']);
// * returns 3: true
// * example 3: in_array(1, ['1', '2', '3'], false);
// * returns 3: true
// * example 4: in_array(1, ['1', '2', '3'], true);
// * returns 4: false
var key = '',
strict = !! argStrict;
if (strict) {
for (key in haystack) {
if (haystack[key] === needle) {
return true;
}
}
} else {
for (key in haystack) {
if (haystack[key] == needle) {
return true;
}
}
}
return false;
}
function key (arr) {
// http://kevin.vanzonneveld.net
// + original by: Brett Zamir (http://brett-zamir.me)
// + input by: Riddler (http://www.frontierwebdev.com/)
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// % note 1: Uses global: php_js to store the array pointer
// * example 1: array = {fruit1: 'apple', 'fruit2': 'orange'}
// * example 1: key(array);
// * returns 1: 'fruit1'
// BEGIN REDUNDANT
this.php_js = this.php_js || {};
this.php_js.pointers = this.php_js.pointers || [];
var indexOf = function (value) {
for (var i = 0, length = this.length; i < length; i++) {
if (this[i] === value) {
return i;
}
}
return -1;
};
// END REDUNDANT
var pointers = this.php_js.pointers;
if (!pointers.indexOf) {
pointers.indexOf = indexOf;
}
if (pointers.indexOf(arr) === -1) {
pointers.push(arr, 0);
}
var cursor = pointers[pointers.indexOf(arr) + 1];
if (Object.prototype.toString.call(arr) !== '[object Array]') {
var ct = 0;
for (var k in arr) {
if (ct === cursor) {
return k;
}
ct++;
}
return false; // Empty
}
if (arr.length === 0) {
return false;
}
return cursor;
}
function date (format, timestamp) {
// http://kevin.vanzonneveld.net
// + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
// + parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html)
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: MeEtc (http://yass.meetcweb.com)
// + improved by: Brad Touesnard
// + improved by: Tim Wiel
// + improved by: Bryan Elliott
//
// + improved by: Brett Zamir (http://brett-zamir.me)
// + improved by: David Randall
// + input by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Brett Zamir (http://brett-zamir.me)
// + improved by: Brett Zamir (http://brett-zamir.me)
// + improved by: Theriault
// + derived from: gettimeofday
// + input by: majak
// + bugfixed by: majak
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: Alex
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// + improved by: Theriault
// + improved by: Brett Zamir (http://brett-zamir.me)
// + improved by: Theriault
// + improved by: Thomas Beaucourt (http://www.webapp.fr)
// + improved by: JT
// + improved by: Theriault
// + improved by: Rafał Kukawski (http://blog.kukawski.pl)
// + bugfixed by: omid (http://phpjs.org/functions/380:380#comment_137122)
// + input by: Martin
// + input by: Alex Wilson
// % note 1: Uses global: php_js to store the default timezone
// % note 2: Although the function potentially allows timezone info (see notes), it currently does not set
// % note 2: per a timezone specified by date_default_timezone_set(). Implementers might use
// % note 2: this.php_js.currentTimezoneOffset and this.php_js.currentTimezoneDST set by that function
// % note 2: in order to adjust the dates in this function (or our other date functions!) accordingly
// * example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
// * returns 1: '09:09:40 m is month'
// * example 2: date('F j, Y, g:i a', 1062462400);
// * returns 2: 'September 2, 2003, 2:26 am'
// * example 3: date('Y W o', 1062462400);
// * returns 3: '2003 36 2003'
// * example 4: x = date('Y m d', (new Date()).getTime()/1000);
// * example 4: (x+'').length == 10 // 2009 01 09
// * returns 4: true
// * example 5: date('W', 1104534000);
// * returns 5: '53'
// * example 6: date('B t', 1104534000);
// * returns 6: '999 31'
// * example 7: date('W U', 1293750000.82); // 2010-12-31
// * returns 7: '52 1293750000'
// * example 8: date('W', 1293836400); // 2011-01-01
// * returns 8: '52'
// * example 9: date('W Y-m-d', 1293974054); // 2011-01-02
// * returns 9: '52 2011-01-02'
var that = this,
jsdate, f, formatChr = /\\?([a-z])/gi,
formatChrCb,
// Keep this here (works, but for code commented-out
// below for file size reasons)
//, tal= [],
_pad = function (n, c) {
if ((n = n + '').length < c) {
return new Array((++c) - n.length).join('0') + n;
}
return n;
},
txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
formatChrCb = function (t, s) {
return f[t] ? f[t]() : s;
};
f = {
// Day
d: function () { // Day of month w/leading 0; 01..31
return _pad(f.j(), 2);
},
D: function () { // Shorthand day name; Mon...Sun
return f.l().slice(0, 3);
},
j: function () { // Day of month; 1..31
return jsdate.getDate();
},
l: function () { // Full day name; Monday...Sunday
return txt_words[f.w()] + 'day';
},
N: function () { // ISO-8601 day of week; 1[Mon]..7[Sun]
return f.w() || 7;
},
S: function () { // Ordinal suffix for day of month; st, nd, rd, th
var j = f.j();
return j > 4 && j < 21 ? 'th' : {1: 'st', 2: 'nd', 3: 'rd'}[j % 10] || 'th';
},
w: function () { // Day of week; 0[Sun]..6[Sat]
return jsdate.getDay();
},
z: function () { // Day of year; 0..365
var a = new Date(f.Y(), f.n() - 1, f.j()),
b = new Date(f.Y(), 0, 1);
return Math.round((a - b) / 864e5) + 1;
},
// Week
W: function () { // ISO-8601 week number
var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3),
b = new Date(a.getFullYear(), 0, 4);
return _pad(1 + Math.round((a - b) / 864e5 / 7), 2);
},
// Month
F: function () { // Full month name; January...December
return txt_words[6 + f.n()];
},
m: function () { // Month w/leading 0; 01...12
return _pad(f.n(), 2);
},
M: function () { // Shorthand month name; Jan...Dec
return f.F().slice(0, 3);
},
n: function () { // Month; 1...12
return jsdate.getMonth() + 1;
},
t: function () { // Days in month; 28...31
return (new Date(f.Y(), f.n(), 0)).getDate();
},
// Year
L: function () { // Is leap year?; 0 or 1
return new Date(f.Y(), 1, 29).getMonth() === 1 | 0;
},
o: function () { // ISO-8601 year
var n = f.n(),
W = f.W(),
Y = f.Y();
return Y + (n === 12 && W < 9 ? -1 : n === 1 && W > 9);
},
Y: function () { // Full year; e.g. 1980...2010
return jsdate.getFullYear();
},
y: function () { // Last two digits of year; 00...99
return (f.Y() + "").slice(-2);
},
// Time
a: function () { // am or pm
return jsdate.getHours() > 11 ? "pm" : "am";
},
A: function () { // AM or PM
return f.a().toUpperCase();
},
B: function () { // Swatch Internet time; 000..999
var H = jsdate.getUTCHours() * 36e2,
// Hours
i = jsdate.getUTCMinutes() * 60,
// Minutes
s = jsdate.getUTCSeconds(); // Seconds
return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3);
},
g: function () { // 12-Hours; 1..12
return f.G() % 12 || 12;
},
G: function () { // 24-Hours; 0..23
return jsdate.getHours();
},
h: function () { // 12-Hours w/leading 0; 01..12
return _pad(f.g(), 2);
},
H: function () { // 24-Hours w/leading 0; 00..23
return _pad(f.G(), 2);
},
i: function () { // Minutes w/leading 0; 00..59
return _pad(jsdate.getMinutes(), 2);
},
s: function () { // Seconds w/leading 0; 00..59
return _pad(jsdate.getSeconds(), 2);
},
u: function () { // Microseconds; 000000-999000
return _pad(jsdate.getMilliseconds() * 1000, 6);
},
// Timezone
e: function () { // Timezone identifier; e.g. Atlantic/Azores, ...
// The following works, but requires inclusion of the very large
// timezone_abbreviations_list() function.
/* return this.date_default_timezone_get();
*/
throw 'Not supported (see source code of date() for timezone on how to add support)';
},
I: function () { // DST observed?; 0 or 1
// Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC.
// If they are not equal, then DST is observed.
var a = new Date(f.Y(), 0),
// Jan 1
c = Date.UTC(f.Y(), 0),
// Jan 1 UTC
b = new Date(f.Y(), 6),
// Jul 1
d = Date.UTC(f.Y(), 6); // Jul 1 UTC
return 0 + ((a - c) !== (b - d));
},
O: function () { // Difference to GMT in hour format; e.g. +0200
var tzo = jsdate.getTimezoneOffset(),
a = Math.abs(tzo);
return (tzo > 0 ? "-" : "+") + _pad(Math.floor(a / 60) * 100 + a % 60, 4);
},
P: function () { // Difference to GMT w/colon; e.g. +02:00
var O = f.O();
return (O.substr(0, 3) + ":" + O.substr(3, 2));
},
T: function () { // Timezone abbreviation; e.g. EST, MDT, ...
// The following works, but requires inclusion of the very
// large timezone_abbreviations_list() function.
/* var abbr = '', i = 0, os = 0, default = 0;
if (!tal.length) {
tal = that.timezone_abbreviations_list();
}
if (that.php_js && that.php_js.default_timezone) {
default = that.php_js.default_timezone;
for (abbr in tal) {
for (i=0; i < tal[abbr].length; i++) {
if (tal[abbr][i].timezone_id === default) {
return abbr.toUpperCase();
}
}
}
}
for (abbr in tal) {
for (i = 0; i < tal[abbr].length; i++) {
os = -jsdate.getTimezoneOffset() * 60;
if (tal[abbr][i].offset === os) {
return abbr.toUpperCase();
}
}
}
*/
return 'UTC';
},
Z: function () { // Timezone offset in seconds (-43200...50400)
return -jsdate.getTimezoneOffset() * 60;
},
// Full Date/Time
c: function () { // ISO-8601 date.
return 'Y-m-d\\Th:i:sP'.replace(formatChr, formatChrCb);
},
r: function () { // RFC 2822
return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb);
},
U: function () { // Seconds since UNIX epoch
return jsdate.getTime() / 1000 | 0;
}
};
this.date = function (format, timestamp) {
that = this;
jsdate = ((typeof timestamp === 'undefined') ? new Date() : // Not provided
(timestamp instanceof Date) ? new Date(timestamp) : // JS Date()
new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
);
return format.replace(formatChr, formatChrCb);
};
return this.date(format, timestamp);
}
function basename (path, suffix) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Ash Searle (http://hexmen.com/blog/)
// + improved by: Lincoln Ramsay
// + improved by: djmix
// * example 1: basename('/www/site/home.htm', '.htm');
// * returns 1: 'home'
// * example 2: basename('ecra.php?p=1');
// * returns 2: 'ecra.php?p=1'
var b = path.replace(/^.*[\/\\]/g, '');
if (typeof(suffix) == 'string' && b.substr(b.length - suffix.length) == suffix) {
b = b.substr(0, b.length - suffix.length);
}
return b;
}
function dirname (path) {
// http://kevin.vanzonneveld.net
// + original by: Ozh
// + improved by: XoraX (http://www.xorax.info)
// * example 1: dirname('/etc/passwd');
// * returns 1: '/etc'
// * example 2: dirname('c:/Temp/x');
// * returns 2: 'c:/Temp'
// * example 3: dirname('/dir/test/');
// * returns 3: '/dir'
return path.replace(/\\/g, '/').replace(/\/[^\/]*\/?$/, '');
}
function json_decode (str_json) {
// http://kevin.vanzonneveld.net
// + original by: Public Domain (http://www.json.org/json2.js)
// + reimplemented by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: T.J. Leahy
// + improved by: Michael White
// * example 1: json_decode('[\n "e",\n {\n "pluribus": "unum"\n}\n]');
// * returns 1: ['e', {pluribus: 'unum'}]
/*
http://www.JSON.org/json2.js
2008-11-19
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See http://www.JSON.org/js.html
*/
var json = this.window.JSON;
if (typeof json === 'object' && typeof json.parse === 'function') {
try {
return json.parse(str_json);
} catch (err) {
if (!(err instanceof SyntaxError)) {
throw new Error('Unexpected error type in json_decode()');
}
this.php_js = this.php_js || {};
this.php_js.last_error_json = 4; // usable by json_last_error()
return null;
}
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
var j;
var text = str_json;
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if ((/^[\],:{}\s]*$/).
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
return j;
}
this.php_js = this.php_js || {};
this.php_js.last_error_json = 4; // usable by json_last_error()
return null;
}
function json_encode (mixed_val) {
// http://kevin.vanzonneveld.net
// + original by: Public Domain (http://www.json.org/json2.js)
// + reimplemented by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Michael White
// + input by: felix
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// * example 1: json_encode(['e', {pluribus: 'unum'}]);
// * returns 1: '[\n "e",\n {\n "pluribus": "unum"\n}\n]'
/*
http://www.JSON.org/json2.js
2008-11-19
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See http://www.JSON.org/js.html
*/
var retVal, json = this.window.JSON;
try {
if (typeof json === 'object' && typeof json.stringify === 'function') {
retVal = json.stringify(mixed_val); // Errors will not be caught here if our own equivalent to resource
// (an instance of PHPJS_Resource) is used
if (retVal === undefined) {
throw new SyntaxError('json_encode');
}
return retVal;
}
var value = mixed_val;
var quote = function (string) {
var escapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
var meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"': '\\"',
'\\': '\\\\'
};
escapable.lastIndex = 0;
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' : '"' + string + '"';
};
var str = function (key, holder) {
var gap = '';
var indent = ' ';
var i = 0; // The loop counter.
var k = ''; // The member key.
var v = ''; // The member value.
var length = 0;
var mind = gap;
var partial = [];
var value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' && typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
case 'object':
// If the type is 'object', we might be dealing with an object or an array or
// null.
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
if ((this.PHPJS_Resource && value instanceof this.PHPJS_Resource) || (window.PHPJS_Resource && value instanceof window.PHPJS_Resource)) {
throw new SyntaxError('json_encode');
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']';
gap = mind;
return v;
}
// Iterate through all of the keys in the object.
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0 ? '{}' : gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : '{' + partial.join(',') + '}';
gap = mind;
return v;
case 'undefined':
// Fall-through
case 'function':
// Fall-through
default:
throw new SyntaxError('json_encode');
}
};
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', {
'': value
});
} catch (err) { // Todo: ensure error handling above throws a SyntaxError in all cases where it could
// (i.e., when the JSON global is not available and there is an error)
if (!(err instanceof SyntaxError)) {
throw new Error('Unexpected error type in json_encode()');
}
this.php_js = this.php_js || {};
this.php_js.last_error_json = 4; // usable by json_last_error()
return null;
}
}
function uniqid (prefix, more_entropy) {
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + revised by: Kankrelune (http://www.webfaktory.info/)
// % note 1: Uses an internal counter (in php_js global) to avoid collision
// * example 1: uniqid();
// * returns 1: 'a30285b160c14'
// * example 2: uniqid('foo');
// * returns 2: 'fooa30285b1cd361'
// * example 3: uniqid('bar', true);
// * returns 3: 'bara20285b23dfd1.31879087'
if (typeof prefix == 'undefined') {
prefix = "";
}
var retId;
var formatSeed = function (seed, reqWidth) {
seed = parseInt(seed, 10).toString(16); // to hex str
if (reqWidth < seed.length) { // so long we split
return seed.slice(seed.length - reqWidth);
}
if (reqWidth > seed.length) { // so short we pad
return Array(1 + (reqWidth - seed.length)).join('0') + seed;
}
return seed;
};
// BEGIN REDUNDANT
if (!this.php_js) {
this.php_js = {};
}
// END REDUNDANT
if (!this.php_js.uniqidSeed) { // init seed with big random int
this.php_js.uniqidSeed = Math.floor(Math.random() * 0x75bcd15);
}
this.php_js.uniqidSeed++;
retId = prefix; // start with prefix, add current milliseconds hex string
retId += formatSeed(parseInt(new Date().getTime() / 1000, 10), 8);
retId += formatSeed(this.php_js.uniqidSeed, 5); // add seed hex string
if (more_entropy) {
// for more entropy we add a float lower to 10
retId += (Math.random() * 10).toFixed(8).toString();
}
return retId;
}
function echo () {
// http://kevin.vanzonneveld.net
// + original by: Philip Peterson
// + improved by: echo is bad
// + improved by: Nate
// + revised by: Der Simon (http://innerdom.sourceforge.net/)
// + improved by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Eugene Bulkin (http://doubleaw.com/)
// + input by: JB
// + improved by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: EdorFaus
// + improved by: Brett Zamir (http://brett-zamir.me)
// % note 1: If browsers start to support DOM Level 3 Load and Save (parsing/serializing),
// % note 1: we wouldn't need any such long code (even most of the code below). See
// % note 1: link below for a cross-browser implementation in JavaScript. HTML5 might
// % note 1: possibly support DOMParser, but that is not presently a standard.
// % note 2: Although innerHTML is widely used and may become standard as of HTML5, it is also not ideal for
// % note 2: use with a temporary holder before appending to the DOM (as is our last resort below),
// % note 2: since it may not work in an XML context
// % note 3: Using innerHTML to directly add to the BODY is very dangerous because it will
// % note 3: break all pre-existing references to HTMLElements.
// * example 1: echo('
');
// * returns 1: undefined
// Fix: This function really needs to allow non-XHTML input (unless in true XHTML mode) as in jQuery
var arg = '',
argc = arguments.length,
argv = arguments,
i = 0,
holder, win = this.window,
d = win.document,
ns_xhtml = 'http://www.w3.org/1999/xhtml',
ns_xul = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'; // If we're in a XUL context
var stringToDOM = function (str, parent, ns, container) {
var extraNSs = '';
if (ns === ns_xul) {
extraNSs = ' xmlns:html="' + ns_xhtml + '"';
}
var stringContainer = '<' + container + ' xmlns="' + ns + '"' + extraNSs + '>' + str + '' + container + '>';
var dils = win.DOMImplementationLS,
dp = win.DOMParser,
ax = win.ActiveXObject;
if (dils && dils.createLSInput && dils.createLSParser) {
// Follows the DOM 3 Load and Save standard, but not
// implemented in browsers at present; HTML5 is to standardize on innerHTML, but not for XML (though
// possibly will also standardize with DOMParser); in the meantime, to ensure fullest browser support, could
// attach http://svn2.assembla.com/svn/brettz9/DOMToString/DOM3.js (see http://svn2.assembla.com/svn/brettz9/DOMToString/DOM3.xhtml for a simple test file)
var lsInput = dils.createLSInput();
// If we're in XHTML, we'll try to allow the XHTML namespace to be available by default
lsInput.stringData = stringContainer;
var lsParser = dils.createLSParser(1, null); // synchronous, no schema type
return lsParser.parse(lsInput).firstChild;
} else if (dp) {
// If we're in XHTML, we'll try to allow the XHTML namespace to be available by default
try {
var fc = new dp().parseFromString(stringContainer, 'text/xml');
if (fc && fc.documentElement && fc.documentElement.localName !== 'parsererror' && fc.documentElement.namespaceURI !== 'http://www.mozilla.org/newlayout/xml/parsererror.xml') {
return fc.documentElement.firstChild;
}
// If there's a parsing error, we just continue on
} catch (e) {
// If there's a parsing error, we just continue on
}
} else if (ax) { // We don't bother with a holder in Explorer as it doesn't support namespaces
var axo = new ax('MSXML2.DOMDocument');
axo.loadXML(str);
return axo.documentElement;
}
/*else if (win.XMLHttpRequest) { // Supposed to work in older Safari
var req = new win.XMLHttpRequest;
req.open('GET', 'data:application/xml;charset=utf-8,'+encodeURIComponent(str), false);
if (req.overrideMimeType) {
req.overrideMimeType('application/xml');
}
req.send(null);
return req.responseXML;
}*/
// Document fragment did not work with innerHTML, so we create a temporary element holder
// If we're in XHTML, we'll try to allow the XHTML namespace to be available by default
//if (d.createElementNS && (d.contentType && d.contentType !== 'text/html')) { // Don't create namespaced elements if we're being served as HTML (currently only Mozilla supports this detection in true XHTML-supporting browsers, but Safari and Opera should work with the above DOMParser anyways, and IE doesn't support createElementNS anyways)
if (d.createElementNS && // Browser supports the method
(d.documentElement.namespaceURI || // We can use if the document is using a namespace
d.documentElement.nodeName.toLowerCase() !== 'html' || // We know it's not HTML4 or less, if the tag is not HTML (even if the root namespace is null)
(d.contentType && d.contentType !== 'text/html') // We know it's not regular HTML4 or less if this is Mozilla (only browser supporting the attribute) and the content type is something other than text/html; other HTML5 roots (like svg) still have a namespace
)) { // Don't create namespaced elements if we're being served as HTML (currently only Mozilla supports this detection in true XHTML-supporting browsers, but Safari and Opera should work with the above DOMParser anyways, and IE doesn't support createElementNS anyways); last test is for the sake of being in a pure XML document
holder = d.createElementNS(ns, container);
} else {
holder = d.createElement(container); // Document fragment did not work with innerHTML
}
holder.innerHTML = str;
while (holder.firstChild) {
parent.appendChild(holder.firstChild);
}
return false;
// throw 'Your browser does not support DOM parsing as required by echo()';
};
var ieFix = function (node) {
if (node.nodeType === 1) {
var newNode = d.createElement(node.nodeName);
var i, len;
if (node.attributes && node.attributes.length > 0) {
for (i = 0, len = node.attributes.length; i < len; i++) {
newNode.setAttribute(node.attributes[i].nodeName, node.getAttribute(node.attributes[i].nodeName));
}
}
if (node.childNodes && node.childNodes.length > 0) {
for (i = 0, len = node.childNodes.length; i < len; i++) {
newNode.appendChild(ieFix(node.childNodes[i]));
}
}
return newNode;
} else {
return d.createTextNode(node.nodeValue);
}
};
var replacer = function (s, m1, m2) {
// We assume for now that embedded variables do not have dollar sign; to add a dollar sign, you currently must use {$$var} (We might change this, however.)
// Doesn't cover all cases yet: see http://php.net/manual/en/language.types.string.php#language.types.string.syntax.double
if (m1 !== '\\') {
return m1 + eval(m2);
} else {
return s;
}
};
this.php_js = this.php_js || {};
var phpjs = this.php_js,
ini = phpjs.ini,
obs = phpjs.obs;
for (i = 0; i < argc; i++) {
arg = argv[i];
if (ini && ini['phpjs.echo_embedded_vars']) {
arg = arg.replace(/(.?)\{?\$(\w*?\}|\w*)/g, replacer);
}
if (!phpjs.flushing && obs && obs.length) { // If flushing we output, but otherwise presence of a buffer means caching output
obs[obs.length - 1].buffer += arg;
continue;
}
if (d.appendChild) {
if (d.body) {
if (win.navigator.appName === 'Microsoft Internet Explorer') { // We unfortunately cannot use feature detection, since this is an IE bug with cloneNode nodes being appended
d.body.appendChild(stringToDOM(ieFix(arg)));
} else {
var unappendedLeft = stringToDOM(arg, d.body, ns_xhtml, 'div').cloneNode(true); // We will not actually append the div tag (just using for providing XHTML namespace by default)
if (unappendedLeft) {
d.body.appendChild(unappendedLeft);
}
}
} else {
d.documentElement.appendChild(stringToDOM(arg, d.documentElement, ns_xul, 'description')); // We will not actually append the description tag (just using for providing XUL namespace by default)
}
} else if (d.write) {
d.write(arg);
}
/* else { // This could recurse if we ever add print!
print(arg);
}*/
}
}
function number_format (number, decimals, dec_point, thousands_sep) {
// http://kevin.vanzonneveld.net
// + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfix by: Michael White (http://getsprink.com)
// + bugfix by: Benjamin Lupton
// + bugfix by: Allan Jensen (http://www.winternet.no)
// + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
// + bugfix by: Howard Yeend
// + revised by: Luke Smith (http://lucassmith.name)
// + bugfix by: Diogo Resende
// + bugfix by: Rival
// + input by: Kheang Hok Chin (http://www.distantia.ca/)
// + improved by: davook
// + improved by: Brett Zamir (http://brett-zamir.me)
// + input by: Jay Klehr
// + improved by: Brett Zamir (http://brett-zamir.me)
// + input by: Amir Habibi (http://www.residence-mixte.com/)
// + bugfix by: Brett Zamir (http://brett-zamir.me)
// + improved by: Theriault
// + input by: Amirouche
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// * example 1: number_format(1234.56);
// * returns 1: '1,235'
// * example 2: number_format(1234.56, 2, ',', ' ');
// * returns 2: '1 234,56'
// * example 3: number_format(1234.5678, 2, '.', '');
// * returns 3: '1234.57'
// * example 4: number_format(67, 2, ',', '.');
// * returns 4: '67,00'
// * example 5: number_format(1000);
// * returns 5: '1,000'
// * example 6: number_format(67.311, 2);
// * returns 6: '67.31'
// * example 7: number_format(1000.55, 1);
// * returns 7: '1,000.6'
// * example 8: number_format(67000, 5, ',', '.');
// * returns 8: '67.000,00000'
// * example 9: number_format(0.9, 0);
// * returns 9: '1'
// * example 10: number_format('1.20', 2);
// * returns 10: '1.20'
// * example 11: number_format('1.20', 4);
// * returns 11: '1.2000'
// * example 12: number_format('1.2000', 3);
// * returns 12: '1.200'
// * example 13: number_format('1 000,50', 2, '.', ' ');
// * returns 13: '100 050.00'
// Strip all characters but numerical ones.
number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
var n = !isFinite(+number) ? 0 : +number,
prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
s = '',
toFixedFix = function (n, prec) {
var k = Math.pow(10, prec);
return '' + Math.round(n * k) / k;
};
// Fix for IE parseFloat(0.55).toFixed(0) = 0;
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
if (s[0].length > 3) {
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
}
if ((s[1] || '').length < prec) {
s[1] = s[1] || '';
s[1] += new Array(prec - s[1].length + 1).join('0');
}
return s.join(dec);
}
function sprintf () {
// http://kevin.vanzonneveld.net
// + original by: Ash Searle (http://hexmen.com/blog/)
// + namespaced by: Michael White (http://getsprink.com)
// + tweaked by: Jack
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: Paulo Freitas
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: Brett Zamir (http://brett-zamir.me)
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// * example 1: sprintf("%01.2f", 123.1);
// * returns 1: 123.10
// * example 2: sprintf("[%10s]", 'monkey');
// * returns 2: '[ monkey]'
// * example 3: sprintf("[%'#10s]", 'monkey');
// * returns 3: '[####monkey]'
var regex = /%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuidfegEG])/g;
var a = arguments,
i = 0,
format = a[i++];
// pad()
var pad = function (str, len, chr, leftJustify) {
if (!chr) {
chr = ' ';
}
var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr);
return leftJustify ? str + padding : padding + str;
};
// justify()
var justify = function (value, prefix, leftJustify, minWidth, zeroPad, customPadChar) {
var diff = minWidth - value.length;
if (diff > 0) {
if (leftJustify || !zeroPad) {
value = pad(value, minWidth, customPadChar, leftJustify);
} else {
value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length);
}
}
return value;
};
// formatBaseX()
var formatBaseX = function (value, base, prefix, leftJustify, minWidth, precision, zeroPad) {
// Note: casts negative numbers to positive ones
var number = value >>> 0;
prefix = prefix && number && {
'2': '0b',
'8': '0',
'16': '0x'
}[base] || '';
value = prefix + pad(number.toString(base), precision || 0, '0', false);
return justify(value, prefix, leftJustify, minWidth, zeroPad);
};
// formatString()
var formatString = function (value, leftJustify, minWidth, precision, zeroPad, customPadChar) {
if (precision != null) {
value = value.slice(0, precision);
}
return justify(value, '', leftJustify, minWidth, zeroPad, customPadChar);
};
// doFormat()
var doFormat = function (substring, valueIndex, flags, minWidth, _, precision, type) {
var number;
var prefix;
var method;
var textTransform;
var value;
if (substring == '%%') {
return '%';
}
// parse flags
var leftJustify = false,
positivePrefix = '',
zeroPad = false,
prefixBaseX = false,
customPadChar = ' ';
var flagsl = flags.length;
for (var j = 0; flags && j < flagsl; j++) {
switch (flags.charAt(j)) {
case ' ':
positivePrefix = ' ';
break;
case '+':
positivePrefix = '+';
break;
case '-':
leftJustify = true;
break;
case "'":
customPadChar = flags.charAt(j + 1);
break;
case '0':
zeroPad = true;
break;
case '#':
prefixBaseX = true;
break;
}
}
// parameters may be null, undefined, empty-string or real valued
// we want to ignore null, undefined and empty-string values
if (!minWidth) {
minWidth = 0;
} else if (minWidth == '*') {
minWidth = +a[i++];
} else if (minWidth.charAt(0) == '*') {
minWidth = +a[minWidth.slice(1, -1)];
} else {
minWidth = +minWidth;
}
// Note: undocumented perl feature:
if (minWidth < 0) {
minWidth = -minWidth;
leftJustify = true;
}
if (!isFinite(minWidth)) {
throw new Error('sprintf: (minimum-)width must be finite');
}
if (!precision) {
precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : undefined;
} else if (precision == '*') {
precision = +a[i++];
} else if (precision.charAt(0) == '*') {
precision = +a[precision.slice(1, -1)];
} else {
precision = +precision;
}
// grab value using valueIndex if required?
value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++];
switch (type) {
case 's':
return formatString(String(value), leftJustify, minWidth, precision, zeroPad, customPadChar);
case 'c':
return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad);
case 'b':
return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
case 'o':
return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
case 'x':
return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
case 'X':
return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad).toUpperCase();
case 'u':
return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
case 'i':
case 'd':
number = (+value) | 0;
prefix = number < 0 ? '-' : positivePrefix;
value = prefix + pad(String(Math.abs(number)), precision, '0', false);
return justify(value, prefix, leftJustify, minWidth, zeroPad);
case 'e':
case 'E':
case 'f':
case 'F':
case 'g':
case 'G':
number = +value;
prefix = number < 0 ? '-' : positivePrefix;
method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())];
textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2];
value = prefix + Math.abs(number)[method](precision);
return justify(value, prefix, leftJustify, minWidth, zeroPad)[textTransform]();
default:
return substring;
}
};
return format.replace(regex, doFormat);
}
function substr (str, start, len) {
// Returns part of a string
//
// version: 909.322
// discuss at: http://phpjs.org/functions/substr
// + original by: Martijn Wieringa
// + bugfixed by: T.Wild
// + tweaked by: Onno Marsman
// + revised by: Theriault
// + improved by: Brett Zamir (http://brett-zamir.me)
// % note 1: Handles rare Unicode characters if 'unicode.semantics' ini (PHP6) is set to 'on'
// * example 1: substr('abcdef', 0, -1);
// * returns 1: 'abcde'
// * example 2: substr(2, 0, -6);
// * returns 2: false
// * example 3: ini_set('unicode.semantics', 'on');
// * example 3: substr('a\uD801\uDC00', 0, -1);
// * returns 3: 'a'
// * example 4: ini_set('unicode.semantics', 'on');
// * example 4: substr('a\uD801\uDC00', 0, 2);
// * returns 4: 'a\uD801\uDC00'
// * example 5: ini_set('unicode.semantics', 'on');
// * example 5: substr('a\uD801\uDC00', -1, 1);
// * returns 5: '\uD801\uDC00'
// * example 6: ini_set('unicode.semantics', 'on');
// * example 6: substr('a\uD801\uDC00z\uD801\uDC00', -3, 2);
// * returns 6: '\uD801\uDC00z'
// * example 7: ini_set('unicode.semantics', 'on');
// * example 7: substr('a\uD801\uDC00z\uD801\uDC00', -3, -1)
// * returns 7: '\uD801\uDC00z'
// Add: (?) Use unicode.runtime_encoding (e.g., with string wrapped in "binary" or "Binary" class) to
// allow access of binary (see file_get_contents()) by: charCodeAt(x) & 0xFF (see https://developer.mozilla.org/En/Using_XMLHttpRequest ) or require conversion first?
var i = 0,
allBMP = true,
es = 0,
el = 0,
se = 0,
ret = '';
str += '';
var end = str.length;
// BEGIN REDUNDANT
this.php_js = this.php_js || {};
this.php_js.ini = this.php_js.ini || {};
// END REDUNDANT
switch ((this.php_js.ini['unicode.semantics'] && this.php_js.ini['unicode.semantics'].local_value.toLowerCase())) {
case 'on':
// Full-blown Unicode including non-Basic-Multilingual-Plane characters
// strlen()
for (i = 0; i < str.length; i++) {
if (/[\uD800-\uDBFF]/.test(str.charAt(i)) && /[\uDC00-\uDFFF]/.test(str.charAt(i + 1))) {
allBMP = false;
break;
}
}
if (!allBMP) {
if (start < 0) {
for (i = end - 1, es = (start += end); i >= es; i--) {
if (/[\uDC00-\uDFFF]/.test(str.charAt(i)) && /[\uD800-\uDBFF]/.test(str.charAt(i - 1))) {
start--;
es--;
}
}
} else {
var surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
while ((surrogatePairs.exec(str)) != null) {
var li = surrogatePairs.lastIndex;
if (li - 2 < start) {
start++;
} else {
break;
}
}
}
if (start >= end || start < 0) {
return false;
}
if (len < 0) {
for (i = end - 1, el = (end += len); i >= el; i--) {
if (/[\uDC00-\uDFFF]/.test(str.charAt(i)) && /[\uD800-\uDBFF]/.test(str.charAt(i - 1))) {
end--;
el--;
}
}
if (start > end) {
return false;
}
return str.slice(start, end);
} else {
se = start + len;
for (i = start; i < se; i++) {
ret += str.charAt(i);
if (/[\uD800-\uDBFF]/.test(str.charAt(i)) && /[\uDC00-\uDFFF]/.test(str.charAt(i + 1))) {
se++; // Go one further, since one of the "characters" is part of a surrogate pair
}
}
return ret;
}
break;
}
// Fall-through
case 'off':
// assumes there are no non-BMP characters;
// if there may be such characters, then it is best to turn it on (critical in true XHTML/XML)
default:
if (start < 0) {
start += end;
}
end = typeof len === 'undefined' ? end : (len < 0 ? len + end : len + start);
// PHP returns false if start does not fall within the string.
// PHP returns false if the calculated end comes before the calculated start.
// PHP returns an empty string if start and end are the same.
// Otherwise, PHP returns the portion of the string from start to end.
return start >= str.length || start < 0 || start > end ? !1 : str.slice(start, end);
}
return undefined; // Please Netbeans
}
function trim (str, charlist) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: mdsjack (http://www.mdsjack.bo.it)
// + improved by: Alexander Ermolaev (http://snippets.dzone.com/user/AlexanderErmolaev)
// + input by: Erkekjetter
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: DxGx
// + improved by: Steven Levithan (http://blog.stevenlevithan.com)
// + tweaked by: Jack
// + bugfixed by: Onno Marsman
// * example 1: trim(' Kevin van Zonneveld ');
// * returns 1: 'Kevin van Zonneveld'
// * example 2: trim('Hello World', 'Hdle');
// * returns 2: 'o Wor'
// * example 3: trim(16, 1);
// * returns 3: 6
var whitespace, l = 0,
i = 0;
str += '';
if (!charlist) {
// default list
whitespace = " \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000";
} else {
// preg_quote custom list
charlist += '';
whitespace = charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1');
}
l = str.length;
for (i = 0; i < l; i++) {
if (whitespace.indexOf(str.charAt(i)) === -1) {
str = str.substring(i);
break;
}
}
l = str.length;
for (i = l - 1; i >= 0; i--) {
if (whitespace.indexOf(str.charAt(i)) === -1) {
str = str.substring(0, i + 1);
break;
}
}
return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
}
function ucfirst (str) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Onno Marsman
// + improved by: Brett Zamir (http://brett-zamir.me)
// * example 1: ucfirst('kevin van zonneveld');
// * returns 1: 'Kevin van zonneveld'
str += '';
var f = str.charAt(0).toUpperCase();
return f + str.substr(1);
}
function rawurldecode (str) {
// http://kevin.vanzonneveld.net
// + original by: Brett Zamir (http://brett-zamir.me)
// + input by: travc
// + input by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: Ratheous
// + reimplemented by: Brett Zamir (http://brett-zamir.me)
// % note 1: Please be aware that this function expects to decode from UTF-8 encoded strings, as found on
// % note 1: pages served as UTF-8
// * example 1: rawurldecode('Kevin+van+Zonneveld%21');
// * returns 1: 'Kevin+van+Zonneveld!'
// * example 2: rawurldecode('http%3A%2F%2Fkevin.vanzonneveld.net%2F');
// * returns 2: 'http://kevin.vanzonneveld.net/'
// * example 3: rawurldecode('http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a');
// * returns 3: 'http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'
// * example 4: rawurldecode('-22%97bc%2Fbc');
// * returns 4: '-22—bc/bc'
return decodeURIComponent(str + '');
}
function rawurlencode (str) {
// http://kevin.vanzonneveld.net
// + original by: Brett Zamir (http://brett-zamir.me)
// + input by: travc
// + input by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: Michael Grier
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// + input by: Ratheous
// + reimplemented by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Joris
// + reimplemented by: Brett Zamir (http://brett-zamir.me)
// % note 1: This reflects PHP 5.3/6.0+ behavior
// % note 2: Please be aware that this function expects to encode into UTF-8 encoded strings, as found on
// % note 2: pages served as UTF-8
// * example 1: rawurlencode('Kevin van Zonneveld!');
// * returns 1: 'Kevin%20van%20Zonneveld%21'
// * example 2: rawurlencode('http://kevin.vanzonneveld.net/');
// * returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F'
// * example 3: rawurlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a');
// * returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a'
str = (str + '').toString();
// Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current
// PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following.
return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').
replace(/\)/g, '%29').replace(/\*/g, '%2A');
}
function urldecode (str) {
// http://kevin.vanzonneveld.net
// + original by: Philip Peterson
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: AJ
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Brett Zamir (http://brett-zamir.me)
// + input by: travc
// + input by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Lars Fischer
// + input by: Ratheous
// + improved by: Orlando
// + reimplemented by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Rob
// + input by: e-mike
// + improved by: Brett Zamir (http://brett-zamir.me)
// % note 1: info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
// % note 2: Please be aware that this function expects to decode from UTF-8 encoded strings, as found on
// % note 2: pages served as UTF-8
// * example 1: urldecode('Kevin+van+Zonneveld%21');
// * returns 1: 'Kevin van Zonneveld!'
// * example 2: urldecode('http%3A%2F%2Fkevin.vanzonneveld.net%2F');
// * returns 2: 'http://kevin.vanzonneveld.net/'
// * example 3: urldecode('http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a');
// * returns 3: 'http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'
return decodeURIComponent((str + '').replace(/\+/g, '%20'));
}
function urlencode (str) {
// http://kevin.vanzonneveld.net
// + original by: Philip Peterson
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: AJ
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: travc
// + input by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Lars Fischer
// + input by: Ratheous
// + reimplemented by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Joris
// + reimplemented by: Brett Zamir (http://brett-zamir.me)
// % note 1: This reflects PHP 5.3/6.0+ behavior
// % note 2: Please be aware that this function expects to encode into UTF-8 encoded strings, as found on
// % note 2: pages served as UTF-8
// * example 1: urlencode('Kevin van Zonneveld!');
// * returns 1: 'Kevin+van+Zonneveld%21'
// * example 2: urlencode('http://kevin.vanzonneveld.net/');
// * returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F'
// * example 3: urlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a');
// * returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a'
str = (str + '').toString();
// Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current
// PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following.
return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').
replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
}
function empty (mixed_var) {
// http://kevin.vanzonneveld.net
// + original by: Philippe Baumann
// + input by: Onno Marsman
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: LH
// + improved by: Onno Marsman
// + improved by: Francesco
// + improved by: Marc Jansen
// + input by: Stoyan Kyosev (http://www.svest.org/)
// * example 1: empty(null);
// * returns 1: true
// * example 2: empty(undefined);
// * returns 2: true
// * example 3: empty([]);
// * returns 3: true
// * example 4: empty({});
// * returns 4: true
// * example 5: empty({'aFunc' : function () { alert('humpty'); } });
// * returns 5: false
var key;
if (mixed_var === "" || mixed_var === 0 || mixed_var === "0" || mixed_var === null || mixed_var === false || typeof mixed_var === 'undefined') {
return true;
}
if (typeof mixed_var == 'object') {
for (key in mixed_var) {
return false;
}
return true;
}
return false;
}
function intval (mixed_var, base) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: stensi
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: Matteo
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Rafał Kukawski (http://kukawski.pl)
// * example 1: intval('Kevin van Zonneveld');
// * returns 1: 0
// * example 2: intval(4.2);
// * returns 2: 4
// * example 3: intval(42, 8);
// * returns 3: 42
// * example 4: intval('09');
// * returns 4: 9
// * example 5: intval('1e', 16);
// * returns 5: 30
var tmp;
var type = typeof(mixed_var);
if (type === 'boolean') {
return +mixed_var;
} else if (type === 'string') {
tmp = parseInt(mixed_var, base || 10);
return (isNaN(tmp) || !isFinite(tmp)) ? 0 : tmp;
} else if (type === 'number' && isFinite(mixed_var)) {
return mixed_var | 0;
} else {
return 0;
}
}
function is_array (mixed_var) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Legaev Andrey
// + bugfixed by: Cord
// + bugfixed by: Manish
// + improved by: Onno Marsman
// + improved by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// + improved by: Nathan Sepulveda
// + improved by: Brett Zamir (http://brett-zamir.me)
// % note 1: In php.js, javascript objects are like php associative arrays, thus JavaScript objects will also
// % note 1: return true in this function (except for objects which inherit properties, being thus used as objects),
// % note 1: unless you do ini_set('phpjs.objectsAsArrays', 0), in which case only genuine JavaScript arrays
// % note 1: will return true
// * example 1: is_array(['Kevin', 'van', 'Zonneveld']);
// * returns 1: true
// * example 2: is_array('Kevin van Zonneveld');
// * returns 2: false
// * example 3: is_array({0: 'Kevin', 1: 'van', 2: 'Zonneveld'});
// * returns 3: true
// * example 4: is_array(function tmp_a(){this.name = 'Kevin'});
// * returns 4: false
var ini,
_getFuncName = function (fn) {
var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn);
if (!name) {
return '(Anonymous)';
}
return name[1];
},
_isArray = function (mixed_var) {
// return Object.prototype.toString.call(mixed_var) === '[object Array]';
// The above works, but let's do the even more stringent approach: (since Object.prototype.toString could be overridden)
// Null, Not an object, no length property so couldn't be an Array (or String)
if (!mixed_var || typeof mixed_var !== 'object' || typeof mixed_var.length !== 'number') {
return false;
}
var len = mixed_var.length;
mixed_var[mixed_var.length] = 'bogus';
// The only way I can think of to get around this (or where there would be trouble) would be to have an object defined
// with a custom "length" getter which changed behavior on each call (or a setter to mess up the following below) or a custom
// setter for numeric properties, but even that would need to listen for specific indexes; but there should be no false negatives
// and such a false positive would need to rely on later JavaScript innovations like __defineSetter__
if (len !== mixed_var.length) { // We know it's an array since length auto-changed with the addition of a
// numeric property at its length end, so safely get rid of our bogus element
mixed_var.length -= 1;
return true;
}
// Get rid of the property we added onto a non-array object; only possible
// side-effect is if the user adds back the property later, it will iterate
// this property in the older order placement in IE (an order which should not
// be depended on anyways)
delete mixed_var[mixed_var.length];
return false;
};
if (!mixed_var || typeof mixed_var !== 'object') {
return false;
}
// BEGIN REDUNDANT
this.php_js = this.php_js || {};
this.php_js.ini = this.php_js.ini || {};
// END REDUNDANT
ini = this.php_js.ini['phpjs.objectsAsArrays'];
return _isArray(mixed_var) ||
// Allow returning true unless user has called
// ini_set('phpjs.objectsAsArrays', 0) to disallow objects as arrays
((!ini || ( // if it's not set to 0 and it's not 'off', check for objects as arrays
(parseInt(ini.local_value, 10) !== 0 && (!ini.local_value.toLowerCase || ini.local_value.toLowerCase() !== 'off')))
) && (
Object.prototype.toString.call(mixed_var) === '[object Object]' && _getFuncName(mixed_var.constructor) === 'Object' // Most likely a literal and intended as assoc. array
));
}
function is_numeric (mixed_var) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: David
// + improved by: taith
// + bugfixed by: Tim de Koning
// + bugfixed by: WebDevHobo (http://webdevhobo.blogspot.com/)
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// * example 1: is_numeric(186.31);
// * returns 1: true
// * example 2: is_numeric('Kevin van Zonneveld');
// * returns 2: false
// * example 3: is_numeric('+186.31e2');
// * returns 3: true
// * example 4: is_numeric('');
// * returns 4: false
// * example 4: is_numeric([]);
// * returns 4: false
return (typeof(mixed_var) === 'number' || typeof(mixed_var) === 'string') && mixed_var !== '' && !isNaN(mixed_var);
}
function is_string (mixed_var) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// * example 1: is_string('23');
// * returns 1: true
// * example 2: is_string(23.5);
// * returns 2: false
return (typeof(mixed_var) == 'string');
}
function print_r (array, return_val) {
// http://kevin.vanzonneveld.net
// + original by: Michael White (http://getsprink.com)
// + improved by: Ben Bryan
// + input by: Brett Zamir (http://brett-zamir.me)
// + improved by: Brett Zamir (http://brett-zamir.me)
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// - depends on: echo
// * example 1: print_r(1, true);
// * returns 1: 1
var output = '',
pad_char = ' ',
pad_val = 4,
d = this.window.document,
getFuncName = function (fn) {
var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn);
if (!name) {
return '(Anonymous)';
}
return name[1];
},
repeat_char = function (len, pad_char) {
var str = '';
for (var i = 0; i < len; i++) {
str += pad_char;
}
return str;
},
formatArray = function (obj, cur_depth, pad_val, pad_char) {
if (cur_depth > 0) {
cur_depth++;
}
var base_pad = repeat_char(pad_val * cur_depth, pad_char);
var thick_pad = repeat_char(pad_val * (cur_depth + 1), pad_char);
var str = '';
if (typeof obj === 'object' && obj !== null && obj.constructor && getFuncName(obj.constructor) !== 'PHPJS_Resource') {
str += 'Array\n' + base_pad + '(\n';
for (var key in obj) {
if (Object.prototype.toString.call(obj[key]) === '[object Array]') {
str += thick_pad + '[' + key + '] => ' + formatArray(obj[key], cur_depth + 1, pad_val, pad_char);
}
else {
str += thick_pad + '[' + key + '] => ' + obj[key] + '\n';
}
}
str += base_pad + ')\n';
}
else if (obj === null || obj === undefined) {
str = '';
}
else { // for our "resource" class
str = obj.toString();
}
return str;
};
output = formatArray(array, 0, pad_val, pad_char);
if (return_val !== true) {
if (d.body) {
this.echo(output);
}
else {
try {
d = XULDocument; // We're in XUL, so appending as plain text won't work; trigger an error out of XUL
this.echo('' + output + '
');
} catch (e) {
this.echo(output); // Outputting as plain text may work in some plain XML
}
}
return true;
}
return output;
}