[Phpfreechat-svn] SF.net SVN: phpfreechat: [1215] trunk
Status: Beta
Brought to you by:
kerphi
|
From: <ke...@us...> - 2007-11-22 16:50:33
|
Revision: 1215
http://phpfreechat.svn.sourceforge.net/phpfreechat/?rev=1215&view=rev
Author: kerphi
Date: 2007-11-22 08:50:37 -0800 (Thu, 22 Nov 2007)
Log Message:
-----------
- Upgrade to prototype 1.6
- Bug fix: whoisbox was broken in IE7
- Window onload event is now handled only by prototype
Modified Paths:
--------------
trunk/data/public/js/md5.js
trunk/data/public/js/pfcclient.js
trunk/data/public/js/pfcgui.js
trunk/data/public/js/pfcresource.js
trunk/data/public/js/prototype.js
trunk/src/phpfreechat.class.php
trunk/themes/default/chat.js.tpl.php
Modified: trunk/data/public/js/md5.js
===================================================================
--- trunk/data/public/js/md5.js 2007-11-22 16:45:25 UTC (rev 1214)
+++ trunk/data/public/js/md5.js 2007-11-22 16:50:37 UTC (rev 1215)
@@ -1,256 +1,327 @@
-/*
- * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
- * Digest Algorithm, as defined in RFC 1321.
- * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for more info.
- */
+/**
+* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
+* Digest Algorithm, as defined in RFC 1321.
+*
+* Extends string prototype with the following method:
+* md5
+*
+* This extensions doesn't depend on any other code or overwrite existing methods.
+*
+*
+* The Initial Developer of the Original Code is
+* Paul Johnston
+* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
+* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+*
+* Distributed under the BSD License
+* See http://pajhome.org.uk/crypt/md5 for more info.
+*
+*
+* Contributor(s):
+* Harald Hanek <har...@gm...>
+*
+* Copyright (c) 2007 Harald Hanek (http://js-methods.googlecode.com)
+*
+* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
+* and GPL (http://www.gnu.org/licenses/gpl.html) licenses.
+*
+* @author Harald Hanek
+* @version 0.9
+* @lastchangeddate 10. October 2007 18:01:32
+* @revision 876
+*/
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
-var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
-var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
+(function(){
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
-function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
-function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
-function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
-function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
-function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
+ var md5 =
+ {
+ hexcase : 0, /* hex output format. 0 - lowercase; 1 - uppercase */
+ b64pad : "", /* base-64 pad character. "=" for strict RFC compliance */
+ chrsz : 8, /* bits per input character. 8 - ASCII; 16 - Unicode */
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function md5_vm_test()
-{
- return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
-}
+ /**
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+ 'hex_md5' : function(s)
+ {
+ return this.binl2hex(this.core_md5(this.str2binl(s), s.length * this.chrsz));
+ },
+
+ 'b64_md5' : function(s)
+ {
+ return this.binl2b64(this.core_md5(this.str2binl(s), s.length * this.chrsz));
+ },
+
+ 'str_md5' : function(s)
+ {
+ return this.binl2str(this.core_md5(this.str2binl(s), s.length * this.chrsz));
+ },
+
+ 'hex_hmac_md5' : function(key, data)
+ {
+ return this.binl2hex(this.core_hmac_md5(key, data));
+ },
+
+ 'b64_hmac_md5' : function(key, data)
+ {
+ return this.binl2b64(this.core_hmac_md5(key, data));
+ },
+
+ 'str_hmac_md5' : function(key, data)
+ {
+ return this.binl2str(this.core_hmac_md5(key, data));
+ },
+
+ /**
+ * Calculate the MD5 of an array of little-endian words, and a bit length.
+ *
+ */
+ 'core_md5' : function(x, len)
+ {
+ x[len >> 5] |= 0x80 << ((len) % 32);
+ x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+ var a = 1732584193;
+ var b = -271733879;
+ var c = -1732584194;
+ var d = 271733878;
+
+ for(var i = 0; i < x.length; i += 16)
+ {
+ var olda = a;
+ var oldb = b;
+ var oldc = c;
+ var oldd = d;
+
+ a = this.md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
+ d = this.md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
+ c = this.md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
+ b = this.md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
+ a = this.md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
+ d = this.md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
+ c = this.md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
+ b = this.md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
+ a = this.md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
+ d = this.md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
+ c = this.md5_ff(c, d, a, b, x[i+10], 17, -42063);
+ b = this.md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
+ a = this.md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
+ d = this.md5_ff(d, a, b, c, x[i+13], 12, -40341101);
+ c = this.md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
+ b = this.md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
+
+ a = this.md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
+ d = this.md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
+ c = this.md5_gg(c, d, a, b, x[i+11], 14, 643717713);
+ b = this.md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
+ a = this.md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
+ d = this.md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
+ c = this.md5_gg(c, d, a, b, x[i+15], 14, -660478335);
+ b = this.md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
+ a = this.md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
+ d = this.md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
+ c = this.md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
+ b = this.md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
+ a = this.md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
+ d = this.md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
+ c = this.md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
+ b = this.md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
+
+ a = this.md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
+ d = this.md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
+ c = this.md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
+ b = this.md5_hh(b, c, d, a, x[i+14], 23, -35309556);
+ a = this.md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
+ d = this.md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
+ c = this.md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
+ b = this.md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
+ a = this.md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
+ d = this.md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
+ c = this.md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
+ b = this.md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
+ a = this.md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
+ d = this.md5_hh(d, a, b, c, x[i+12], 11, -421815835);
+ c = this.md5_hh(c, d, a, b, x[i+15], 16, 530742520);
+ b = this.md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
+
+ a = this.md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
+ d = this.md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
+ c = this.md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
+ b = this.md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
+ a = this.md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
+ d = this.md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
+ c = this.md5_ii(c, d, a, b, x[i+10], 15, -1051523);
+ b = this.md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
+ a = this.md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
+ d = this.md5_ii(d, a, b, c, x[i+15], 10, -30611744);
+ c = this.md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
+ b = this.md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
+ a = this.md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
+ d = this.md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
+ c = this.md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
+ b = this.md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
+
+ a = this.safe_add(a, olda);
+ b = this.safe_add(b, oldb);
+ c = this.safe_add(c, oldc);
+ d = this.safe_add(d, oldd);
+ }
+ return Array(a, b, c, d);
+ },
-/*
- * Calculate the MD5 of an array of little-endian words, and a bit length
- */
-function core_md5(x, len)
-{
- /* append padding */
- x[len >> 5] |= 0x80 << ((len) % 32);
- x[(((len + 64) >>> 9) << 4) + 14] = len;
+ /**
+ * These functions implement the four basic operations the algorithm uses.
+ *
+ */
+ 'md5_cmn' : function(q, a, b, x, s, t)
+ {
+ return this.safe_add(this.bit_rol(this.safe_add(this.safe_add(a, q), this.safe_add(x, t)), s),b);
+ },
+
+ 'md5_ff' : function(a, b, c, d, x, s, t)
+ {
+ return this.md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
+ },
+
+ 'md5_gg' : function(a, b, c, d, x, s, t)
+ {
+ return this.md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
+ },
+
+ 'md5_hh' : function(a, b, c, d, x, s, t)
+ {
+ return this.md5_cmn(b ^ c ^ d, a, b, x, s, t);
+ },
+
+ 'md5_ii' : function(a, b, c, d, x, s, t)
+ {
+ return this.md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
+ },
- var a = 1732584193;
- var b = -271733879;
- var c = -1732584194;
- var d = 271733878;
+ /**
+ * Calculate the HMAC-MD5, of a key and some data.
+ *
+ */
+ 'core_hmac_md5' : function(key, data)
+ {
+ var bkey = this.str2binl(key);
+ if(bkey.length > 16)
+ bkey = this.core_md5(bkey, key.length * this.chrsz);
+
+ var ipad = Array(16), opad = Array(16);
+ for(var i = 0; i < 16; i++)
+ {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5C5C5C5C;
+ }
+
+ var hash = this.core_md5(ipad.concat(this.str2binl(data)), 512 + data.length * this.chrsz);
+ return this.core_md5(opad.concat(hash), 512 + 128);
+ },
- for(var i = 0; i < x.length; i += 16)
- {
- var olda = a;
- var oldb = b;
- var oldc = c;
- var oldd = d;
- a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
- d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
- c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
- b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
- a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
- d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
- c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
- b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
- a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
- d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
- c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
- b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
- a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
- d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
- c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
- b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
+ /**
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ *
+ */
+ 'safe_add' : function(x, y)
+ {
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+ },
+
+ /**
+ * Bitwise rotate a 32-bit number to the left.
+ *
+ */
+ 'bit_rol' : function(num, cnt)
+ {
+ return (num << cnt) | (num >>> (32 - cnt));
+ },
+
+ /**
+ * Convert a string to an array of little-endian words.
+ * If this.chrsz is ASCII, characters >255 have their hi-byte silently ignored.
+ *
+ */
+ 'str2binl' : function(str)
+ {
+ var bin = Array();
+ var mask = (1 << this.chrsz) - 1;
+ for(var i = 0; i < str.length * this.chrsz; i += this.chrsz)
+ bin[i>>5] |= (str.charCodeAt(i / this.chrsz) & mask) << (i%32);
+ return bin;
+ },
+
+ /**
+ * Convert an array of little-endian words to a string
+ *
+ */
+ 'binl2str' : function(bin)
+ {
+ var str = "";
+ var mask = (1 << this.chrsz) - 1;
+ for(var i = 0; i < bin.length * 32; i += this.chrsz)
+ str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
+ return str;
+ },
+
+ /**
+ * Convert an array of little-endian words to a hex string.
+ *
+ */
+ 'binl2hex' : function(binarray)
+ {
+ var hex_tab = this.hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+ var str = "";
+ for(var i = 0; i < binarray.length * 4; i++)
+ {
+ str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
+ hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
+ }
+ return str;
+ },
+
+ /**
+ * Convert an array of little-endian words to a base-64 string
+ *
+ */
+ 'binl2b64' : function(binarray)
+ {
+ var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var str = "";
+ for(var i = 0; i < binarray.length * 4; i += 3)
+ {
+ var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)
+ | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
+ | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
+ for(var j = 0; j < 4; j++)
+ {
+ if(i * 8 + j * 6 > binarray.length * 32)
+ str += this.b64pad;
+ else
+ str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
+ }
+ }
+ return str;
+ }
+ };
- a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
- d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
- c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
- b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
- a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
- d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
- c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
- b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
- a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
- d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
- c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
- b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
- a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
- d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
- c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
- b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
-
- a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
- d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
- c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
- b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
- a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
- d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
- c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
- b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
- a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
- d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
- c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
- b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
- a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
- d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
- c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
- b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
-
- a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
- d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
- c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
- b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
- a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
- d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
- c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
- b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
- a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
- d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
- c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
- b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
- a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
- d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
- c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
- b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
-
- a = safe_add(a, olda);
- b = safe_add(b, oldb);
- c = safe_add(c, oldc);
- d = safe_add(d, oldd);
- }
- return Array(a, b, c, d);
-
-}
-
-/*
- * These functions implement the four basic operations the algorithm uses.
- */
-function md5_cmn(q, a, b, x, s, t)
-{
- return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
-}
-function md5_ff(a, b, c, d, x, s, t)
-{
- return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
-}
-function md5_gg(a, b, c, d, x, s, t)
-{
- return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
-}
-function md5_hh(a, b, c, d, x, s, t)
-{
- return md5_cmn(b ^ c ^ d, a, b, x, s, t);
-}
-function md5_ii(a, b, c, d, x, s, t)
-{
- return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
-}
-
-/*
- * Calculate the HMAC-MD5, of a key and some data
- */
-function core_hmac_md5(key, data)
-{
- var bkey = str2binl(key);
- if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
-
- var ipad = Array(16), opad = Array(16);
- for(var i = 0; i < 16; i++)
- {
- ipad[i] = bkey[i] ^ 0x36363636;
- opad[i] = bkey[i] ^ 0x5C5C5C5C;
- }
-
- var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
- return core_md5(opad.concat(hash), 512 + 128);
-}
-
-/*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
-function safe_add(x, y)
-{
- var lsw = (x & 0xFFFF) + (y & 0xFFFF);
- var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
- return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/*
- * Bitwise rotate a 32-bit number to the left.
- */
-function bit_rol(num, cnt)
-{
- return (num << cnt) | (num >>> (32 - cnt));
-}
-
-/*
- * Convert a string to an array of little-endian words
- * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
- */
-function str2binl(str)
-{
- var bin = Array();
- var mask = (1 << chrsz) - 1;
- for(var i = 0; i < str.length * chrsz; i += chrsz)
- bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
- return bin;
-}
-
-/*
- * Convert an array of little-endian words to a string
- */
-function binl2str(bin)
-{
- var str = "";
- var mask = (1 << chrsz) - 1;
- for(var i = 0; i < bin.length * 32; i += chrsz)
- str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
- return str;
-}
-
-/*
- * Convert an array of little-endian words to a hex string.
- */
-function binl2hex(binarray)
-{
- var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
- var str = "";
- for(var i = 0; i < binarray.length * 4; i++)
- {
- str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
- hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
- }
- return str;
-}
-
-/*
- * Convert an array of little-endian words to a base-64 string
- */
-function binl2b64(binarray)
-{
- var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- var str = "";
- for(var i = 0; i < binarray.length * 4; i += 3)
- {
- var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)
- | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
- | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
- for(var j = 0; j < 4; j++)
- {
- if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
- else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
- }
- }
- return str;
-}
+ /**
+ * Returns the md5 hash of the given string.
+ *
+ * @example "JavaScript".md5();
+ * @result "686155af75a60a0f6e9d80c1f7edd3e9"
+ *
+ * @name md5
+ * @return String
+ */
+ if(!String.prototype.md5)
+ String.prototype.md5 = function()
+ {
+ return md5.hex_md5(this);
+ }
+})();
\ No newline at end of file
Modified: trunk/data/public/js/pfcclient.js
===================================================================
--- trunk/data/public/js/pfcclient.js 2007-11-22 16:45:25 UTC (rev 1214)
+++ trunk/data/public/js/pfcclient.js 2007-11-22 16:50:37 UTC (rev 1215)
@@ -62,6 +62,16 @@
this.blinktimeout = Array();
},
+ loadChat: function() {
+ new Ajax.Request(pfc_server_script_url, {
+ method: 'get',
+ parameters: {pfc_ajax: 1, f: 'loadChat'},
+ onSuccess: function(transport) {
+ eval( transport.responseText );
+ }
+ });
+ },
+
connectListener: function()
{
this.el_words = $('pfc_words');
@@ -170,8 +180,8 @@
if (cmd == "who" || cmd == "who2")
{
param2 = $H(param2);
- param2['meta'] = $H(param2['meta']);
- param2['meta']['users'] = $H(param2['meta']['users']);
+ param2.set('meta', $H(param2.get('meta')));
+ param2.get('meta').set('users', $H(param2.get('meta').get('users')));
trace('handleResponse: '+cmd + "-"+resp+"-"+param2.inspect());
}
else
@@ -407,7 +417,8 @@
}
else if (cmd == "whois" || cmd == "whois2")
{
- var nickid = param['nickid'];
+ param = $H(param);
+ var nickid = param.get('nickid');
if (resp == "ok")
{
this.setUserMeta(nickid, param);
@@ -423,7 +434,7 @@
for (var i=0; i<um_keys.length; i++)
{
var k = um_keys[i];
- var v = um[k];
+ var v = um.get(k);
if (v &&
// these parameter are used internaly (don't display it)
k != 'nickid' &&
@@ -437,18 +448,19 @@
}
else if (cmd == "who" || cmd == "who2")
{
- var chan = param['chan'];
- var chanid = param['chanid'];
- var meta = $H(param['meta']);
- meta['users'] = $H(meta['users']);
+ param = $H(param);
+ var chan = param.get('chan');
+ var chanid = param.get('chanid');
+ var meta = $H(param.get('meta'));
+ meta.set('users', $H(meta.get('users')));
if (resp == "ok")
{
this.setChanMeta(chanid,meta);
// send /whois commands for unknown users
- for (var i=0; i<meta['users']['nickid'].length; i++)
+ for (var i=0; i<meta.get('users').get('nickid').length; i++)
{
- var nickid = meta['users']['nickid'][i];
- var nick = meta['users']['nick'][i];
+ var nickid = meta.get('users').get('nickid')[i];
+ var nick = meta.get('users').get('nick')[i];
var um = this.getAllUserMeta(nickid);
if (!um) this.sendRequest('/whois2 "'+nickid+'"');
}
@@ -490,16 +502,16 @@
getAllUserMeta: function(nickid)
{
- if (nickid && this.usermeta[nickid])
- return this.usermeta[nickid];
+ if (nickid && this.usermeta.get(nickid))
+ return this.usermeta.get(nickid);
else
return null;
},
getUserMeta: function(nickid, key)
{
- if (nickid && key && this.usermeta[nickid] && this.usermeta[nickid][key])
- return this.usermeta[nickid][key];
+ if (nickid && key && this.usermeta.get(nickid) && this.usermeta.get(nickid).get(key))
+ return this.usermeta.get(nickid).get(key);
else
return '';
},
@@ -508,26 +520,26 @@
{
if (nickid && key)
{
- if (!this.usermeta[nickid]) this.usermeta[nickid] = $H();
+ if (!this.usermeta.get(nickid)) this.usermeta.set(nickid, $H());
if (value)
- this.usermeta[nickid][key] = value;
+ this.usermeta.get(nickid).set(key, value);
else
- this.usermeta[nickid] = $H(key);
+ this.usermeta.set(nickid, $H(key));
}
},
getAllChanMeta: function(chanid)
{
- if (chanid && this.chanmeta[chanid])
- return this.chanmeta[chanid];
+ if (chanid && this.chanmeta.get(chanid))
+ return this.chanmeta.get(chanid);
else
return null;
},
getChanMeta: function(chanid, key)
{
- if (chanid && key && this.chanmeta[chanid] && this.chanmeta[chanid][key])
- return this.chanmeta[chanid][key];
+ if (chanid && key && this.chanmeta.get(chanid) && this.chanmeta.get(chanid).get(key))
+ return this.chanmeta.get(chanid).get(key);
else
return '';
},
@@ -536,11 +548,11 @@
{
if (chanid && key)
{
- if (!this.chanmeta[chanid]) this.chanmeta[chanid] = $H();
+ if (!this.chanmeta.get(chanid)) this.chanmeta.set(chanid, $H());
if (value)
- this.chanmeta[chanid][key] = value;
+ this.chanmeta.get(chanid).set(key,value);
else
- this.chanmeta[chanid] = $H(key);
+ this.chanmeta.set(chanid, $H(key));
}
},
@@ -909,9 +921,8 @@
var msg_html = $H();
var max_msgid = $H();
- //alert(cmds.inspect());
+//alert(cmds.inspect());
- // var html = '';
for(var mid = 0; mid < cmds.length ; mid++)
{
var id = cmds[mid][0];
@@ -923,7 +934,7 @@
var param = cmds[mid][6];
var fromtoday = cmds[mid][7];
var oldmsg = cmds[mid][8];
-
+
// format and post message
var line = '';
line += '<div id="pfc_msg_'+recipientid+'_'+id+'" class="pfc_cmd_'+ cmd +' pfc_message';
@@ -940,7 +951,7 @@
line += '‹';
line += '<span ';
line += 'onclick="pfc.insert_text(\'' + sender.replace("'", '\\\'') + ', \',\'\',false)" ';
- line += 'class="pfc_nickmarker pfc_nick_'+ hex_md5(_to_utf8(sender)) +'">';
+ line += 'class="pfc_nickmarker pfc_nick_'+ _to_utf8(sender).md5() +'">';
line += sender;
line += '</span>';
line += '›';
@@ -965,14 +976,14 @@
this.gui.notifyWindow();
}
- if (msg_html[recipientid] == null)
- msg_html[recipientid] = line;
+ if (msg_html.get(recipientid) == null)
+ msg_html.set(recipientid, line);
else
- msg_html[recipientid] += line;
-
+ msg_html.set(recipientid, msg_html.get(recipientid) + line);
+
// remember the max message id in order to clean old lines
- if (!max_msgid[recipientid]) max_msgid[recipientid] = 0;
- if (max_msgid[recipientid] < id) max_msgid[recipientid] = id;
+ if (!max_msgid.get(recipientid)) max_msgid.set(recipientid, 0);
+ if (max_msgid.get(recipientid) < id) max_msgid.set(recipientid, id);
}
// loop on all recipients and post messages
@@ -981,13 +992,12 @@
{
var recipientid = keys[i];
var tabid = recipientid;
-
// create the tab if it doesn't exists yet
var recipientdiv = this.gui.getChatContentFromTabId(tabid);
-
+
// create a dummy div to avoid konqueror bug when setting nickmarkers
var m = document.createElement('div'); // do not setup a inline element (ex: span) because the element height will be wrong on FF2 -> scrollDown(..) will be broken
- m.innerHTML = msg_html[recipientid];
+ m.innerHTML = msg_html.get(recipientid);
this.colorizeNicks(m);
this.refresh_clock(m);
// finaly append this to the message list
@@ -995,7 +1005,7 @@
this.gui.scrollDown(tabid, m);
// delete the old messages from the client (save some memory)
- var limit_msgid = max_msgid[recipientid] - pfc_max_displayed_lines;
+ var limit_msgid = max_msgid.get(recipientid) - pfc_max_displayed_lines;
var elt = $('pfc_msg_'+recipientid+'_'+limit_msgid);
while (elt)
{
@@ -1009,8 +1019,7 @@
limit_msgid--;
elt = $('pfc_msg_'+recipientid+'_'+limit_msgid);
}
- }
-
+ }
},
/**
@@ -1039,13 +1048,9 @@
// send the real ajax request
var url = pfc_server_script_url;
- var params = $H();
- params['pfc_ajax'] = 1;
- params['f'] = 'handleRequest';
- params['cmd'] = cmd;
new Ajax.Request(url, {
method: 'post',
- parameters: params,
+ parameters: {'pfc_ajax':1, 'f':'handleRequest', 'cmd': cmd },
onCreate: function(transport) {
this.pfc_ajax_connected = true;
// request time counter used by ping indicator
@@ -1221,7 +1226,7 @@
{
var className = (! is_ie) ? 'class' : 'className';
- var nickidlst = this.getChanMeta(chanid,'users')['nickid'];
+ var nickidlst = this.getChanMeta(chanid,'users').get('nickid');
var nickdiv = this.gui.getOnlineContentFromTabId(chanid);
var ul = document.createElement('ul');
ul.setAttribute(className, 'pfc_nicklist');
@@ -1242,9 +1247,9 @@
getNickWhoisBox: function(nickid)
{
- if (!this.nickwhoisbox[nickid])
+ if (!this.nickwhoisbox.get(nickid))
this.updateNickWhoisBox(nickid);
- return this.nickwhoisbox[nickid];
+ return this.nickwhoisbox.get(nickid);
},
updateNickWhoisBox: function(nickid)
@@ -1252,7 +1257,6 @@
var className = (! is_ie) ? 'class' : 'className';
var usermeta = this.getAllUserMeta(nickid);
-
var div = document.createElement('div');
div.setAttribute(className, 'pfc_nickwhois');
@@ -1271,7 +1275,7 @@
img.setAttribute('src', this.res.getFileUrl('images/close-whoisbox.gif'));
img.alt = this.res.getLabel('Close');
p.appendChild(img);
- p.appendChild(document.createTextNode(usermeta['nick'])); // append the nickname text in the title
+ p.appendChild(document.createTextNode(usermeta.get('nick'))); // append the nickname text in the title
// add the whois information table
var table = document.createElement('table');
@@ -1282,7 +1286,7 @@
for (var i=0; i<um_keys.length; i++)
{
var k = um_keys[i];
- var v = usermeta[k];
+ var v = usermeta.get(k);
if (v && k != 'nickid'
&& k != 'nick' // useless because it is displayed in the box title
&& k != 'isadmin' // useless because of the gold shield icon
@@ -1292,12 +1296,12 @@
)
{
var tr = document.createElement('tr');
- if (nickmeta_key_to_hide.indexOf(k) != -1)
+ if (pfc_nickmeta_key_to_hide.indexOf(k) != -1)
{
var td2 = document.createElement('td');
td2.setAttribute(className, 'pfc_nickwhois_c2');
td2.setAttribute('colspan', 2);
- td2.update(v);
+ td2.innerHTML = v;
tr.appendChild(td2);
}
else
@@ -1306,8 +1310,8 @@
td1.setAttribute(className, 'pfc_nickwhois_c1');
var td2 = document.createElement('td');
td2.setAttribute(className, 'pfc_nickwhois_c2');
- td1.update(k);
- td2.update(v);
+ td1.innerHTML = k;
+ td2.innerHTML = v;
tr.appendChild(td1);
tr.appendChild(td2);
}
@@ -1340,7 +1344,7 @@
div.appendChild(p);
}
- this.nickwhoisbox[nickid] = div;
+ this.nickwhoisbox.set(nickid, div);
},
buildNickItem: function(nickid)
@@ -1502,13 +1506,12 @@
// We don't want to replace smiley strings inside of tags.
// Use negative lookahead to search for end of tag.
rx = new RegExp(RegExp.escape(sl[i]) + '(?![^<]*>)','g');
- msg = msg.replace(rx, '<img src="'+ smileys[sl[i]] +'" alt="' + sl[i] + '" title="' + sl[i] + '" />');
+ msg = msg.replace(rx, '<img src="'+ smileys.get(sl[i]) +'" alt="' + sl[i] + '" title="' + sl[i] + '" />');
}
-
+
// try to parse nickname for highlighting
rx = new RegExp('(^|[ :,;])'+RegExp.escape(this.nickname)+'([ :,;]|$)','gi');
msg = msg.replace(rx, '$1<strong>'+ this.nickname +'</strong>$2');
-
// this piece of code is replaced by the word-wrap CSS3 rule.
/*
@@ -1593,7 +1596,7 @@
applyNickColor: function(root, nick, color)
{
- var nicktochange = this.getElementsByClassName(root, 'pfc_nick_'+ hex_md5(_to_utf8(nick)), '');
+ var nicktochange = this.getElementsByClassName(root, 'pfc_nick_'+ _to_utf8(nick).md5(), '');
for(var i = 0; nicktochange.length > i; i++)
nicktochange[i].style.color = color;
@@ -2070,7 +2073,6 @@
for(var i = 0; i < contentlist.length; i++)
{
var chatdiv = contentlist[i];
- var style = $H();
if (!this.showwhosonline)
{
chatdiv.style.width = '100%';
Modified: trunk/data/public/js/pfcgui.js
===================================================================
--- trunk/data/public/js/pfcgui.js 2007-11-22 16:45:25 UTC (rev 1214)
+++ trunk/data/public/js/pfcgui.js 2007-11-22 16:50:37 UTC (rev 1215)
@@ -36,8 +36,8 @@
if (this.getTabId() != tabid)
{
// no it's not the current active one so just cache the elttoscroll in the famouse this.elttoscroll array
- if (!this.elttoscroll[tabid]) this.elttoscroll[tabid] = Array();
- this.elttoscroll[tabid].push(elttoscroll);
+ if (!this.elttoscroll.get(tabid)) this.elttoscroll.set(tabid, Array());
+ this.elttoscroll.get(tabid).push(elttoscroll);
return;
}
// the wanted tab is active so just scroll down the tab content element
@@ -48,7 +48,7 @@
// http://sourceforge.net/tracker/index.php?func=detail&aid=1568264&group_id=158880&atid=809601
var dudVar = content.scrollTop;
content.scrollTop += elttoscroll.offsetHeight+2;
- this.scrollpos[tabid] = content.scrollTop;
+ this.scrollpos.set(tabid, content.scrollTop);
},
isCreated: function(tabid)
@@ -69,7 +69,7 @@
// first of all save the scroll pos of the visible tab
var content = this.getChatContentFromTabId(this.current_tab_id);
- this.scrollpos[this.current_tab_id] = content.scrollTop;
+ this.scrollpos.set(this.current_tab_id, content.scrollTop);
// start without selected tabs
this.current_tab = '';
@@ -103,17 +103,17 @@
// restore the scroll pos
var content = this.getChatContentFromTabId(tabid);
- content.scrollTop = this.scrollpos[tabid];
+ content.scrollTop = this.scrollpos.get(tabid);
// scroll the new posted message
- if (this.elttoscroll[tabid] &&
- this.elttoscroll[tabid].length > 0)
+ if (this.elttoscroll.get(tabid) &&
+ this.elttoscroll.get(tabid).length > 0)
{
// on by one
- for (var i=0; i<this.elttoscroll[tabid].length; i++)
- this.scrollDown(tabid,this.elttoscroll[tabid][i]);
+ for (var i=0; i<this.elttoscroll.get(tabid).length; i++)
+ this.scrollDown(tabid,this.elttoscroll.get(tabid)[i]);
// empty the cached element list because it has been scrolled
- this.elttoscroll[tabid] = Array();
+ this.elttoscroll.set(tabid, Array());
}
this.unnotifyTab(tabid);
@@ -129,7 +129,7 @@
var className = (! is_ie) ? 'class' : 'className';
// return the chat content if it exists
- var cc = this.chatcontent[tabid];
+ var cc = this.chatcontent.get(tabid);
if (cc) return cc;
// if the chat content doesn't exists yet, just create a cached one
@@ -141,7 +141,7 @@
cc.style.display = "block"; // needed by IE6 to show the online div at startup (first loaded page)
// cc.style.marginLeft = "5px";
- this.chatcontent[tabid] = cc;
+ this.chatcontent.set(tabid,cc);
return cc;
},
getOnlineContentFromTabId: function(tabid)
@@ -149,7 +149,7 @@
var className = (! is_ie) ? 'class' : 'className';
// return the online content if it exists
- var oc = this.onlinecontent[tabid];
+ var oc = this.onlinecontent.get(tabid);
if (oc) return oc;
oc = document.createElement('div');
@@ -160,7 +160,7 @@
// oc.style.borderLeft = "1px solid #555";
oc.style.display = "block"; // needed by IE6 to show the online div at startup (first loaded page)
- this.onlinecontent[tabid] = oc;
+ this.onlinecontent.set(tabid,oc);
return oc;
},
@@ -194,7 +194,7 @@
/*
removeTabByName: function(name)
{
- var tabid = hex_md5(_to_utf8(name));
+ var tabid = _to_utf8(name).md5();
var ret = this.removeTabById(tabid);
if (ret == name)
return tabid;
@@ -214,7 +214,7 @@
// do not create twice a the same tab
if (this.isCreated(tabid)) return;
- // var tabid = hex_md5(_to_utf8(name));
+ // var tabid = _to_utf8(name).md5();
//alert(name+'='+tabid);
this.tabs.push(name);
this.tabids.push(tabid);
@@ -406,7 +406,7 @@
for(var i = 0; i < sl.length; i++)
{
s_url = sl[i];
- s_symbol = smileys[sl[i]];
+ s_symbol = smileys.get(sl[i]);
s_symbol = s_symbol.unescapeHTML();
// Replace " with " for IE and Webkit browsers.
// The prototype.js version 1.5.1.1 unescapeHTML() function does not do this.
Modified: trunk/data/public/js/pfcresource.js
===================================================================
--- trunk/data/public/js/pfcresource.js 2007-11-22 16:45:25 UTC (rev 1214)
+++ trunk/data/public/js/pfcresource.js 2007-11-22 16:50:37 UTC (rev 1215)
@@ -17,15 +17,15 @@
setLabel: function(key, value)
{
- this.labels[key] = value;
+ this.labels.set(key,value);
},
getLabel: function()
{
var key = this.getLabel.arguments[0];
- if (this.labels[key])
+ if (this.labels.get(key))
{
- this.getLabel.arguments[0] = this.labels[key];
+ this.getLabel.arguments[0] = this.labels.get(key);
return String.sprintf2(this.getLabel.arguments);
}
else
@@ -34,27 +34,27 @@
setFileUrl: function(key, value)
{
- this.fileurl[key] = value;
+ this.fileurl.set(key,value);
},
getFileUrl: function(key)
{
- if (this.fileurl[key])
- return this.fileurl[key];
+ if (this.fileurl.get(key))
+ return this.fileurl.get(key);
else
return "";
},
setSmiley: function(key, value)
{
- this.smileys[key] = value;
- this.smileysreverse[value] = key;
+ this.smileys.set(key, value);
+ this.smileysreverse.set(value,key);
this.smileyskeys.push(key);
},
getSmiley: function(key)
{
- if (this.smileys[key])
- return this.smileys[key];
+ if (this.smileys.get(key))
+ return this.smileys.get(key);
else
return "";
},
Modified: trunk/data/public/js/prototype.js
===================================================================
--- trunk/data/public/js/prototype.js 2007-11-22 16:45:25 UTC (rev 1214)
+++ trunk/data/public/js/prototype.js 2007-11-22 16:50:37 UTC (rev 1215)
@@ -1,27 +1,29 @@
-/* Prototype JavaScript framework, version 1.5.1.1
+/* Prototype JavaScript framework, version 1.6.0
* (c) 2005-2007 Sam Stephenson
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://www.prototypejs.org/
*
-/*--------------------------------------------------------------------------*/
+ *--------------------------------------------------------------------------*/
var Prototype = {
- Version: '1.5.1.1',
+ Version: '1.6.0',
Browser: {
IE: !!(window.attachEvent && !window.opera),
Opera: !!window.opera,
WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
- Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
+ Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
+ MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
},
BrowserFeatures: {
XPath: !!document.evaluate,
ElementExtensions: !!window.HTMLElement,
SpecificElementExtensions:
- (document.createElement('div').__proto__ !==
- document.createElement('form').__proto__)
+ document.createElement('div').__proto__ &&
+ document.createElement('div').__proto__ !==
+ document.createElement('form').__proto__
},
ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
@@ -29,24 +31,81 @@
emptyFunction: function() { },
K: function(x) { return x }
-}
+};
+if (Prototype.Browser.MobileSafari)
+ Prototype.BrowserFeatures.SpecificElementExtensions = false;
+
+if (Prototype.Browser.WebKit)
+ Prototype.BrowserFeatures.XPath = false;
+
+/* Based on Alex Arnell's inheritance implementation. */
var Class = {
create: function() {
- return function() {
+ var parent = null, properties = $A(arguments);
+ if (Object.isFunction(properties[0]))
+ parent = properties.shift();
+
+ function klass() {
this.initialize.apply(this, arguments);
}
+
+ Object.extend(klass, Class.Methods);
+ klass.superclass = parent;
+ klass.subclasses = [];
+
+ if (parent) {
+ var subclass = function() { };
+ subclass.prototype = parent.prototype;
+ klass.prototype = new subclass;
+ parent.subclasses.push(klass);
+ }
+
+ for (var i = 0; i < properties.length; i++)
+ klass.addMethods(properties[i]);
+
+ if (!klass.prototype.initialize)
+ klass.prototype.initialize = Prototype.emptyFunction;
+
+ klass.prototype.constructor = klass;
+
+ return klass;
}
-}
+};
-var Abstract = new Object();
+Class.Methods = {
+ addMethods: function(source) {
+ var ancestor = this.superclass && this.superclass.prototype;
+ var properties = Object.keys(source);
+ if (!Object.keys({ toString: true }).length)
+ properties.push("toString", "valueOf");
+
+ for (var i = 0, length = properties.length; i < length; i++) {
+ var property = properties[i], value = source[property];
+ if (ancestor && Object.isFunction(value) &&
+ value.argumentNames().first() == "$super") {
+ var method = value, value = Object.extend((function(m) {
+ return function() { return ancestor[m].apply(this, arguments) };
+ })(property).wrap(method), {
+ valueOf: function() { return method },
+ toString: function() { return method.toString() }
+ });
+ }
+ this.prototype[property] = value;
+ }
+
+ return this;
+ }
+};
+
+var Abstract = { };
+
Object.extend = function(destination, source) {
- for (var property in source) {
+ for (var property in source)
destination[property] = source[property];
- }
return destination;
-}
+};
Object.extend(Object, {
inspect: function(object) {
@@ -62,24 +121,35 @@
toJSON: function(object) {
var type = typeof object;
- switch(type) {
+ switch (type) {
case 'undefined':
case 'function':
case 'unknown': return;
case 'boolean': return object.toString();
}
+
if (object === null) return 'null';
if (object.toJSON) return object.toJSON();
- if (object.ownerDocument === document) return;
+ if (Object.isElement(object)) return;
+
var results = [];
for (var property in object) {
var value = Object.toJSON(object[property]);
if (value !== undefined)
results.push(property.toJSON() + ': ' + value);
}
+
return '{' + results.join(', ') + '}';
},
+ toQueryString: function(object) {
+ return $H(object).toQueryString();
+ },
+
+ toHTML: function(object) {
+ return object && object.toHTML ? object.toHTML() : String.interpret(object);
+ },
+
keys: function(object) {
var keys = [];
for (var property in object)
@@ -95,55 +165,99 @@
},
clone: function(object) {
- return Object.extend({}, object);
+ return Object.extend({ }, object);
+ },
+
+ isElement: function(object) {
+ return object && object.nodeType == 1;
+ },
+
+ isArray: function(object) {
+ return object && object.constructor === Array;
+ },
+
+ isHash: function(object) {
+ return object instanceof Hash;
+ },
+
+ isFunction: function(object) {
+ return typeof object == "function";
+ },
+
+ isString: function(object) {
+ return typeof object == "string";
+ },
+
+ isNumber: function(object) {
+ return typeof object == "number";
+ },
+
+ isUndefined: function(object) {
+ return typeof object == "undefined";
}
});
-Function.prototype.bind = function() {
- var __method = this, args = $A(arguments), object = args.shift();
- return function() {
- return __method.apply(object, args.concat($A(arguments)));
- }
-}
+Object.extend(Function.prototype, {
+ argumentNames: function() {
+ var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
+ return names.length == 1 && !names[0] ? [] : names;
+ },
-Function.prototype.bindAsEventListener = function(object) {
- var __method = this, args = $A(arguments), object = args.shift();
- return function(event) {
- return __method.apply(object, [event || window.event].concat(args));
- }
-}
+ bind: function() {
+ if (arguments.length < 2 && arguments[0] === undefined) return this;
+ var __method = this, args = $A(arguments), object = args.shift();
+ return function() {
+ return __method.apply(object, args.concat($A(arguments)));
+ }
+ },
-Object.extend(Number.prototype, {
- toColorPart: function() {
- return this.toPaddedString(2, 16);
+ bindAsEventListener: function() {
+ var __method = this, args = $A(arguments), object = args.shift();
+ return function(event) {
+ return __method.apply(object, [event || window.event].concat(args));
+ }
},
- succ: function() {
- return this + 1;
+ curry: function() {
+ if (!arguments.length) return this;
+ var __method = this, args = $A(arguments);
+ return function() {
+ return __method.apply(this, args.concat($A(arguments)));
+ }
},
- times: function(iterator) {
- $R(0, this, true).each(iterator);
- return this;
+ delay: function() {
+ var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
+ return window.setTimeout(function() {
+ return __method.apply(__method, args);
+ }, timeout);
},
- toPaddedString: function(length, radix) {
- var string = this.toString(radix || 10);
- return '0'.times(length - string.length) + string;
+ wrap: function(wrapper) {
+ var __method = this;
+ return function() {
+ return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
+ }
},
- toJSON: function() {
- return isFinite(this) ? this.toString() : 'null';
+ methodize: function() {
+ if (this._methodized) return this._methodized;
+ var __method = this;
+ return this._methodized = function() {
+ return __method.apply(null, [this].concat($A(arguments)));
+ };
}
});
+Function.prototype.defer = Function.prototype.delay.curry(0.01);
+
Date.prototype.toJSON = function() {
- return '"' + this.getFullYear() + '-' +
- (this.getMonth() + 1).toPaddedString(2) + '-' +
- this.getDate().toPaddedString(2) + 'T' +
- this.getHours().toPaddedString(2) + ':' +
- this.getMinutes().toPaddedString(2) + ':' +
- this.getSeconds().toPaddedString(2) + '"';
+ return '"' + this.getUTCFullYear() + '-' +
+ (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
+ this.getUTCDate().toPaddedString(2) + 'T' +
+ this.getUTCHours().toPaddedString(2) + ':' +
+ this.getUTCMinutes().toPaddedString(2) + ':' +
+ this.getUTCSeconds().toPaddedString(2) + 'Z"';
};
var Try = {
@@ -155,17 +269,22 @@
try {
returnValue = lambda();
break;
- } catch (e) {}
+ } catch (e) { }
}
return returnValue;
}
-}
+};
+RegExp.prototype.match = RegExp.prototype.test;
+
+RegExp.escape = function(str) {
+ return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
+};
+
/*--------------------------------------------------------------------------*/
-var PeriodicalExecuter = Class.create();
-PeriodicalExecuter.prototype = {
+var PeriodicalExecuter = Class.create({
initialize: function(callback, frequency) {
this.callback = callback;
this.frequency = frequency;
@@ -178,6 +297,10 @@
this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
+ execute: function() {
+ this.callback(this);
+ },
+
stop: function() {
if (!this.timer) return;
clearInterval(this.timer);
@@ -188,13 +311,13 @@
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true;
- this.callback(this);
+ this.execute();
} finally {
this.currentlyExecuting = false;
}
}
}
-}
+});
Object.extend(String, {
interpret: function(value) {
return value == null ? '' : String(value);
@@ -238,14 +361,14 @@
scan: function(pattern, iterator) {
this.gsub(pattern, iterator);
- return this;
+ return String(this);
},
truncate: function(length, truncation) {
length = length || 30;
truncation = truncation === undefined ? '...' : truncation;
return this.length > length ?
- this.slice(0, length - truncation.length) + truncation : this;
+ this.slice(0, length - truncation.length) + truncation : String(this);
},
strip: function() {
@@ -279,7 +402,7 @@
},
unescapeHTML: function() {
- var div = document.createElement('div');
+ var div = new Element('div');
div.innerHTML = this.stripTags();
return div.childNodes[0] ? (div.childNodes.length > 1 ?
$A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
@@ -288,16 +411,16 @@
toQueryParams: function(separator) {
var match = this.strip().match(/([^?#]*)(#.*)?$/);
- if (!match) return {};
+ if (!match) return { };
- return match[1].split(separator || '&').inject({}, function(hash, pair) {
+ return match[1].split(separator || '&').inject({ }, function(hash, pair) {
if ((pair = pair.split('='))[0]) {
var key = decodeURIComponent(pair.shift());
var value = pair.length > 1 ? pair.join('=') : pair[0];
if (value != undefined) value = decodeURIComponent(value);
if (key in hash) {
- if (hash[key].constructor != Array) hash[key] = [hash[key]];
+ if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
hash[key].push(value);
}
else hash[key] = value;
@@ -316,9 +439,7 @@
},
times: function(count) {
- var result = '';
- for (var i = 0; i < count; i++) result += this;
- return result;
+ return count < 1 ? '' : new Array(count + 1).join(this);
},
camelize: function() {
@@ -396,6 +517,10 @@
blank: function() {
return /^\s*$/.test(this);
+ },
+
+ interpolate: function(object, pattern) {
+ return new Template(this, pattern).evaluate(object);
}
});
@@ -409,10 +534,10 @@
});
String.prototype.gsub.prepareReplacement = function(replacement) {
- if (typeof replacement == 'function') return replacement;
+ if (Object.isFunction(replacement)) return replacement;
var template = new Template(replacement);
return function(match) { return template.evaluate(match) };
-}
+};
String.prototype.parseQuery = String.prototype.toQueryParams;
@@ -423,28 +548,46 @@
with (String.prototype.escapeHTML) div.appendChild(text);
-var Template = Class.create();
-Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
-Template.prototype = {
+var Template = Class.create({
initialize: function(template, pattern) {
this.template = template.toString();
- this.pattern = pattern || Template.Pattern;
+ this.pattern = pattern || Template.Pattern;
},
evaluate: function(object) {
+ if (Object.isFunction(object.toTemplateReplacements))
+ object = object.toTemplateReplacements();
+
return this.template.gsub(this.pattern, function(match) {
- var before = match[1];
+ if (object == null) return '';
+
+ var before = match[1] || '';
if (before == '\\') return match[2];
- return before + String.interpret(object[match[3]]);
- });
+
+ var ctx = object, expr = match[3];
+ var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/, match = pattern.exec(expr);
+ if (match == null) return before;
+
+ while (match != null) {
+ var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
+ ctx = ctx[comp];
+ if (null == ctx || '' == match[3]) break;
+ expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
+ match = pattern.exec(expr);
+ }
+
+ return before + String.interpret(ctx);
+ }.bind(this));
}
-}
+});
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
-var $break = {}, $continue = new Error('"throw $continue" is deprecated, use "return" instead');
+var $break = { };
var Enumerable = {
- each: function(iterator) {
+ each: function(iterator, context) {
var index = 0;
+ iterator = iterator.bind(context);
try {
this._each(function(value) {
iterator(value, index++);
@@ -455,40 +598,45 @@
return this;
},
- eachSlice: function(number, iterator) {
+ eachSlice: function(number, iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
var index = -number, slices = [], array = this.toArray();
while ((index += number) < array.length)
slices.push(array.slice(index, index+number));
- return slices.map(iterator);
+ return slices.collect(iterator, context);
},
- all: function(iterator) {
+ all: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
var result = true;
this.each(function(value, index) {
- result = result && !!(iterator || Prototype.K)(value, index);
+ result = result && !!iterator(value, index);
if (!result) throw $break;
});
return result;
},
- any: function(iterator) {
+ any: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
var result = false;
this.each(function(value, index) {
- if (result = !!(iterator || Prototype.K)(value, index))
+ if (result = !!iterator(value, index))
throw $break;
});
return result;
},
- collect: function(iterator) {
+ collect: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
var results = [];
this.each(function(value, index) {
- results.push((iterator || Prototype.K)(value, index));
+ results.push(iterator(value, index));
});
return results;
},
- detect: function(iterator) {
+ detect: function(iterator, context) {
+ iterator = iterator.bind(context);
var result;
this.each(function(value, index) {
if (iterator(value, index)) {
@@ -499,7 +647,8 @@
return result;
},
- findAll: function(iterator) {
+ findAll: function(iterator, context) {
+ iterator = iterator.bind(context);
var results = [];
this.each(function(value, index) {
if (iterator(value, index))
@@ -508,17 +657,24 @@
return results;
},
- grep: function(pattern, iterator) {
+ grep: function(filter, iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
var results = [];
+
+ if (Object.isString(filter))
+ filter = new RegExp(filter);
+
this.each(function(value, index) {
- var stringValue = value.toString();
- if (stringValue.match(pattern))
- results.push((iterator || Prototype.K)(value, index));
- })
+ if (filter.match(value))
+ results.push(iterator(value, index));
+ });
return results;
},
include: function(object) {
+ if (Object.isFunction(this.indexOf))
+ if (this.indexOf(object) != -1) return true;
+
var found = false;
this.each(function(value) {
if (value == object) {
@@ -537,7 +693,8 @@
});
},
- inject: function(memo, iterator) {
+ inject: function(memo, iterator, context) {
+ iterator = iterator.bind(context);
this.each(function(value, index) {
memo = iterator(memo, value, index);
});
@@ -551,30 +708,33 @@
});
},
- max: function(iterator) {
+ max: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
var result;
this.each(function(value, index) {
- value = (iterator || Prototype.K)(value, index);
+ value = iterator(value, index);
if (result == undefined || value >= result)
result = value;
});
return result;
},
- min: function(iterator) {
+ min: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
var result;
this.each(function(value, index) {
- value = (iterator || Prototype.K)(value, index);
+ value = iterator(value, index);
if (result == undefined || value < result)
result = value;
});
return result;
},
- partition: function(iterator) {
+ partition: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
var trues = [], falses = [];
this.each(function(value, index) {
- ((iterator || Prototype.K)(value, index) ?
+ (iterator(value, index) ?
trues : falses).push(value);
});
return [trues, falses];
@@ -582,13 +742,14 @@
pluck: function(property) {
var results = [];
- this.each(function(value, index) {
+ this.each(function(value) {
results.push(value[property]);
});
return results;
},
- reject: function(iterator) {
+ reject: function(iterator, context) {
+ iterator = iterator.bind(context);
var results = [];
this.each(function(value, index) {
if (!iterator(value, index))
@@ -597,7 +758,8 @@
return results;
},
- sortBy: function(iterator) {
+ sortBy: function(iterator, context) {
+ iterator = iterator.bind(context);
return this.map(function(value, index) {
return {value: value, criteria: iterator(value, index)};
}).sort(function(left, right) {
@@ -612,7 +774,7 @@
zip: function() {
var iterator = Prototype.K, args = $A(arguments);
- if (typeof args.last() == 'function')
+ if (Object.isFunction(args.last()))
iterator = args.pop();
var collections = [this].concat(args).map($A);
@@ -628,46 +790,42 @@
inspect: function() {
return '#<Enumerable:' + this.toArray().inspect() + '>';
}
-}
+};
Object.extend(Enumerable, {
map: Enumerable.collect,
find: Enumerable.detect,
select: Enumerable.findAll,
+ filter: Enumerable.findAll,
member: Enumerable.include,
- entries: Enumerable.toArray
+ entries: Enumerable.toArray,
+ every: Enumerable.all,
+ some: Enumerable.any
});
-var $A = Array.from = function(iterable) {
+function $A(iterable) {
if (!iterable) return [];
- if (iterable.toArray) {
- return iterable.toArray();
- } else {
- var results = [];
- for (var i = 0, length = iterable.length; i < length; i++)
- results.push(iterable[i]);
- return results;
- }
+ if (iterable.toArray) return iterable.toArray();
+ var length = iterable.length, results = new Array(length);
+ while (length--) results[length] = iterable[length];
+ return results;
}
if (Prototype.Browser.WebKit) {
- $A = Array.from = function(iterable) {
+ function $A(iterable) {
if (!iterable) return [];
- if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&
- iterable.toArray) {
- return iterable.toArray();
- } else {
- var results = [];
- for (var i = 0, length = iterable.length; i < length; i++)
- results.push(iterable[i]);
- return results;
- }
+ if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
+ iterable.toArray) return iterable.toArray();
+ var length = iterable.length, results = new Array(length);
+ while (length--) results[length] = iterable[length];
+ return results;
}
}
+Array.from = $A;
+
Object.extend(Array.prototype, Enumerable);
-if (!Array.prototype._reverse)
- Array.prototype._reverse = Array.prototype.reverse;
+if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
Object.extend(Array.prototype, {
_each: function(iterator) {
@@ -696,7 +854,7 @@
flatten: function() {
return this.inject([], function(array, value) {
- return array.concat(value && value.constructor == Array ?
+ return array.concat(Object.isArray(value) ?
value.flatten() : [value]);
});
},
@@ -708,12 +866,6 @@
});
},
- indexOf: function(object) {
- for (var i = 0, length = this.length; i < length; i++)
- if (this[i] ==...
[truncated message content] |