X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=jquery%2Fjquery.js;h=6da9d608f867430afc75bcb6e00713f33b4df133;hb=4ad5fcb4f752fb09d7074deb9b2c98167b1a7dd7;hp=2874e528f9baef78b5efe570be27de6b1780b2fd;hpb=4531ab13243f5e94e1ecfbd55e992842666d08aa;p=jquery.git diff --git a/jquery/jquery.js b/jquery/jquery.js index 2874e52..6da9d60 100644 --- a/jquery/jquery.js +++ b/jquery/jquery.js @@ -12,55 +12,76 @@ // Global undefined variable window.undefined = window.undefined; -// Map over the $ in case of overwrite -if ( $ ) var _$ = $; - /** * Create a new jQuery Object * @constructor */ -var $ = jQuery = function(a,c) { +function jQuery(a,c) { + + // Shortcut for document ready (because $(document).each() is silly) + if ( a && a.constructor == Function ) + return $(document).ready(a); + + // Make sure t hat a selection was provided + a = a || jQuery.context || document; + /* - * Handle support for overriding other $() functions. Way too many libraries - * provide this function to simply ignore it and overwrite it. - */ + * Handle support for overriding other $() functions. Way too many libraries + * provide this function to simply ignore it and overwrite it. + */ // Check to see if this is a possible collision case - if ( _$ && !c && ( a.constructor == String && + if ( jQuery._$ && !c && a.constructor == String && // Make sure that the expression is a colliding one !/[^a-zA-Z0-9_-]/.test(a) && // and that there are no elements that match it // (this is the one truly ambiguous case) - !document.getElementsByTagName(a).length ) || - - // Watch for an array being passed in (Prototype 1.5) - a.constructor == Array ) + !document.getElementsByTagName(a).length ) // Use the default method, in case it works some voodoo - return _$( a ); + return jQuery._$( a ); - // Watch for when a jQuery object is passed in as an arg - if ( a && a.jquery ) + // Watch for when a jQuery object is passed as the selector + if ( a.jquery ) return a; + + // Watch for when a jQuery object is passed at the context + if ( c && c.jquery ) + return $(c.get()).find(a); // If the context is global, return a new object if ( window == this ) return new jQuery(a,c); - - // Find the matching elements and save them for later - this.cur = jQuery.Select( - a || jQuery.context || document, - c && c.jquery && c.get(0) || c - ); + + // Watch for when an array is passed in + this.get( a.constructor == Array ? + // Assume that it's an array of DOM Elements + a : + + // Find the matching elements and save them for later + jQuery.Select( a, c ) ); + + var fn = arguments[ arguments.length - 1 ]; + if ( fn && fn.constructor == Function ) + this.each(fn); } +// Map over the $ in case of overwrite +if ( $ ) + jQuery._$ = $; + +// Map the jQuery namespace to the '$' one +var $ = jQuery; + jQuery.fn = jQuery.prototype = { /** * The current SVN version of jQuery. * * @private + * @property + * @name jquery * @type String */ jquery: "$Rev$", @@ -68,114 +89,206 @@ jQuery.fn = jQuery.prototype = { /** * The number of elements currently matched. * + * @property + * @name length + * @type Number + */ + + /** + * The number of elements currently matched. + * + * @name size * @type Number */ size: function() { - return this.get().length; + return this.length; }, /** - * Access the elements matched. If a number is provided, - * the Nth element is returned, otherwise, an array of all - * matched items is returned. + * Access all matched elements. This serves as a backwards-compatible + * way of accessing all matched elements (other than the jQuery object + * itself, which is, in fact, an array of elements). + * + * @name get + * @type Array + */ + + /** + * Access a single matched element. num is used to access the + * numth element matched. * - * @type Array,DOMElement + * @name get + * @type Element + * @param Number num Access the element in the numth position. */ - get: function(num) { - return num == undefined ? this.cur : this.cur[num]; + + /** + * Set the jQuery object to an array of elements. + * + * @private + * @name get + * @type jQuery + * @param Elements elems An array of elements + */ + get: function( num ) { + // Watch for when an array (of elements) is passed in + if ( num && num.constructor == Array ) { + + // Use a tricky hack to make the jQuery object + // look and feel like an array + this.length = 0; + [].push.apply( this, num ); + + return this; + } else + return num == undefined ? + + // Return a 'clean' array + $.map( this, function(a){ return a } ) : + + // Return just the object + this[num]; }, - each: function(f) { - for ( var i = 0; i < this.size(); i++ ) - f.apply( this.get(i), [i] ); + /** + * Execute a function within the context of every matched element. + * This means that every time the passed-in function is executed + * (which is once for every element matched) the 'this' keyword + * points to the specific element. + * + * Additionally, the function, when executed, is passed a single + * argument representing the position of the element in the matched + * set. + * + * @name each + * @type jQuery + * @param Function fn A function to execute + */ + each: function( fn ) { + // Iterate through all of the matched elements + for ( var i = 0; i < this.length; i++ ) + + // Execute the function within the context of each element + fn.apply( this[i], [i] ); + return this; }, - set: function(a,b) { - return this.each(function(){ - if ( b === undefined ) - for ( var j in a ) - jQuery.attr(this,j,a[j]); - else - jQuery.attr(this,a,b); - }); - }, - html: function(h) { - return h == undefined && this.size() ? - this.get(0).innerHTML : this.set( "innerHTML", h ); - }, - val: function(h) { - return h == undefined && this.size() ? - this.get(0).value : this.set( "value", h ); - }, - text: function(e) { - e = e || this.get(); - var t = ""; - for ( var j = 0; j < e.length; j++ ) - for ( var i = 0; i < e[j].childNodes.length; i++ ) - t += e[j].childNodes[i].nodeType != 1 ? - e[j].childNodes[i].nodeValue : - jQuery.fn.text(e[j].childNodes[i].childNodes); - return t; - }, - css: function(a,b) { - return a.constructor != String || b ? + /** + * Access a property on the first matched element. + * This method makes it easy to retreive a property value + * from the first matched element. + * + * @name attr + * @type Object + * @param String name The name of the property to access. + */ + + /** + * Set a hash of key/value object properties to all matched elements. + * This serves as the best way to set a large number of properties + * on all matched elements. + * + * @name attr + * @type jQuery + * @param Hash prop A set of key/value pairs to set as object properties. + */ + + /** + * Set a single property to a value, on all matched elements. + * + * @name attr + * @type jQuery + * @param String key The name of the property to set. + * @param Object value The value to set the property to. + */ + attr: function( key, value ) { + // Check to see if we're setting style values + return key.constructor != String || value ? this.each(function(){ - if ( b === undefined ) - for ( var j in a ) - jQuery.attr(this.style,j,a[j]); + // See if we're setting a hash of styles + if ( value == undefined ) + // Set all the styles + for ( var prop in key ) + jQuery.attr( + type ? this.style : this, + prop, key[prop] + ); + + // See if we're setting a single key/value style else - jQuery.attr(this.style,a,b); - }) : jQuery.css( this.get(0), a ); - }, - toggle: function() { - return this.each(function(){ - var d = jQuery.css(this,"display"); - if ( !d || d == "none" ) - $(this).show(); - else - $(this).hide(); - }); - }, - show: function() { - return this.each(function(){ - this.style.display = this.oldblock ? this.oldblock : ""; - if ( jQuery.css(this,"display") == "none" ) - this.style.display = "block"; - }); - }, - hide: function() { - return this.each(function(){ - this.oldblock = jQuery.css(this,"display"); - if ( this.oldblock == "none" ) - this.oldblock = "block"; - this.style.display = "none"; - }); - }, - addClass: function(c) { - return this.each(function(){ - jQuery.className.add(this,c); - }); - }, - removeClass: function(c) { - return this.each(function(){ - jQuery.className.remove(this,c); - }); + jQuery.attr( + type ? this.style : this, + key, value + ); + }) : + + // Look for the case where we're accessing a style value + jQuery[ type || "attr" ]( this[0], key ); }, - - toggleClass: function(c) { - return this.each(function(){ - if (jQuery.hasWord(this,c)) - jQuery.className.remove(this,c); - else - jQuery.className.add(this,c); - }); + + /** + * Access a style property on the first matched element. + * This method makes it easy to retreive a style property value + * from the first matched element. + * + * @name css + * @type Object + * @param String name The name of the property to access. + */ + + /** + * Set a hash of key/value style properties to all matched elements. + * This serves as the best way to set a large number of style properties + * on all matched elements. + * + * @name css + * @type jQuery + * @param Hash prop A set of key/value pairs to set as style properties. + */ + + /** + * Set a single style property to a value, on all matched elements. + * + * @name css + * @type jQuery + * @param String key The name of the property to set. + * @param Object value The value to set the property to. + */ + css: function( key, value ) { + return this.attr( key, value, "css" ); }, - remove: function() { - this.each(function(){this.parentNode.removeChild( this );}); - return this.pushStack( [] ); + + /** + * Retreive the text contents of all matched elements. The result is + * a string that contains the combined text contents of all matched + * elements. This method works on both HTML and XML documents. + * + * @name text + * @type String + */ + text: function(e) { + e = e || this; + var t = ""; + for ( var j = 0; j < e.length; j++ ) { + var r = e[j].childNodes; + for ( var i = 0; i < r.length; i++ ) + t += r[i].nodeType != 1 ? + r[i].nodeValue : jQuery.fn.text([ r[i] ]); + } + return t; }, + /** + * Set a single style property to a value, on all matched elements. + * + * @name wrap + * @type jQuery + * @any String html A string of HTML, that will be created on the fly and wrapped around the target. + * @any Element elem A DOM element that will be wrapped. + * @any Array elems An array of elements, the first of which will be wrapped. + * @any Object + */ wrap: function() { var a = jQuery.clean(arguments); return this.each(function(){ @@ -188,117 +301,110 @@ jQuery.fn = jQuery.prototype = { }, append: function() { - var clone = this.size() > 1; - var a = jQuery.clean(arguments); - return this.domManip(function(){ - for ( var i = 0; i < a.length; i++ ) - this.appendChild( clone ? a[i].cloneNode(true) : a[i] ); - }); - }, - - appendTo: function() { - var a = arguments; - return this.each(function(){ - for ( var i = 0; i < a.length; i++ ) - $(a[i]).append( this ); + return this.domManip(arguments, true, 1, function(a){ + this.appendChild( 1 ); }); }, prepend: function() { - var clone = this.size() > 1; - var a = jQuery.clean(arguments); - return this.domManip(function(){ - for ( var i = a.length - 1; i >= 0; i-- ) - this.insertBefore( clone ? a[i].cloneNode(true) : a[i], this.firstChild ); + return this.domManip(arguments, true, -1, function(a){ + this.insertBefore( a, this.firstChild ); }); }, before: function() { - var clone = this.size() > 1; - var a = jQuery.clean(arguments); - return this.each(function(){ - for ( var i = 0; i < a.length; i++ ) - this.parentNode.insertBefore( clone ? a[i].cloneNode(true) : a[i], this ); + return this.domManip(arguments, false, 1, function(a){ + this.parentNode.insertBefore( a, this ); }); }, after: function() { - var clone = this.size() > 1; - var a = jQuery.clean(arguments); - return this.each(function(){ - for ( var i = a.length - 1; i >= 0; i-- ) - this.parentNode.insertBefore( clone ? a[i].cloneNode(true) : a[i], this.nextSibling ); + return this.domManip(arguments, false, -1, function(a){ + this.parentNode.insertBefore( a, this.nextSibling ); }); }, - empty: function() { + /** + * A wrapper function for each() to be used by append and prepend. + * Handles cases where you're trying to modify the inner contents of + * a table, when you actually need to work with the tbody. + * + * @private + * @member jQuery + * @param {Function} fn The function doing the DOM manipulation. + * @type jQuery + */ + domManip: function(args, table, dir, fn){ + var clone = this.size() > 1; + var a = jQuery.clean(args); + return this.each(function(){ - while ( this.firstChild ) - this.removeChild( this.firstChild ); - }); - }, - - bind: function(t,f) { - return this.each(function(){jQuery.event.add(this,t,f);}); - }, - unbind: function(t,f) { - return this.each(function(){jQuery.event.remove(this,t,f);}); - }, - trigger: function(t) { - return this.each(function(){jQuery.event.trigger(this,t);}); - }, + var obj = this; + + if ( table && this.nodeName == "TABLE" ) { + var tbody = this.getElementsByTagName("tbody"); + + if ( !tbody.length ) { + obj = document.createElement("tbody"); + this.appendChild( obj ); + } else + obj = tbody[0]; + } - pushStack: function(a) { - if ( !this.stack ) this.stack = []; - this.stack.unshift( this.cur ); - if ( a ) this.cur = a; - return this; + for ( var i = ( dir < 0 ? a.length - 1 : 0 ); + i != ( dir < 0 ? dir : a.length ); i += dir ) + fn.apply( obj, [ a[i] ] ); + }); }, - find: function(t) { - var ret = []; - this.each(function(){ - ret = jQuery.merge( ret, jQuery.Select(t,this) ); - }); - this.pushStack( ret ); + pushStack: function(a,args) { + var fn = args && args[args.length-1]; + + if ( !fn || fn.constructor != Function ) { + if ( !this.stack ) this.stack = []; + this.stack.push( this.get() ); + this.get( a ); + } else { + var old = this.get(); + this.get( a ); + if ( fn.constructor == Function ) + return this.each( fn ); + this.get( old ); + } + return this; }, - + end: function() { - this.cur = this.stack.shift(); + this.get( this.stack.pop() ); return this; }, - parent: function(a) { - var ret = jQuery.map(this.cur,"d.parentNode"); - if ( a ) ret = jQuery.filter(a,ret).r; - return this.pushStack(ret); - }, - - parents: function(a) { - var ret = jQuery.map(this.cur,jQuery.parents); - if ( a ) ret = jQuery.filter(a,ret).r; - return this.pushStack(ret); - }, - - siblings: function(a) { - // Incorrect, need to exclude current element - var ret = jQuery.map(this.cur,jQuery.sibling); - if ( a ) ret = jQuery.filter(a,ret).r; - return this.pushStack(ret); + find: function(t) { + return this.pushStack( jQuery.map( this, function(a){ + return jQuery.Select(t,a); + }), arguments ); }, filter: function(t) { - return this.pushStack( jQuery.filter(t,this.cur).r ); + return t.constructor == Array ? + // Multi Filtering + this.pushStack( jQuery.map(this,function(a){ + for ( var i = 0; i < t.length; i++ ) + if ( jQuery.filter(t[i],[a]).r.length ) + return a; + }), arguments ) : + + this.pushStack( jQuery.filter(t,this).r, arguments ); }, not: function(t) { return this.pushStack( t.constructor == String ? - jQuery.filter(t,this.cur,false).r : - jQuery.grep(this.cur,function(a){ return a != t; }) ); + jQuery.filter(t,this,false).r : + jQuery.grep(this,function(a){ return a != t; }), arguments ); }, add: function(t) { - return this.pushStack( jQuery.merge( this.cur, t.constructor == String ? - jQuery.Select(t) : t.constructor == Array ? t : [t] ) ); + return this.pushStack( jQuery.merge( this, t.constructor == String ? + jQuery.Select(t) : t.constructor == Array ? t : [t] ), arguments ); }, /** @@ -311,47 +417,7 @@ jQuery.fn = jQuery.prototype = { * @type Boolean */ is: function(expr) { - return jQuery.filter(expr,this.cur).r.length > 0; - }, - - /** - * A wrapper function for each() to be used by append and prepend. - * Handles cases where you're trying to modify the inner contents of - * a table, when you actually need to work with the tbody. - * - * @private - * @member jQuery - * @param {Function} fn The function doing the DOM manipulation. - * @type jQuery - */ - domManip: function(fn){ - return this.each(function(){ - var obj = this; - - if ( this.nodeName == "TABLE" ) { - var tbody = this.getElementsByTagName("tbody"); - - if ( !tbody.length ) { - obj = document.createElement("tbody"); - this.appendChild( obj ); - } else - obj = tbody[0]; - } - - fn.apply( obj ); - }); - } -}; - -jQuery.className = { - add: function(o,c){ - if (jQuery.hasWord(o,c)) return; - o.className += ( o.className ? " " : "" ) + c; - }, - remove: function(o,c){ - o.className = !c ? "" : - o.className.replace( - new RegExp("(^|\\s*\\b[^-])"+c+"($|\\b(?=[^-]))", "g"), ""); + return jQuery.filter(expr,this).r.length > 0; } }; @@ -368,44 +434,161 @@ jQuery.className = { // Check to see if the W3C box model is being used jQuery.boxModel = ( jQuery.browser != "msie" || document.compatMode == "CSS1Compat" ); + + var axis = { + parent: "a.parentNode", + parents: jQuery.parents, + ancestors: jQuery.parents, + next: "a.nextSibling", + prev: "a.previousSibling", + siblings: jQuery.sibling + }; + + for ( var i in axis ) {(function(){ + var t = axis[i]; + jQuery.fn[ i ] = function(a) { + var ret = jQuery.map(this,t); + if ( a ) ret = jQuery.filter(a,ret).r; + return this.pushStack( ret, arguments ); + }; + })();} + + var to = "html,append,prepend,before,after".split(','); + + for ( var i = 0; i < to.length; i++ ) {(function(){ + var n = to[i]; + jQuery.fn[ n + "To" ] = function(){ + var a = arguments; + return this.each(function(){ + for ( var i = 0; i < a.length; i++ ) + $(a[i])[n]( this ); + }); + }; + })();} + + var each = { + show: function(){ + this.style.display = this.oldblock ? this.oldblock : ""; + if ( jQuery.css(this,"display") == "none" ) + this.style.display = "block"; + }, + + hide: function(){ + this.oldblock = jQuery.css(this,"display"); + if ( this.oldblock == "none" ) + this.oldblock = "block"; + this.style.display = "none"; + }, + + toggle: function(){ + var d = jQuery.css(this,"display"); + $(this)[ !d || d == "none" ? 'show' : 'hide' ](); + }, + + addClass: function(c){ + jQuery.className.add(this,c); + }, + + removeClass: function(c){ + jQuery.className.remove(this,c); + }, + + toggleClass: function( c ){ + jQuery.className[ jQuery.hasWord(this,a) ? 'remove' : 'add' ](this,c); + }, + + remove: function(){ + this.parentNode.removeChild( this ); + }, + + empty: function(){ + while ( this.firstChild ) + this.removeChild( this.firstChild ); + }, + + bind: function( type, fn ) { + jQuery.event.add( this, type, fn ); + }, + + unbind: function( type, fn ) { + jQuery.event.remove( this, type, fn ); + }, + + trigger: function( type ) { + jQuery.event.trigger( this, type ); + }, + }; + + for ( var i in each ) {(function(){ + var n = each[i]; + jQuery.fn[ i ] = function(a,b) { + var a = arguments; + return this.each(function(){ + n.apply( this, a ); + }); + }; + })();} + + var attr = { + val: 'value', + html: 'innerHTML' + }; + + for ( var i in attr ) {(function(){ + var n = attr[i]; + jQuery.fn[ i ] = function(h) { + return h == undefined && this.length ? + this[0][n] : this.set( n, h ); + }; + })();} + })(); +jQuery.className = { + add: function(o,c){ + if (jQuery.hasWord(o,c)) return; + o.className += ( o.className ? " " : "" ) + c; + }, + remove: function(o,c){ + o.className = !c ? "" : + o.className.replace( + new RegExp("(^|\\s*\\b[^-])"+c+"($|\\b(?=[^-]))", "g"), ""); + } +}; + +$.swap = function(e,o,f) { + for ( var i in o ) { + e.style["old"+i] = e.style[i]; + e.style[i] = o[i]; + } + f.apply( e, [] ); + for ( var i in o ) + e.style[i] = e.style["old"+i]; +}; + jQuery.css = function(e,p) { // Adapted from Prototype 1.4.0 if ( p == "height" || p == "width" ) { + var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"]; - // Handle extra width/height provided by the W3C box model - var ph = (!jQuery.boxModel ? 0 : - jQuery.css(e,"paddingTop") + jQuery.css(e,"paddingBottom") + - jQuery.css(e,"borderTopWidth") + jQuery.css(e,"borderBottomWidth")) || 0; - - var pw = (!jQuery.boxModel ? 0 : - jQuery.css(e,"paddingLeft") + jQuery.css(e,"paddingRight") + - jQuery.css(e,"borderLeftWidth") + jQuery.css(e,"borderRightWidth")) || 0; - - var oHeight, oWidth; - - if (jQuery.css(e,"display") != 'none') { - oHeight = e.offsetHeight || parseInt(e.style.height) || 0; - oWidth = e.offsetWidth || parseInt(e.style.width) || 0; - } else { - var els = e.style; - var ov = els.visibility; - var op = els.position; - var od = els.display; - els.visibility = "hidden"; - els.position = "absolute"; - els.display = ""; - oHeight = e.clientHeight || parseInt(e.style.height); - oWidth = e.clientWidth || parseInt(e.style.width); - els.display = od; - els.position = op; - els.visibility = ov; + for ( var i in d ) { + old["padding" + d[i]] = 0; + old["border" + d[i] + "Width"] = 0; } - return p == "height" ? - (oHeight - ph < 0 ? 0 : oHeight - ph) : - (oWidth - pw < 0 ? 0 : oWidth - pw); + $.swap( e, old, function() { + if (jQuery.css(e,"display") != 'none') { + oHeight = e.offsetHeight; + oWidth = e.offsetWidth; + } else + $.swap( e, { visibility: 'hidden', position: 'absolute', display: '' }, + function(){ + oHeight = e.clientHeight; + oWidth = e.clientWidth; + }); + }); + + return p == "height" ? oHeight : oWidth; } var r; @@ -420,7 +603,7 @@ jQuery.css = function(e,p) { r = s ? s.getPropertyValue(p) : null; } - return /top|right|left|bottom/i.test(p) ? parseFloat( r ) : r; + return r; }; jQuery.clean = function(a) { @@ -517,9 +700,14 @@ jQuery.token = [ ]; jQuery.Select = function( t, context ) { + // Make sure that the context is a DOM Element + if ( context && context.getElementsByTagName == undefined ) + context = null; + + // Set the correct context (if none is provided) context = context || jQuery.context || document; - if ( t.constructor != String ) - return t.constructor == Array ? t : [t]; + + if ( t.constructor != String ) return [t]; if ( !t.indexOf("//") ) { context = context.documentElement; @@ -537,10 +725,10 @@ jQuery.Select = function( t, context ) { var last = null; while ( t.length > 0 && last != t ) { - var r = []; + var r = []; last = t; - t = jQuery.cleanSpaces(t).replace( /^\/\//i, "" ); + t = jQuery.cleanSpaces(t).replace( /^\/\//i, "" ); var foundToken = false; @@ -635,7 +823,7 @@ jQuery.filter = function(t,r,not) { g = function(a,f) {return jQuery.grep(a,f,true);}; while ( t && t.match(/^[:\\.#\\[a-zA-Z\\*]/) ) { - var re = /^\[ *@([a-z0-9*()_-]+) *([~!|*$^=]*) *'?"?([^'"]*)'?"? *\]/i; + var re = /^\[ *@([a-z*_-][a-z0-9()_-]*) *([~!|*$^=]*) *'?"?([^'"]*)'?"? *\]/i; var m = re.exec(t); if ( m ) @@ -706,15 +894,14 @@ jQuery.sibling = function(a,n,e) { type.n = type.length - 1; } if ( e ) n = type.length - n - 1; - type.cur = ( type[n] == a ); - type.prev = ( type.n > 0 ? type[type.n - 1] : null ); - type.next = ( type.n < type.length - 1 ? type[type.n + 1] : null ); + type.cur = type[n] == a; + type.next = type[type.n + 1]; return type; }; jQuery.hasWord = function(e,a) { - if ( e == undefined ) return; - if ( e.className ) e = e.className; + if ( e.className ) + e = e.className; return new RegExp("(^|\\s)" + a + "(\\s|$)").test(e); }; @@ -778,10 +965,15 @@ jQuery.event = { handlers[0] = element["on" + type]; } handlers[handler.guid] = handler; - element["on" + type] = jQuery.event.handle; + element["on" + type] = this.handle; + + if (!this.global[type]) + this.global[type] = []; + this.global[type].push( element ); }, guid: 1, + global: {}, // Detach an event or set of events from an element remove: function(element, type, handler) { @@ -794,13 +986,28 @@ jQuery.event = { delete element.events[type][i]; else for ( var j in element.events ) - jQuery.event.remove( element, j ); + this.remove( element, j ); }, - trigger: function(element,type,data) { - data = data || [ jQuery.event.fix({ type: type }) ]; - if ( element && element["on" + type] ) + trigger: function(type,data,element) { + // Touch up the incoming data + data = data || []; + + // Handle a global trigger + if ( !element ) { + var g = this.global[type]; + if ( g ) + for ( var i = 0; i < g.length; i++ ) + this.trigger( type, data, g[i] ); + + // Handle triggering a single element + } else if ( element["on" + type] ) { + // Pass along a fake event + data.unshift( this.fix({ type: type, target: element }) ); + + // Trigger the event element["on" + type].apply( element, data ); + } }, handle: function(event) { @@ -843,4 +1050,4 @@ jQuery.event = { return event; } -}; +}; \ No newline at end of file