Test case details

Preparation Code

<script> /*! * utility v0.3.0 * http://code.google.com/p/utility-js/ * * Developed by: * - Xotic750 * * GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html */ /*jslint sub: true, maxerr: 50, maxlen: 250, indent: 4 */ /*global window,document,console,alert,jQuery,GM_getValue,GM_setValue,GM_deleteValue,GM_listValues,localStorage,sessionStorage,rison,Components */ (function utility_closure() { "use strict"; /////////////////////////// // Variables /////////////////////////// var core = {}, defineProperty = Object.defineProperty, getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, getOwnPropertyNames = Object.getOwnPropertyNames, hasOwnProperty = Object.prototype.hasOwnProperty, getPrototypeOf = Object.getPrototypeOf, oToString = Object.prototype.toString, aSlice = Array.prototype.slice, cNull = null, cUndefined; /////////////////////////// // Utility /////////////////////////// function Utility(obj) { defineProperty(this, "refersTo", { enumerable: true, value: obj }); return this; } /////////////////////////// // utility /////////////////////////// function utility(obj) { switch (utility.typeOf(obj)) { case "object": if (utility.isPlainObject(obj)) { Utility.prototype = core.Object.prototype; } else { Utility.prototype = core.Common.prototype; } break; case "array": Utility.prototype = core.Array.prototype; break; case "function": Utility.prototype = core.Function.prototype; break; case "string": Utility.prototype = core.String.prototype; break; case "number": Utility.prototype = core.Number.prototype; break; case "boolean": Utility.prototype = core.Boolean.prototype; break; case "date": Utility.prototype = core.Date.prototype; break; case "regexp": Utility.prototype = core.RegExp.prototype; break; case "arguments": Utility.prototype = core.Arguments.prototype; break; case "error": Utility.prototype = core.Error.prototype; break; default: Utility.prototype = core.Common.prototype; } return new Utility(obj); } defineProperty(utility, "version", { value: "0.3.0" }); defineProperty(utility, "inheriting", { value: {} }); defineProperty(utility, "mixin", { value: function (obj, inheritFrom, keys) { keys.forEach(function (key) { defineProperty(obj, key, getOwnPropertyDescriptor(inheritFrom, key)); }); } }); defineProperty(utility, "isUndefined", { value: function (obj) { return obj === cUndefined; } }); defineProperty(utility, "isNull", { value: function (obj) { return obj === cNull; } }); defineProperty(utility, "isInitialised", { value: function (obj) { return !(obj === cUndefined || obj === cNull); } }); function generateClassIs(typeArr) { if (oToString.call(typeArr) !== "[object Array]" || typeArr.length < 1) { throw new TypeError("'typeArr' must be an array with elements"); } var prop = "is" + typeArr[0]; if (typeArr[0] === "Array") { defineProperty(utility, prop, { value: Array.isArray }); } else { defineProperty(utility, prop, { value: function (obj) { var matched = typeArr.some(function (type) { return obj !== cUndefined && obj !== cNull && oToString.call(obj) === "[object " + type + "]"; }); return matched; } }); } } defineProperty(utility, "classStringToType", { value: (function () { var a = ["Boolean", "Number", "String", "Function", "Array", "Date", "RegExp", "Arguments", "Error", "Object"], o = {}; a.forEach(function (type) { o["[object " + type + "]"] = type.toLowerCase(); generateClassIs([type]); }); return o; }()) }); defineProperty(utility, "toClassString", { value: function (obj) { return oToString.call(obj); } }); defineProperty(utility, "typeOf", { value: function (obj) { if (!utility.isInitialised(obj)) { return String(obj); } return utility.classStringToType[utility.toClassString(obj)] || typeof obj; } }); defineProperty(utility, "isNumeric", { value: (function () { var rx = /^-/; return function (obj) { return (utility.isNumber(obj) || (utility.isString(obj) && obj.length > 0)) && !isNaN(parseFloat(obj)) && isFinite(obj.toString().replace(rx, '')); }; }()) }); defineProperty(utility, "isInt", { value: function (obj) { return utility.isNumeric(obj) && parseInt(obj, 10) === parseFloat(obj); } }); defineProperty(utility, "isCircular", { value: function (obj, a) { if (!utility.isObject(obj) && !utility.isFunction(obj)) { return false; } if (!utility.isArray(a)) { if (utility.isInitialised(a)) { throw new TypeError("Expected attribute to be an array"); } a = []; } a.push(obj); var val, c = Object.keys(obj).some(function (key) { val = obj[key]; return (utility.isObject(val) || utility.isFunction(val)) && (a.indexOf(val) >= 0 || utility.isCircular(val, a)); }); a.pop(); return c; } }); defineProperty(utility, "isNativeFunction", { value: (function () { var e = "{ [native code] }", m = e.length; return function (fn) { return utility.isFunction(fn) && fn.toString().slice(-m) === e; }; }()) }); defineProperty(utility, "has", { value: function (obj, prop) { return utility.isInitialised(obj) && utility.isString(prop) && prop.length > 0 && prop in obj; } }); defineProperty(utility, "hasOwn", { value: function (obj, prop) { return utility.isInitialised(obj) && utility.isString(prop) && prop.length > 0 && hasOwnProperty.call(obj, prop); } }); defineProperty(utility, "isDom", { value: (function () { var p = "[object HTML", l = p.length, a = ["Element", "Attr", "Text", "CDATASection", "EntityReference", "Entity", "ProcessingInstruction", "Comment", "Document", "DocumentType", "DocumentFragment", "Notation"], o = {}; a.forEach(function (type) { o["[object " + type + "]"] = true; generateClassIs(["DOMType" + type]); }); return function (obj) { var classString = utility.toClassString(obj); return utility.isObject(obj) && (o[classString] || classString.slice(0, l) === p); }; }()) }); generateClassIs(["HTMLDocument"]); generateClassIs(["Window", "global"]); defineProperty(utility, "isPlainObject", { value: (function () { var o = {}; return function (obj) { return utility.isObject(obj) && getPrototypeOf(obj).isPrototypeOf(o); }; }()) }); defineProperty(utility, "isEmptyObject", { value: function (obj) { if (!utility.isPlainObject(obj)) { throw new TypeError("Cannot call method 'isEmptyObject' of " + utility.toClassString(obj)); } return Object.keys(obj).length === 0; } }); defineProperty(utility, "lengthOf", { value: function (obj) { if (utility.isArray(obj) || utility.isString(obj) || utility.isArguments(obj) || (utility.isObject(obj) && utility.isInitialised(obj.length))) { return obj.length; } if (utility.isPlainObject(obj)) { return Object.keys(obj).length; } throw new Error("Cannot call method 'lengthOf' of " + utility.toClassString(obj)); } }); defineProperty(utility, "hasContent", { value: function (obj) { if (!utility.isInitialised(obj)) { return false; } if (utility.isFunction(obj) || utility.isBoolean(obj) || utility.isWindow(obj)) { return true; } if (utility.isNumber(obj) || utility.isDate(obj)) { return isFinite(obj); } if (utility.isRegExp(obj)) { return utility.isString(obj.source) && obj.source.length > 0 && obj.source !== "(?:)"; } if (utility.isError(obj)) { return utility.isString(obj.stack) && obj.stack.length > 0; } try { return utility.lengthOf(obj) > 0; } catch (e) { throw new Error("Cannot call method 'hasContent' of " + utility.toClassString(obj)); } } }); defineProperty(utility, "setContent", { value: function (obj, val) { if (utility.hasContent(obj)) { return obj; } return val; } }); defineProperty(utility, "hasIndexOf", { value: function (obj, val) { return ((utility.isArray(obj) || !utility.isString(obj)) && obj.length > 0 && obj.indexOf(val) >= 0) || (utility.isPlainObject(obj) && Object.keys(obj).indexOf(val) >= 0); } }); defineProperty(utility, "addEvent", { value: function addEvent(obj, type, fn) { if (!utility.isDom(obj) || (!utility.has(obj, "attachEvent") && !utility.has(obj, "addEventListener"))) { throw new TypeError("Cannot call method 'addEvent' of " + utility.toClassString(obj)); } if (!utility.isString(obj) || obj.length < 1) { throw new TypeError("Attribute 'type' is not a valid identifier"); } if (!utility.isFunction(obj)) { throw new TypeError("Attribute 'fn' is not a function"); } if (utility.isFunction(obj, "attachEvent")) { obj['e' + type + fn] = fn; obj[type + fn] = function () { obj['e' + type + fn](window.event); }; obj.attachEvent('on' + type, obj[type + fn]); } else if (utility.isFunction(obj, "addEventListener")) { obj.addEventListener(type, fn, false); } else { throw new Error("unable to call method 'addEvent' of" + utility.toClassString(obj)); } } }); defineProperty(utility, "removeEvent", { value: function (obj, type, fn) { if (!utility.isDom(obj) || (!utility.has(obj, "detachEvent") && !utility.has(obj, "removeEventListener"))) { throw new TypeError("Cannot call method 'removeEvent' of " + utility.toClassString(obj)); } if (!utility.isString(obj) || obj.length < 1) { throw new TypeError("Attribute 'type' is not a valid identifier"); } if (!utility.isFunction(obj)) { throw new TypeError("Attribute 'fn' is not a function"); } if (utility.isFunction(obj, "detachEvent")) { obj.detachEvent('on' + type, obj[type + fn]); obj[type + fn] = null; } else if (utility.isFunction(obj, "removeEventListener")) { obj.removeEventListener(type, fn, false); } else { throw new Error("unable to call method 'removeEvent' of" + utility.toClassString(obj)); } } }); defineProperty(utility, "escapeRegExpString", { value: (function () { var a = ['.', '*', '+', '?', '^', '=', '!', ':', '$', '{', '}', '(', ')', '|', '[', ']', '/', '\\'], rx = new RegExp("([\\" + a.join('\\') + "])", "gm"); return function (str) { if (!utility.isString(str)) { throw new TypeError("Attribute 'str' is not a string " + utility.toClassString(str)); } if (str.length === 0) { return str; } return str.replace(rx, '\\$1'); }; }()) }); defineProperty(utility, "repeatString", { value: function (str, num) { if (!utility.isString(str)) { throw new TypeError("Attribute 'str' is not a string " + utility.toClassString(str)); } if (str.length === 0 || !utility.isNumber(num) || !utility.isNumeric(num) || num <= 1) { if (num === 1) { return str; } return ''; } var result = '', pattern = str; /*jslint bitwise: true */ while (num > 0) { if (num & 1) { result += pattern; } num >>= 1; pattern += pattern; } /*jslint bitwise: false */ return result; } }); defineProperty(utility, "lpadString", { value: function (obj, str, num) { if (!utility.isString(obj)) { throw new TypeError("Attribute 'obj' is not a string " + utility.toClassString(obj)); } if (!utility.isString(str)) { throw new TypeError("Attribute 'str' is not a string " + utility.toClassString(str)); } return utility.repeatString(str, num) + obj; } }); defineProperty(utility, "rpadString", { value: function (obj, str, num) { if (!utility.isString(obj)) { throw new TypeError("Attribute 'obj' is not a string " + utility.toClassString(obj)); } if (!utility.isString(str)) { throw new TypeError("Attribute 'str' is not a string " + utility.toClassString(str)); } return utility.repeatString(str, num) + obj; } }); defineProperty(utility, "decodeURIQueryString", { value: (function () { var rx = /\+/g; return function (str) { if (!utility.isString(str)) { throw new TypeError("Attribute 'str' is not a string " + utility.toClassString(str)); } return str.replace(rx, ' '); }; }()) }); defineProperty(utility, "toQueryParams", { value: (function () { var mrx = new RegExp("([^?#]*)(#.*)?$"), qrx = new RegExp("(?:^|&)([^&=]*)=?([^&]*)", "g"); return function (str) { if (!utility.isString(str)) { throw new TypeError("Attribute 'str' is not a string " + utility.toClassString(str)); } var hash = {}; str.trim().match(mrx)[1].replace(qrx, function () { var args = aSlice.call(arguments), key = args[1], value = args[2]; if (utility.isString(key) && key.length > 0) { key = utility.decodeURIQueryString(decodeURIComponent(key)); if (utility.isString(value) && value.length > 0) { value = utility.decodeURIQueryString(decodeURIComponent(value)); } else { value = ""; } if (utility.isString(key) && key.length > 0) { if (utility.isInitialised(hash[key])) { if (!utility.isArray(hash[key])) { hash[key] = [hash[key]]; } hash[key].push(value); } else { hash[key] = value; } } } }); return hash; }; }()) }); defineProperty(utility, "toUriParts", { value: (function () { var srx = new RegExp("^(?:([^:\\/?#]+):)?(?:\\/\\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\\/?#]*)(?::(\\d*))?))?((((?:[^?#\\/]*\\/)*)([^?#]*))(?:\\?([^#]*))?(?:#(.*))?)"), lrx = new RegExp("^(?:(?![^:@]+:[^:@\\/]*@)([^:\\/?#.]+):)?(?:\\/\\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\\/?#]*)(?::(\\d*))?)(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))(?:\\?([^#]*))?(?:#(.*))?)"), keys = ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"]; return function (str, strict) { if (!utility.isString(str)) { throw new TypeError("Attribute 'str' is not a string " + utility.toClassString(str)); } var uri = {}, vals; if (strict === true) { vals = srx.exec(str); } else { vals = lrx.exec(str); } keys.forEach(function (key, index) { var val = vals[index]; if (utility.isString(val) && val.length > 0) { uri[key] = decodeURIComponent(val); } else { uri[key] = ""; } }); if (uri.query.length > 0) { uri.queryKey = utility.toQueryParams(uri.query); } else { uri.queryKey = {}; } if (uri.anchor.length > 0) { uri.anchorKey = utility.toQueryParams(uri.anchor); } else { uri.anchorKey = {}; } return uri; }; }()) }); defineProperty(utility, "toNumberIfNumeric", { value: function (str) { if (utility.isNumeric(str)) { return parseFloat(str); } return str; } }); defineProperty(utility, "regex", { value: function (str, obj, flags) { if (!utility.isString(str)) { throw new TypeError("Attribute 'str' is not a string " + utility.toClassString(str)); } if (!utility.isString(obj) && !utility.isRegExp(obj)) { throw new TypeError("Attribute 'obj' is not a string or regexp " + utility.toClassString(obj)); } if (utility.isInitialised(flags)) { if (!utility.isString(flags)) { throw new TypeError("Attribute 'flags' is not a string " + utility.toClassString(obj)); } if (!/^[gi]*$/.test(flags)) { throw new TypeError("Invalid flags supplied '" + flags.match(new RegExp("[^gi]*")) + "'"); } } var matches, rx, uflags = '', cflags = '', interim = [], results = []; if (utility.isString(obj) && utility.isString(flags)) { if (flags.indexOf("g") >= 0) { uflags += 'g'; } if (flags.indexOf("i") >= 0) { uflags += 'i'; } } if (utility.isString(obj)) { matches = str.match(new RegExp(utility.escapeRegExpString(obj), uflags)); } else { matches = str.match(obj); } if (!utility.isArray(matches)) { return utility.toNumberIfNumeric(matches); } if (utility.isRegExp(obj)) { if (obj.global) { if (obj.multiline) { cflags += 'm'; } if (obj.ignoreCase) { cflags += 'i'; } rx = new RegExp(obj.source, cflags); matches.forEach(function (match) { interim.push(utility.regex(match, rx)); }); } else { if (matches.length > 1) { interim = matches.slice(1); } else { return matches.pop(); } } interim.forEach(function (element) { if (utility.isArray(element)) { var a = []; element.forEach(function (sub) { a.push(utility.toNumberIfNumeric(sub)); }); results.push(a); } else { results.push(utility.toNumberIfNumeric(element)); } }); } else { matches.forEach(function (match) { results.push(utility.toNumberIfNumeric(match)); }); } return results; } }); defineProperty(utility, "toList", { value: (function () { var rx = /[,\n]/g; return function (str) { if (!utility.isString(str)) { return []; } var a = [], t = str.split(rx); t.forEach(function (element) { var trimmed = element.trim(); if (trimmed.length > 0) { a.push(utility.toNumberIfNumeric(trimmed)); } }); return a; }; }()) }); /*jslint bitwise: true */ defineProperty(utility, "Utf8encode", { value: (function () { var rx1 = /[\u0080-\u07ff]/g, rx2 = /[\u0800-\uffff]/g, b64mask = 0x3f, msbmask = 0x80; return function (str) { if (!utility.isString(str)) { return ''; } var s = str.replace(rx1, function (c) { var cc = c.charCodeAt(0); return String.fromCharCode(0xc0 | cc >> 6, msbmask | cc & b64mask); }); s = s.replace(rx2, function (c) { var cc = c.charCodeAt(0); return String.fromCharCode(0xe0 | cc >> 12, msbmask | cc >> 6 & b64mask, msbmask | cc & b64mask); }); return s; }; }()) }); /*jslint bitwise: false */ /*jslint bitwise: true */ defineProperty(utility, "Utf8decode", { value: (function () { var rx1 = /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g, rx2 = /[\u00c0-\u00df][\u0080-\u00bf]/g, b16mask = 0x0f, b32mask = 0x1f, b64mask = 0x3f; return function (str) { if (!utility.isString(str)) { return ''; } var s = str.replace(rx1, function (c) { return String.fromCharCode(((c.charCodeAt(0) & b16mask) << 12) | ((c.charCodeAt(1) & b64mask) << 6) | (c.charCodeAt(2) & b64mask)); }); s = s.replace(rx2, function (c) { return String.fromCharCode((c.charCodeAt(0) & b32mask) << 6 | c.charCodeAt(1) & b64mask); }); return s; }; }()) }); /*jslint bitwise: false */ defineProperty(utility, "b64CharSet", { value: (function () { var c = [[65, 90], [97, 122], [48, 57], [43, 43], [47, 47]], a = []; c.forEach(function (range) { var i; for (i = range[0]; i <= range[1]; i += 1) { a.push(String.fromCharCode(i)); } }); return a; }()) }); /*jslint bitwise: true */ defineProperty(utility, "btoa", { value: (function () { var pad = [[/(?:)/, ''], [/(\w\w)$/, "=="], [/(\w)$/, "="]], b2aCodex = utility.b64CharSet.slice(), b64mask = 0x3f; return function (str) { var l = str.length, p = pad[l % 3], e = [], i = 0, bits, c; while (i < l) { c = str.slice(i, i += 3); bits = c.charCodeAt(0) << 16 | c.charCodeAt(1) << 8 | c.charCodeAt(2); e.push(utility.b64CharSet[bits >> 18 & b64mask] + b2aCodex[bits >> 12 & b64mask] + b2aCodex[bits >> 6 & b64mask] + b2aCodex[bits & b64mask]); } return e.join('').replace(p[0], p[1]); }; }()) }); /*jslint bitwise: false */ defineProperty(utility, "utf8_to_b64", { value: function (str) { return utility.btoa(utility.Utf8encode(str)); } }); /*jslint bitwise: true */ defineProperty(utility, "atob", { value: (function () { var a2bCodex = {}, b256mask = 0xff, equals = 0x40; utility.b64CharSet.forEach(function (character, index) { a2bCodex[character] = index; }); a2bCodex["="] = 64; return function (str) { var l = str.length, d = [], i = 0, h3, h4, bits, o1, o2, c; while (i < l) { c = str.slice(i, i += 4); h3 = a2bCodex[c.charAt(2)]; h4 = a2bCodex[c.charAt(3)]; bits = a2bCodex[c.charAt(0)] << 18 | a2bCodex[c.charAt(1)] << 12 | h3 << 6 | h4; o1 = bits >>> 16 & b256mask; if (h3 === equals) { d.push(String.fromCharCode(o1)); } else { o2 = bits >>> 8 & b256mask; if (h4 === equals) { d.push(String.fromCharCode(o1, o2)); } else { d.push(String.fromCharCode(o1, o2, bits & b256mask)); } } } return d.join(''); }; }()) }); /*jslint bitwise: false */ defineProperty(utility, "b64_to_utf8", { value: function (str) { return utility.Utf8decode(utility.atob(str)); } }); /////////////////////////// // Mixin functions /////////////////////////// function mixinCommon(obj) { var a = ["ref", "toString", "toLocaleString", "valueOf"]; utility.mixin(obj.prototype, core.Common.prototype, a); } function mixinRelavant(obj, inheritFrom) { var a = ["constructor", "prototype", "hasOwnProperty", "propertyIsEnum", "isPrototypeOf", "valueOf", "toString", "toLocaleString", "callee", "caller", "__defineGetter__", "__lookupGetter__", "__defineSetter__", "__lookupSetter__"]; getOwnPropertyNames(inheritFrom).forEach(function (key) { var src = getOwnPropertyDescriptor(inheritFrom, key); if (a.indexOf(key) < 0) { if (utility.isFunction(src.value)) { defineProperty(obj, key, { value: function () { return inheritFrom[key].apply(this.refersTo, arguments); } }); } else if (utility.isUndefined(src.value) || (utility.isUndefined(src.get) && !utility.isUndefined(src.set))) { defineProperty(obj, key, { get: function () { return this.refersTo[key]; } }); } else if (utility.isUndefined(src.get) && utility.isUndefined(src.set)) { defineProperty(obj, key, { get: function () { return this.refersTo[key]; }, set: function (val) { this.refersTo[key] = val; } }); } else if (!utility.isUndefined(src.get) && utility.isUndefined(src.set)) { defineProperty(obj, key, { set: function (val) { this.refersTo[key] = val; } }); } else { throw new Error("Did not find any expected property descripter elements in " + key); } } }); } /////////////////////////// // Common /////////////////////////// defineProperty(core, "Common", { value: function UCommon() {} }); defineProperty(core.Common.prototype, "ref", { get: function () { return this.refersTo; } }); defineProperty(core.Common.prototype, "valueOf", { value: function () { if (!utility.isInitialised(this.refersTo)) { return this.refersTo; } return this.refersTo.valueOf(); } }); defineProperty(core.Common.prototype, "toString", { value: function () { if (!utility.isInitialised(this.refersTo)) { return String(this.refersTo); } return this.refersTo.toString(); } }); defineProperty(core.Common.prototype, "toLocaleString", { value: function () { if (!utility.isInitialised(this.refersTo)) { return String(this.refersTo); } return this.refersTo.toLocaleString(); } }); /////////////////////////// // Object /////////////////////////// defineProperty(core, "Object", { value: function UObject() {} }); mixinCommon(core.Object); mixinRelavant(core.Object.prototype, Object.prototype); /////////////////////////// // Array /////////////////////////// defineProperty(core, "Array", { value: function UArray() {} }); mixinCommon(core.Array); mixinRelavant(core.Array.prototype, Array.prototype); /////////////////////////// // function /////////////////////////// defineProperty(core, "Function", { value: function UFunction() {} }); mixinCommon(core.Function); mixinRelavant(core.Function.prototype, Function.prototype); /////////////////////////// // String /////////////////////////// defineProperty(core, "String", { value: function UString() {} }); mixinCommon(core.String); mixinRelavant(core.String.prototype, String.prototype); /////////////////////////// // Number /////////////////////////// defineProperty(core, "Number", { value: function UNumber() {} }); mixinCommon(core.Number); mixinRelavant(core.Number.prototype, Number.prototype); /////////////////////////// // Date /////////////////////////// defineProperty(core, "Date", { value: function UDate() {} }); mixinCommon(core.Date); mixinRelavant(core.Date.prototype, Date.prototype); /////////////////////////// // RegExp /////////////////////////// defineProperty(core, "RegExp", { value: function URegExp() {} }); mixinCommon(core.RegExp); mixinRelavant(core.RegExp.prototype, RegExp.prototype); /////////////////////////// // Arguments /////////////////////////// defineProperty(core, "Arguments", { value: function UArguments() {} }); mixinCommon(core.Arguments); mixinRelavant(core.Arguments.prototype, arguments); /////////////////////////// // Error /////////////////////////// defineProperty(core, "Error", { value: function UError() {} }); mixinCommon(core.Error); mixinRelavant(core.Error.prototype, Error.prototype); /////////////////////////// // Boolean /////////////////////////// defineProperty(core, "Boolean", { value: function UBoolean() {} }); mixinCommon(core.Boolean); mixinRelavant(core.Boolean.prototype, Boolean.prototype); /////////////////////////// // Expose /////////////////////////// window.$u = utility; }()); </script>
/** * * Base64 encode / decode * http://www.webtoolkit.info/ * **/ Base64 = { // private property _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", // public method for encoding encode: function(input) { var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; input = Base64._utf8_encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); } return output; }, // public method for decoding decode: function(input) { var output = ""; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0; input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); while (i < input.length) { enc1 = this._keyStr.indexOf(input.charAt(i++)); enc2 = this._keyStr.indexOf(input.charAt(i++)); enc3 = this._keyStr.indexOf(input.charAt(i++)); enc4 = this._keyStr.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output = output + String.fromCharCode(chr1); if (enc3 != 64) { output = output + String.fromCharCode(chr2); } if (enc4 != 64) { output = output + String.fromCharCode(chr3); } } output = Base64._utf8_decode(output); return output; }, // private method for UTF-8 encoding _utf8_encode: function(string) { string = string.replace(/\r\n/g, "\n"); var utftext = ""; for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if ((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return utftext; }, // private method for UTF-8 decoding _utf8_decode: function(utftext) { var string = ""; var i = 0; var c = c1 = c2 = 0; while (i < utftext.length) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if ((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i + 1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i + 1); c3 = utftext.charCodeAt(i + 2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return string; } } chr = function(code) { return String.fromCharCode(code); }; //returns utf8 encoded charachter of a unicode value. //code must be a number indicating the Unicode value. //returned value is a string between 1 and 4 charachters. code2utf = function(code) { if (code < 128) return chr(code); if (code < 2048) return chr(192 + (code >> 6)) + chr(128 + (code & 63)); if (code < 65536) return chr(224 + (code >> 12)) + chr(128 + ((code >> 6) & 63)) + chr(128 + (code & 63)); if (code < 2097152) return chr(240 + (code >> 18)) + chr(128 + ((code >> 12) & 63)) + chr(128 + ((code >> 6) & 63)) + chr(128 + (code & 63)); }; //it is a private function for internal use in utf8Encode function _utf8Encode = function(str) { var utf8str = new Array(); for (var i = 0; i < str.length; i++) { utf8str[i] = code2utf(str.charCodeAt(i)); } return utf8str.join(''); }; //Encodes a unicode string to UTF8 format. utf8Encode = function(str) { var utf8str = new Array(); var pos, j = 0; var tmpStr = ''; while ((pos = str.search(/[^\x00-\x7F]/)) != -1) { tmpStr = str.match(/([^\x00-\x7F]+[\x00-\x7F]{0,10})+/)[0]; utf8str[j++] = str.substr(0, pos); utf8str[j++] = _utf8Encode(tmpStr); str = str.substr(pos + tmpStr.length); } utf8str[j++] = str; return utf8str.join(''); }; function encodeBase64(str) { var chr1, chr2, chr3, rez = '', arr = [], i = 0, j = 0, code = 0; var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''); while (code = str.charCodeAt(j++)) { if (code < 128) { arr[arr.length] = code; } else if (code < 2048) { arr[arr.length] = 192 | (code >> 6); arr[arr.length] = 128 | (code & 63); } else if (code < 65536) { arr[arr.length] = 224 | (code >> 12); arr[arr.length] = 128 | ((code >> 6) & 63); arr[arr.length] = 128 | (code & 63); } else { arr[arr.length] = 240 | (code >> 18); arr[arr.length] = 128 | ((code >> 12) & 63); arr[arr.length] = 128 | ((code >> 6) & 63); arr[arr.length] = 128 | (code & 63); } }; while (i < arr.length) { chr1 = arr[i++]; chr2 = arr[i++]; chr3 = arr[i++]; rez += chars[chr1 >> 2]; rez += chars[((chr1 & 3) << 4) | (chr2 >> 4)]; rez += chars[chr2 === undefined ? 64 : ((chr2 & 15) << 2) | (chr3 >> 6)]; rez += chars[chr3 === undefined ? 64 : chr3 & 63]; }; return rez; }; // based on Kevin van Zonneveld (http://kevin.vanzonneveld.net), original by Webtoolkit.info (http://www.webtoolkit.info/) // improved by: sowberry, Yves Sucaet, kirilloid // bugfixed by: Onno Marsman, Onno Marsman, Ulrich, Rafal Kukawski // tweaked by: Jack function utf8_encode(a) { var d = 0, b = 0, c = "", f, e; if (null === a || "undefined" === typeof a) { return "" } a += ""; f = a.length; for (var g = 0; g < f; g++) { e = a.charCodeAt(g), crt_encode = null, 128 > e ? d++ : crt_encode = 127 < e && 2048 > e ? String.fromCharCode(e >> 6 | 192, e & 63 | 128) : String.fromCharCode(e >> 12 | 224, e >> 6 & 63 | 128, e & 63 | 128), null !== crt_encode && (d > b && (c += a.slice(b, d)), c += crt_encode, b = d = g + 1) } d > b && (c += a.slice(b, f)); return c } // based on http://www.webtoolkit.info/ function base64_encode(a) { var d = "", b, c, f, e, g, h, j = 0, k; a = utf8_encode(a); for (k = a.length; j < k;) { b = a.charCodeAt(j++), c = a.charCodeAt(j++), f = a.charCodeAt(j++), e = b >> 2, b = (b & 3) << 4 | c >> 4, g = (c & 15) << 2 | f >> 6, h = f & 63, isNaN(c) ? g = h = 64 : isNaN(f) && (h = 64), d += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(e) + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(b) + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(g) + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(h) } return d } a = ""; for (var i = 0; i < 100; i++) a += "teststring ";

Test cases

Test #1

b = btoa(a);

Test #2

b = Base64.encode(a);

Test #3

b = btoa(Base64._utf8_encode(a));

Test #4

b = btoa(unescape(encodeURIComponent(a)));

Test #5

b = btoa(utf8Encode(a));

Test #6

b = encodeBase64(a);

Test #7

b = btoa(utf8_encode(a));

Test #8

b = base64_encode(utf8_encode(a));

Test #9

b = $u.btoa(a);

Test #10

b = $u.btoa($u.Utf8encode(a));