b9cb311ea29306281e26d897c687edc7a60177bf
[jquery.git] / jquery / jquery.js
1 /*
2  * jQuery (jquery.com)
3  *
4  * Copyright (c) 2006 John Resig (ejohn.org)
5  * Licensed under the MIT License:
6  *   http://www.opensource.org/licenses/mit-license.php
7  *
8  * $Date$
9  * $Rev$
10  */
11
12 function $(a,c) {
13         var $a = a || $.context || document;
14         var $c = c && c.$jquery && c.get(0) || c;
15         
16         // Since we're using Prototype's $ function,
17         // be nice and have backwards compatability
18         if ( typeof Prototype != "undefined" ) {
19                 if ( $a.constructor == String ) {
20                         var re = new RegExp( "[^a-zA-Z0-9_-]" );
21                         if ( !re.test($a) ) {
22                                 $c = $c && $c.documentElement || document;
23                                 if ( $c.getElementsByTagName($a).length == 0 ) {
24                                         var obj = $c.getElementById($a);
25                                         if ( obj != null ) return obj;
26                                 }
27                         }
28                 } else if ( $a.constructor == Array ) {
29                         return $.map( $a, function(b){
30                                 if ( b.constructor == String )
31                                         return document.getElementById(b);
32                                 return b;
33                         });
34                 }
35         }
36
37         // Load Dynamic Function List
38         var self = {
39                 cur: $.Select($a,$c),
40                 $jquery: "$Rev$",
41                 
42                 // The only two getters
43                 size: function() {return this.get().length},
44                 get: function(i) {
45                         return i == null ? this.cur : this.cur[i];
46                 },
47                 
48                 each: function(f) {
49                         for ( var i = 0; i < this.size(); i++ )
50                                 $.apply( this.get(i), f, [i] );
51                         return this;
52                 },
53                 set: function(a,b) {
54                         return this.each(function(){
55                                 if ( b == null )
56                                         for ( var j in a )
57                                                 $.attr(this,j,a[j]);
58                                 else
59                                         $.attr(this,a,b);
60                         });
61                 },
62                 html: function(h) {
63                         return h == null && this.size() ?
64                                 this.get(0).innerHTML : this.set( "innerHTML", h );
65                 },
66                 val: function(h) {
67                         return h == null && this.size() ?
68                                 this.get(0).value : this.set( "value", h );
69                 },
70                 
71                 css: function(a,b) {
72                         return  a.constructor != String || b ?
73                                 this.each(function(){
74                                         if ( !b )
75                                                 for ( var j in a )
76                                                         $.attr(this.style,j,a[j]);
77                                         else
78                                                 $.attr(this.style,a,b);
79                                 }) : $.css( this.get(0), a );
80                 },
81                 toggle: function() {
82                         return this.each(function(){
83                                 var d = $.getCSS(this,"display");
84                                 if ( d == "none" || d == '' )
85                                         $(this).show();
86                                 else
87                                         $(this).hide();
88                         });
89                 },
90                 show: function(a) {
91                         return this.each(function(){
92                                 this.style.display = this.$$oldblock ? this.$$oldblock : '';
93                                 if ( $.getCSS(this,"display") == "none" ) this.style.display = 'block';
94                         });
95                 },
96                 hide: function(a) {
97                         return this.each(function(){
98                                 this.$$oldblock = $.getCSS(this,"display");
99                                 if ( this.$$oldblock == "none" ) this.$$oldblock = 'block';
100                                 this.style.display = 'none';
101                         });
102                 },
103                 addClass: function(c) {
104                         return this.each(function(){
105                                 if ($.hasWord(this,c)) return;
106                                 this.className += ( this.className.length > 0 ? " " : "" ) + c;
107                         });
108                 },
109                 removeClass: function(c) {
110                         return this.each(function(){
111                                 this.className = c == null ? '' :
112                                         this.className.replace(
113                                                 new RegExp('(^|\\s*\\b[^-])'+c+'($|\\b(?=[^-]))', 'g'), '');
114                         });
115                 },
116                 // TODO: Optomize
117                 toggleClass: function(c) {
118                         return this.each(function(){
119                                 if ($.hasWord(this,c))
120                                         this.className = 
121                                                 this.className.replace(
122                                                         new RegExp('(\\s*\\b[^-])'+c+'($|\\b(?=[^-]))', 'g'), '');
123                                 else
124                                         this.className += ( this.className.length > 0 ? " " : "" ) + c;
125                         });
126                 },
127                 remove: function() {
128                         this.each(function(){this.parentNode.removeChild( this );});
129                         this.cur = [];
130                         return this;
131                 },
132                 
133                 wrap: function() {
134                         var a = $.clean(arguments);
135                         return this.each(function(){
136                                 var b = a[0].cloneNode(true);
137                                 this.parentNode.insertBefore( b, this );
138                                 while ( b.firstChild ) b = b.firstChild;
139                                 b.appendChild( this );
140                         });
141                 },
142                 
143                 append: function() {
144                         var clone = this.size() > 1;
145                         var a = $.clean(arguments);
146                         return this.each(function(){
147                                 for ( var i = 0; i < a.length; i++ )
148                                   this.appendChild( clone ? a[i].cloneNode(true) : a[i] );
149                         });
150                 },
151
152                 appendTo: function() {
153                         var a = arguments;
154                         return this.each(function(){
155                                 for ( var i = 0; i < a.length; i++ )
156                                         $(a[i]).append( this );
157                         });
158                 },
159                 
160                 prepend: function() {
161                         var clone = this.size() > 1;
162                         var a = $.clean(arguments);
163                         return this.each(function(){
164                                 for ( var i = a.length - 1; i >= 0; i-- )
165                                         this.insertBefore( clone ? a[i].cloneNode(true) : a[i], this.firstChild );
166                         });
167                 },
168                 
169                 before: function() {
170                         var clone = this.size() > 1;
171                         var a = $.clean(arguments);
172                         return this.each(function(){
173                                 for ( var i = 0; i < a.length; i++ )
174                                         this.parentNode.insertBefore( clone ? a[i].cloneNode(true) : a[i], this );
175                         });
176                 },
177                 
178                 after: function() {
179                         var clone = this.size() > 1;
180                         var a = $.clean(arguments);
181                         return this.each(function(){
182                                 for ( var i = a.length - 1; i >= 0; i-- )
183                                         this.parentNode.insertBefore( clone ? a[i].cloneNode(true) : a[i], this.nextSibling );
184                         });
185                 },
186
187                 empty: function() {
188                         return this.each(function(){
189                                 while ( this.firstChild )
190                                         this.removeChild( this.firstChild );
191                         });
192                 },
193                 
194                 bind: function(t,f) {
195                         return this.each(function(){addEvent(this,t,f);});
196                 },
197                 unbind: function(t,f) {
198                         return this.each(function(){removeEvent(this,t,f);});
199                 },
200                 trigger: function(t) {
201                         return this.each(function(){triggerEvent(this,t);});
202                 },
203                 
204                 find: function(t) {
205                         var old = [], ret = [];
206                         this.each(function(){
207                                 old[old.length] = this;
208                                 ret = $.merge( ret, $.Select(t,this) );
209                         });
210                         this.old = old;
211                         this.cur = ret;
212                         return this;
213                 },
214                 end: function() {
215                         this.cur = this.old;
216                         return this;
217                 },
218
219                 parent: function(a) {
220                         this.cur = $.map(this.cur,function(d){
221                                 return d.parentNode;
222                         });
223                         if ( a ) this.cur = $.filter(a,this.cur).r;
224                         return this;
225                 },
226                 
227                 parents: function(a) {
228                         this.cur = $.map(this.cur,$.parents);
229                         if ( a ) this.cur = $.filter(a,this.cur).r;
230                         return this;
231                 },
232                 
233                 siblings: function(a) {
234                         // Incorrect, need to exclude current element
235                         this.cur = $.map(this.cur,$.sibling);
236                         if ( a ) this.cur = $.filter(a,this.cur).r;
237                         return this;
238                 },
239                 
240                 filter: function(t) {
241                         this.cur = $.filter(t,this.cur).r;
242                         return this;
243                 },
244                 not: function(t) {
245                         this.cur = t.constructor == String ?
246                                 $.filter(t,this.cur,false).r :
247                                 $.grep(this.cur,function(a){return a != t;});
248                         return this;
249                 },
250                 add: function(t) {
251                         this.cur = $.merge( this.cur, t.constructor == String ?
252                                 $.Select(t) : t.constructor == Array ? t : [t] );
253                         return this;
254                 },
255                 is: function(t) {
256                         return $.filter(t,this.cur).r.length > 0;
257                 },
258                 isNot: function(t) {
259                         return !this.s(t);
260                 }
261         };
262         
263         // TODO: Remove need to return this
264         for ( var i in $.fn ) {
265                 if ( self[i] != null )
266                         self["_"+i] = self[i];
267                 self[i] = $.fn[i];
268         }
269         
270         if ( typeof Prototype != "undefined" && $a.constructor != String ) {
271                 if ( $c ) $a = self.get();
272                 for ( var i in self ) {(function(j){
273                         try {
274                                 if ( $a[j] == null ) {
275                                         $a[j] = function() {
276                                                 return $.apply(self,self[j],arguments);
277                                         };
278                                 }
279                         } catch(e) {}
280                 })(i);}
281                 return $a;
282         }
283         
284         return self;
285 }
286
287 $.apply = function(o,f,a) {
288         a = a || [];
289         if ( f.apply )
290                 return f.apply( o, a );
291         else {
292                 var p = [];
293                 for (var i = 0; i < a.length; i++)
294                         p[i] = 'a['+i+']';
295                 o.$$exec = this;
296                 var r = eval('o.$$exec(' + p.join(',') + ')');
297                 o.$$exec = null;
298                 return r;
299         }
300 };
301
302 $.getCSS = function(e,p) {
303         // Adapted from Prototype 1.4.0
304         if ( p == 'height' || p == 'width' ) {
305                 if ($.getCSS(e,"display") != 'none')
306                         return p == 'height' ?
307                                 e.offsetHeight || parseInt(e.style.height) : 
308                                 e.offsetWidth || parseInt(e.style.width);
309                 var els = e.style;
310                 var ov = els.visibility;
311                 var op = els.position;
312                 var od = els.display;
313                 els.visibility = 'hidden';
314                 els.position = 'absolute';
315                 els.display = '';
316                 var oHeight = e.clientHeight || parseInt(e.style.height);
317                 var oWidth = e.clientWidth || parseInt(e.style.width);
318                 els.display = od;
319                 els.position = op;
320                 els.visibility = ov;
321                 return p == 'height' ? oHeight : oWidth;
322         }
323         
324         if (e.style[p])
325                 return e.style[p];
326         else if (e.currentStyle)
327                 return e.currentStyle[p];
328         else if (document.defaultView && document.defaultView.getComputedStyle) {
329                 p = p.replace(/([A-Z])/g,"-$1");
330                 p = p.toLowerCase();
331                 var s = document.defaultView.getComputedStyle(e,"");
332                 var r = s ? s.getPropertyValue(p) : p;
333                 return r;
334         } else
335                 return null;
336 };
337 $.css = $.getCSS;
338
339 $.clean = function(a) {
340         var r = [];
341         for ( var i = 0; i < a.length; i++ )
342                 if ( a[i].constructor == String ) {
343                         var div = document.createElement("div");
344                         div.innerHTML = a[i];
345                         for ( var j = 0; j < div.childNodes.length; j++ )
346                                 r[r.length] = div.childNodes[j];
347                 } else if ( a[i].length )
348                         for ( var j = 0; j < a[i].length; j++ )
349                                 r[r.length] = a[i][j];
350                 else if ( a[i] != null )
351                         r[r.length] = 
352                                 a[i].nodeType ? a[i] : document.createTextNode(a[i].toString());
353         return r;
354 };
355
356 $.g = {
357         '': "m[2] == '*' || a.nodeName.toUpperCase() == m[2].toUpperCase()",
358         '#': "a.id == m[2]",
359         ':': {
360                 lt: "i < m[3]-0",
361                 gt: "i > m[3]-0",
362                 nth: "m[3] - 0 == i",
363                 eq: "m[3] - 0 == i",
364                 first: "i == 0",
365                 last: "i == r.length - 1",
366                 even: "i % 2 == 0",
367                 odd: "i % 2 == 1",
368                 "first-child": "$.sibling(a,0).cur",
369                 "nth-child": "(m[3] == 'even'?$.sibling(a,m[3]).n % 2 == 0 :(m[3] == 'odd'?$.sibling(a,m[3]).n % 2 == 1:$.sibling(a,m[3]).cur))",
370                 "last-child": "$.sibling(a,0,true).cur",
371                 "nth-last-child": "$.sibling(a,m[3],true).cur",
372                 "first-of-type": "$.ofType(a,0)",
373                 "nth-of-type": "$.ofType(a,m[3])",
374                 "last-of-type": "$.ofType(a,0,true)",
375                 "nth-last-of-type": "$.ofType(a,m[3],true)",
376                 "only-of-type": "$.ofType(a) == 1",
377                 "only-child": "$.sibling(a).length == 1",
378                 parent: "a.childNodes.length > 0",
379                 empty: "a.childNodes.length == 0",
380                 root: "a == ( a.ownerDocument ? a.ownerDocument : document ).documentElement",
381                 contains: "(a.innerText || a.innerHTML).indexOf(m[3]) != -1",
382                 visible: "(!a.type || a.type != 'hidden') && ($.getCSS(a,'display') != 'none' && $.getCSS(a,'visibility') != 'hidden')",
383                 hidden: "(a.type && a.type == 'hidden') || $.getCSS(a,'display') == 'none' || $.getCSS(a,'visibility') == 'hidden'",
384                 enabled: "a.disabled == false",
385                 disabled: "a.disabled",
386                 checked: "a.checked"
387         },
388         // TODO: Write getAttribute helper
389         ".": "$.hasWord(a,m[2])",
390         "@": {
391                 "=": "$.attr(a,m[3]) == m[4]",
392                 "!=": "$.attr(a,m[3]) != m[4]",
393                 "~=": "$.hasWord($.attr(a,m[3]),m[4])",
394                 "|=": "$.attr(a,m[3]).indexOf(m[4]) == 0",
395                 "^=": "$.attr(a,m[3]).indexOf(m[4]) == 0",
396                 "$=": "$.attr(a,m[3]).substr( $.attr(a,m[3]).length - m[4].length, m[4].length ) == m[4]",
397                 "*=": "$.attr(a,m[3]).indexOf(m[4]) >= 0",
398                 "": "m[3] == '*' ? a.attributes.length > 0 : $.attr(a,m[3])"
399         },
400         "[": "$.Select(m[2],a).length > 0"
401 };
402
403 $.fn = {};
404
405 $.Select = function( t, context ) {
406         context = context || $.context || document;
407         if ( t.constructor != String ) return [t];
408         
409         if ( t.indexOf("//") == 0 ) {
410                 context = context.documentElement;
411                 t = t.substr(2,t.length);
412         } else if ( t.indexOf("/") == 0 ) {
413                 context = context.documentElement;
414                 t = t.substr(1,t.length);
415                 // FIX Assume the root element is right :(
416                 if ( t.indexOf('/') )
417                         t = t.substr(t.indexOf('/'),t.length);
418         }
419         
420         var ret = [context];
421         var done = [];
422         var last = null;
423   
424         while ( t.length > 0 && last != t ) {
425             var r = [];
426                         last = t;
427             
428             t = $.cleanSpaces(t);
429             
430             var re = new RegExp( "^//", "i" );
431             t = t.replace( re, "" );
432         
433             if ( t.indexOf('..') == 0 || t.indexOf('/..') == 0 ) {
434                         if ( t.indexOf('/') == 0 )
435                                 t = t.substr(1,t.length);
436                         r = $.map( ret, function(a){ return a.parentNode; } );
437                         t = t.substr(2,t.length);
438                         t = $.cleanSpaces(t);
439             } else if ( t.indexOf('>') == 0 || t.indexOf('/') == 0 ) {
440                         r = $.map( ret, function(a){ return ( a.childNodes.length > 0 ? $.sibling( a.firstChild ) : null ); } );
441                         t = t.substr(1,t.length);
442                         t = $.cleanSpaces(t);
443             } else if ( t.indexOf('+') == 0 ) {
444                         r = $.map( ret, function(a){ return $.sibling(a).next; } );
445                         t = t.substr(1,t.length);
446                         t = $.cleanSpaces(t);
447             } else if ( t.indexOf('~') == 0 ) {
448                         r = $.map( ret, function(a){
449                                 var r = [];
450                                 var s = $.sibling(a);
451                                 if ( s.n > 0 )
452                                         for ( var i = s.n; i < s.length; i++ )
453                                                 r[r.length] = s[i];
454                                         return r;
455                         });
456                         t = t.substr(1,t.length);
457                         t = $.cleanSpaces(t);
458             } else if ( t.indexOf(',') == 0 || t.indexOf('|') == 0 ) {
459                         if ( ret[0] == context ) ret.shift();
460                         done = $.merge( done, ret );
461                         r = ret = [context];
462                         t = " " + t.substr(1,t.length);
463             } else {
464                         var re = new RegExp( "^([#.]?)([a-z0-9\\*_-]*)", "i" );
465                         var m = re.exec(t);
466                                 
467                         if ( m[1] == "#" ) { // Ummm, should make this work in all XML docs
468                                 var oid = document.getElementById(m[2]);
469                                 r = oid ? [oid] : [];
470                                 t = t.replace( re, "" );
471                         } else {
472                                 if ( m[2] == "" || m[1] == "." ) m[2] = "*";
473         
474                                 for ( var i = 0; i < ret.length; i++ ) {
475                                         var o = ret[i];
476                                         if ( o ) {
477                                                 switch( m[2] ) {
478                                                         case '*':
479                                                                 r = $.merge( $.getAll(o), r );
480                                                         break;
481                                                         case 'text': case 'radio': case 'checkbox': case 'hidden':
482                                                         case 'button': case 'submit': case 'image': case 'password':
483                                                         case 'reset': case 'file':
484                                                                 r = $.merge( $.grep( $.tag(o,"input"), 
485                                                                         function(a){ return a.type == m[2] }), r );
486                                                         break;
487                                                         case 'input':
488                                                                 r = $.merge( $.tag(o,"input"), r );
489                                                                 r = $.merge( $.tag(o,"select"), r );
490                                                                 r = $.merge( $.tag(o,"textarea"), r );
491                                                         break;
492                                                         default:
493                                                                 r = $.merge( r, $.tag(o,m[2]) );
494                                                         break;
495                                                 }
496                                         }
497                                 }
498                         }
499                 }
500
501                 var val = $.filter(t,r);
502                 ret = r = val.r;
503                 t = $.cleanSpaces(val.t);
504         }
505
506         if ( ret && ret[0] == context ) ret.shift();
507         done = $.merge( done, ret );
508         return done;
509 };
510
511 $.tag = function(a,b){
512         return a && typeof a.getElementsByTagName != "undefined" ?
513                 a.getElementsByTagName( b ) : [];
514 };
515
516 $.attr = function(o,a,v){
517         if ( a && a.constructor == String ) {
518                 var fix = {
519                         'for': 'htmlFor',
520                         'text': 'cssText',
521                         'class': 'className',
522                         'float': 'cssFloat'
523                 };
524                 a = (fix[a] && fix[a].replace && fix[a]) || a;
525                 var r = new RegExp("-([a-z])","ig");
526                 a = a.replace(r,function(z,b){return b.toUpperCase();});
527                 if ( v != null ) {
528                         o[a] = v;
529                         if ( o.setAttribute ) o.setAttribute(a,v);
530                 } 
531                 return o[a] || o.getAttribute(a) || '';
532         } else return '';
533 };
534
535 $.filter = function(t,r,not) {
536         var g = $.grep;
537         if ( not == false ) var g = function(a,f) {return $.grep(a,f,true);};
538         
539         while ( t.length > 0 && t.match(/^[:\\.#\\[a-zA-Z\\*]/) ) {
540                 var re = new RegExp( "^\\[ *@([a-z0-9\\(\\)_-]+) *([~!\\|\\*$^=]*) *'?\"?([^'\"]*)'?\"? *\\]", "i" );
541                 var m = re.exec(t);
542                 
543                 if ( m != null ) {
544                         m = ['', '@', m[2], m[1], m[3]];
545                 } else {
546                         var re = new RegExp( "^(\\[) *([^\\]]*) *\\]", "i" );
547                         var m = re.exec(t);
548                         
549                         if ( m == null ) {
550                                 var re = new RegExp( "^(:)([a-z0-9\\*_-]*)\\( *[\"']?([^ \\)'\"]*)['\"]? *\\)", "i" );
551                                 var m = re.exec(t);
552                                 
553                                 if ( m == null ) {
554                                         var re = new RegExp( "^([:\\.#]*)([a-z0-9\\*_-]*)", "i" );
555                                         var m = re.exec(t);
556                                 }
557                         }
558                 }
559                 t = t.replace( re, "" );
560                 
561                 if ( m[1] == ":" && m[2] == "not" )
562                         r = $.filter(m[3],r,false).r;
563                 else {
564                         if ( $.g[m[1]].constructor == String )
565                                 var f = $.g[m[1]];
566                         else if ( $.g[m[1]][m[2]] )
567                                 var f = $.g[m[1]][m[2]];
568                                                 
569                         if ( f != null ) {
570                                 eval("f = function(a,i){return " + f + "}");
571                                 r = g( r, f );
572                         }
573                 }
574         }
575         return { r: r, t: t };
576 };
577
578 $.parents = function(a){
579         var b = [];
580         var c = a.parentNode;
581         while ( c != null && c != document ) {
582                 b[b.length] = c;
583                 c = c.parentNode;
584         }
585         return b;
586 };
587
588 $.cleanSpaces = function(t){
589         return t.replace(/^\s+|\s+$/g, '')
590 };
591
592 $.ofType = function(a,n,e) {
593         var t = $.grep($.sibling(a),function(b){return b.nodeName == a.nodeName});
594         if ( e ) n = t.length - n - 1;
595         return n != null ? t[n] == a : t.length;
596 };
597
598 $.sibling = function(a,n,e) {
599         var type = [];
600         var tmp = a.parentNode.childNodes;
601         for ( var i = 0; i < tmp.length; i++ ) {
602                 if ( tmp[i].nodeType == 1 )
603                         type[type.length] = tmp[i];
604                 if ( tmp[i] == a )
605                         type.n = type.length - 1;
606         }
607         if ( e ) n = type.length - n - 1;
608         type.cur = ( type[n] == a );
609         type.prev = ( type.n > 0 ? type[type.n - 1] : null );
610         type.next = ( type.n < type.length - 1 ? type[type.n + 1] : null );
611         return type;
612 };
613
614 $.hasWord = function(e,a) {
615         if ( e == null ) return false;
616         if ( e.className != null ) e = e.className;
617         return new RegExp("(^|\\s)" + a + "(\\s|$)").test(e)
618 };
619
620 $.getAll = function(o,r) {
621         r = r || [];
622         var s = o.childNodes;
623         for ( var i = 0; i < s.length; i++ ) {
624                 if ( s[i].nodeType == 1 ) {
625                         r[r.length] = s[i];
626                         $.getAll( s[i], r );
627                 }
628         }
629         return r;
630 };
631
632 $.merge = function(a,b) {
633         var d = [];
634         for ( var j = 0; j < b.length; j++ )
635                 d[j] = b[j];
636         
637         for ( var i = 0; i < a.length; i++ ) {
638                 var c = true;
639                 for ( var j = 0; j < b.length; j++ )
640                         if ( a[i] == b[j] )
641                                 c = false;
642                         if ( c )
643                                 d[d.length] = a[i];
644         }
645         return d;
646 };
647
648 $.grep = function(a,f,s) {
649         var r = [];
650         if ( a != null )
651                 for ( var i = 0; i < a.length; i++ )
652                         if ( (!s && f(a[i],i)) || (s && !f(a[i],i)) )
653                                 r[r.length] = a[i];
654         return r;
655 };
656
657 $.map = function(a,f) {
658         var r = [];
659         for ( var i = 0; i < a.length; i++ ) {
660                 var t = f(a[i],i);
661                 if ( t != null ) {
662                         if ( t.constructor != Array ) t = [t];
663                         r = $.merge( t, r );
664                 }
665         }
666         return r;
667 };
668
669 // Bind an event to an element
670 // Original by Dean Edwards
671 function addEvent(element, type, handler) {
672         if ( element.location ) element = window; // Ughhhhh....
673         if (!handler.$$guid) handler.$$guid = addEvent.guid++;
674         if (!element.events) element.events = {};
675         var handlers = element.events[type];
676         if (!handlers) {
677                 handlers = element.events[type] = {};
678                 if (element["on" + type])
679                         handlers[0] = element["on" + type];
680         }
681         handlers[handler.$$guid] = handler;
682         element["on" + type] = handleEvent;
683 };
684 addEvent.guid = 1;
685
686 // Detach an event or set of events from an element
687 function removeEvent(element, type, handler) {
688         if (element.events) {
689                 if (type && element.events[type]) {
690                         if ( handler ) {
691                                 delete element.events[type][handler.$$guid];
692                         } else {
693                                 for ( var i in element.events[type] )
694                                         delete element.events[type][i];
695                         }
696                 } else {
697                         for ( var i in element.events )
698                                 removeEvent( element, i );
699                 }
700         }
701 };
702
703 function triggerEvent(element,type,data) {
704         data = data || [{ type: type }];
705         if ( element && element["on" + type] )
706                 $.apply( element, element["on" + type], data );
707 }
708
709 function handleEvent(event) {
710         var returnValue = true;
711         event = event || fixEvent(window.event);
712         var handlers = [];
713         for ( var i in this.events[event.type] )
714                 handlers[handlers.length] = this.events[event.type][i];
715         for ( var i = 0; i < handlers.length; i++ ) {
716                 try {
717                         if ( handlers[i].constructor == Function ) {
718                                 this.$$handleEvent = handlers[i];
719                                 if (this.$$handleEvent(event) === false) {
720                                         event.preventDefault();
721                                         event.stopPropagation();
722                                         returnValue = false;
723                                 }
724                         }
725                 } catch(e){}
726         }
727         return returnValue;
728 };
729
730 function fixEvent(event) {
731         event.preventDefault = fixEvent.preventDefault;
732         event.stopPropagation = fixEvent.stopPropagation;
733         return event;
734 };
735 fixEvent.preventDefault = function() {
736         this.returnValue = false;
737 };
738 fixEvent.stopPropagation = function() {
739         this.cancelBubble = true;
740 };
741
742 // Move to module
743
744 $.fn.text = function(e) {
745         e = e || this.cur;
746         var t = "";
747         for ( var j = 0; j < e.length; j++ ) {
748                 for ( var i = 0; i < e[j].childNodes.length; i++ )
749                         t += e[j].childNodes[i].nodeType != 1 ?
750                                 e[j].childNodes[i].nodeValue :
751                                 $.fn.text(e[j].childNodes[i].childNodes);
752         }
753         return t;
754 };
755
756 setTimeout(function(){
757         if ( typeof Prototype != "undefined" && $.g == null && $.clean == null )
758                 throw "Error: You are overwriting jQuery, please include jQuery last.";
759 }, 1000);