scratch – Rev 125

Subversion Repositories:
Rev:
define([
        "./core",
        "./var/strundefined",
        "./var/rnotwhite",
        "./var/hasOwn",
        "./var/slice",
        "./event/support",
        "./data/var/data_priv",

        "./core/init",
        "./data/accepts",
        "./selector"
], function( jQuery, strundefined, rnotwhite, hasOwn, slice, support, data_priv ) {

var
        rkeyEvent = /^key/,
        rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
        rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
        rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;

function returnTrue() {
        return true;
}

function returnFalse() {
        return false;
}

function safeActiveElement() {
        try {
                return document.activeElement;
        } catch ( err ) { }
}

/*
 * Helper functions for managing events -- not part of the public interface.
 * Props to Dean Edwards' addEvent library for many of the ideas.
 */
jQuery.event = {

        global: {},

        add: function( elem, types, handler, data, selector ) {

                var handleObjIn, eventHandle, tmp,
                        events, t, handleObj,
                        special, handlers, type, namespaces, origType,
                        elemData = data_priv.get( elem );

                // Don't attach events to noData or text/comment nodes (but allow plain objects)
                if ( !elemData ) {
                        return;
                }

                // Caller can pass in an object of custom data in lieu of the handler
                if ( handler.handler ) {
                        handleObjIn = handler;
                        handler = handleObjIn.handler;
                        selector = handleObjIn.selector;
                }

                // Make sure that the handler has a unique ID, used to find/remove it later
                if ( !handler.guid ) {
                        handler.guid = jQuery.guid++;
                }

                // Init the element's event structure and main handler, if this is the first
                if ( !(events = elemData.events) ) {
                        events = elemData.events = {};
                }
                if ( !(eventHandle = elemData.handle) ) {
                        eventHandle = elemData.handle = function( e ) {
                                // Discard the second event of a jQuery.event.trigger() and
                                // when an event is called after a page has unloaded
                                return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
                                        jQuery.event.dispatch.apply( elem, arguments ) : undefined;
                        };
                }

                // Handle multiple events separated by a space
                types = ( types || "" ).match( rnotwhite ) || [ "" ];
                t = types.length;
                while ( t-- ) {
                        tmp = rtypenamespace.exec( types[t] ) || [];
                        type = origType = tmp[1];
                        namespaces = ( tmp[2] || "" ).split( "." ).sort();

                        // There *must* be a type, no attaching namespace-only handlers
                        if ( !type ) {
                                continue;
                        }

                        // If event changes its type, use the special event handlers for the changed type
                        special = jQuery.event.special[ type ] || {};

                        // If selector defined, determine special event api type, otherwise given type
                        type = ( selector ? special.delegateType : special.bindType ) || type;

                        // Update special based on newly reset type
                        special = jQuery.event.special[ type ] || {};

                        // handleObj is passed to all event handlers
                        handleObj = jQuery.extend({
                                type: type,
                                origType: origType,
                                data: data,
                                handler: handler,
                                guid: handler.guid,
                                selector: selector,
                                needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
                                namespace: namespaces.join(".")
                        }, handleObjIn );

                        // Init the event handler queue if we're the first
                        if ( !(handlers = events[ type ]) ) {
                                handlers = events[ type ] = [];
                                handlers.delegateCount = 0;

                                // Only use addEventListener if the special events handler returns false
                                if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
                                        if ( elem.addEventListener ) {
                                                elem.addEventListener( type, eventHandle, false );
                                        }
                                }
                        }

                        if ( special.add ) {
                                special.add.call( elem, handleObj );

                                if ( !handleObj.handler.guid ) {
                                        handleObj.handler.guid = handler.guid;
                                }
                        }

                        // Add to the element's handler list, delegates in front
                        if ( selector ) {
                                handlers.splice( handlers.delegateCount++, 0, handleObj );
                        } else {
                                handlers.push( handleObj );
                        }

                        // Keep track of which events have ever been used, for event optimization
                        jQuery.event.global[ type ] = true;
                }

        },

        // Detach an event or set of events from an element
        remove: function( elem, types, handler, selector, mappedTypes ) {

                var j, origCount, tmp,
                        events, t, handleObj,
                        special, handlers, type, namespaces, origType,
                        elemData = data_priv.hasData( elem ) && data_priv.get( elem );

                if ( !elemData || !(events = elemData.events) ) {
                        return;
                }

                // Once for each type.namespace in types; type may be omitted
                types = ( types || "" ).match( rnotwhite ) || [ "" ];
                t = types.length;
                while ( t-- ) {
                        tmp = rtypenamespace.exec( types[t] ) || [];
                        type = origType = tmp[1];
                        namespaces = ( tmp[2] || "" ).split( "." ).sort();

                        // Unbind all events (on this namespace, if provided) for the element
                        if ( !type ) {
                                for ( type in events ) {
                                        jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
                                }
                                continue;
                        }

                        special = jQuery.event.special[ type ] || {};
                        type = ( selector ? special.delegateType : special.bindType ) || type;
                        handlers = events[ type ] || [];
                        tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );

                        // Remove matching events
                        origCount = j = handlers.length;
                        while ( j-- ) {
                                handleObj = handlers[ j ];

                                if ( ( mappedTypes || origType === handleObj.origType ) &&
                                        ( !handler || handler.guid === handleObj.guid ) &&
                                        ( !tmp || tmp.test( handleObj.namespace ) ) &&
                                        ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
                                        handlers.splice( j, 1 );

                                        if ( handleObj.selector ) {
                                                handlers.delegateCount--;
                                        }
                                        if ( special.remove ) {
                                                special.remove.call( elem, handleObj );
                                        }
                                }
                        }

                        // Remove generic event handler if we removed something and no more handlers exist
                        // (avoids potential for endless recursion during removal of special event handlers)
                        if ( origCount && !handlers.length ) {
                                if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
                                        jQuery.removeEvent( elem, type, elemData.handle );
                                }

                                delete events[ type ];
                        }
                }

                // Remove the expando if it's no longer used
                if ( jQuery.isEmptyObject( events ) ) {
                        delete elemData.handle;
                        data_priv.remove( elem, "events" );
                }
        },

        trigger: function( event, data, elem, onlyHandlers ) {

                var i, cur, tmp, bubbleType, ontype, handle, special,
                        eventPath = [ elem || document ],
                        type = hasOwn.call( event, "type" ) ? event.type : event,
                        namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];

                cur = tmp = elem = elem || document;

                // Don't do events on text and comment nodes
                if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
                        return;
                }

                // focus/blur morphs to focusin/out; ensure we're not firing them right now
                if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
                        return;
                }

                if ( type.indexOf(".") >= 0 ) {
                        // Namespaced trigger; create a regexp to match event type in handle()
                        namespaces = type.split(".");
                        type = namespaces.shift();
                        namespaces.sort();
                }
                ontype = type.indexOf(":") < 0 && "on" + type;

                // Caller can pass in a jQuery.Event object, Object, or just an event type string
                event = event[ jQuery.expando ] ?
                        event :
                        new jQuery.Event( type, typeof event === "object" && event );

                // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
                event.isTrigger = onlyHandlers ? 2 : 3;
                event.namespace = namespaces.join(".");
                event.namespace_re = event.namespace ?
                        new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
                        null;

                // Clean up the event in case it is being reused
                event.result = undefined;
                if ( !event.target ) {
                        event.target = elem;
                }

                // Clone any incoming data and prepend the event, creating the handler arg list
                data = data == null ?
                        [ event ] :
                        jQuery.makeArray( data, [ event ] );

                // Allow special events to draw outside the lines
                special = jQuery.event.special[ type ] || {};
                if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
                        return;
                }

                // Determine event propagation path in advance, per W3C events spec (#9951)
                // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
                if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {

                        bubbleType = special.delegateType || type;
                        if ( !rfocusMorph.test( bubbleType + type ) ) {
                                cur = cur.parentNode;
                        }
                        for ( ; cur; cur = cur.parentNode ) {
                                eventPath.push( cur );
                                tmp = cur;
                        }

                        // Only add window if we got to document (e.g., not plain obj or detached DOM)
                        if ( tmp === (elem.ownerDocument || document) ) {
                                eventPath.push( tmp.defaultView || tmp.parentWindow || window );
                        }
                }

                // Fire handlers on the event path
                i = 0;
                while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {

                        event.type = i > 1 ?
                                bubbleType :
                                special.bindType || type;

                        // jQuery handler
                        handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
                        if ( handle ) {
                                handle.apply( cur, data );
                        }

                        // Native handler
                        handle = ontype && cur[ ontype ];
                        if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
                                event.result = handle.apply( cur, data );
                                if ( event.result === false ) {
                                        event.preventDefault();
                                }
                        }
                }
                event.type = type;

                // If nobody prevented the default action, do it now
                if ( !onlyHandlers && !event.isDefaultPrevented() ) {

                        if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
                                jQuery.acceptData( elem ) ) {

                                // Call a native DOM method on the target with the same name name as the event.
                                // Don't do default actions on window, that's where global variables be (#6170)
                                if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {

                                        // Don't re-trigger an onFOO event when we call its FOO() method
                                        tmp = elem[ ontype ];

                                        if ( tmp ) {
                                                elem[ ontype ] = null;
                                        }

                                        // Prevent re-triggering of the same event, since we already bubbled it above
                                        jQuery.event.triggered = type;
                                        elem[ type ]();
                                        jQuery.event.triggered = undefined;

                                        if ( tmp ) {
                                                elem[ ontype ] = tmp;
                                        }
                                }
                        }
                }

                return event.result;
        },

        dispatch: function( event ) {

                // Make a writable jQuery.Event from the native event object
                event = jQuery.event.fix( event );

                var i, j, ret, matched, handleObj,
                        handlerQueue = [],
                        args = slice.call( arguments ),
                        handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
                        special = jQuery.event.special[ event.type ] || {};

                // Use the fix-ed jQuery.Event rather than the (read-only) native event
                args[0] = event;
                event.delegateTarget = this;

                // Call the preDispatch hook for the mapped type, and let it bail if desired
                if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
                        return;
                }

                // Determine handlers
                handlerQueue = jQuery.event.handlers.call( this, event, handlers );

                // Run delegates first; they may want to stop propagation beneath us
                i = 0;
                while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
                        event.currentTarget = matched.elem;

                        j = 0;
                        while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {

                                // Triggered event must either 1) have no namespace, or 2) have namespace(s)
                                // a subset or equal to those in the bound event (both can have no namespace).
                                if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {

                                        event.handleObj = handleObj;
                                        event.data = handleObj.data;

                                        ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
                                                        .apply( matched.elem, args );

                                        if ( ret !== undefined ) {
                                                if ( (event.result = ret) === false ) {
                                                        event.preventDefault();
                                                        event.stopPropagation();
                                                }
                                        }
                                }
                        }
                }

                // Call the postDispatch hook for the mapped type
                if ( special.postDispatch ) {
                        special.postDispatch.call( this, event );
                }

                return event.result;
        },

        handlers: function( event, handlers ) {
                var i, matches, sel, handleObj,
                        handlerQueue = [],
                        delegateCount = handlers.delegateCount,
                        cur = event.target;

                // Find delegate handlers
                // Black-hole SVG <use> instance trees (#13180)
                // Avoid non-left-click bubbling in Firefox (#3861)
                if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {

                        for ( ; cur !== this; cur = cur.parentNode || this ) {

                                // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
                                if ( cur.disabled !== true || event.type !== "click" ) {
                                        matches = [];
                                        for ( i = 0; i < delegateCount; i++ ) {
                                                handleObj = handlers[ i ];

                                                // Don't conflict with Object.prototype properties (#13203)
                                                sel = handleObj.selector + " ";

                                                if ( matches[ sel ] === undefined ) {
                                                        matches[ sel ] = handleObj.needsContext ?
                                                                jQuery( sel, this ).index( cur ) >= 0 :
                                                                jQuery.find( sel, this, null, [ cur ] ).length;
                                                }
                                                if ( matches[ sel ] ) {
                                                        matches.push( handleObj );
                                                }
                                        }
                                        if ( matches.length ) {
                                                handlerQueue.push({ elem: cur, handlers: matches });
                                        }
                                }
                        }
                }

                // Add the remaining (directly-bound) handlers
                if ( delegateCount < handlers.length ) {
                        handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
                }

                return handlerQueue;
        },

        // Includes some event props shared by KeyEvent and MouseEvent
        props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),

        fixHooks: {},

        keyHooks: {
                props: "char charCode key keyCode".split(" "),
                filter: function( event, original ) {

                        // Add which for key events
                        if ( event.which == null ) {
                                event.which = original.charCode != null ? original.charCode : original.keyCode;
                        }

                        return event;
                }
        },

        mouseHooks: {
                props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
                filter: function( event, original ) {
                        var eventDoc, doc, body,
                                button = original.button;

                        // Calculate pageX/Y if missing and clientX/Y available
                        if ( event.pageX == null && original.clientX != null ) {
                                eventDoc = event.target.ownerDocument || document;
                                doc = eventDoc.documentElement;
                                body = eventDoc.body;

                                event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
                                event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
                        }

                        // Add which for click: 1 === left; 2 === middle; 3 === right
                        // Note: button is not normalized, so don't use it
                        if ( !event.which && button !== undefined ) {
                                event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
                        }

                        return event;
                }
        },

        fix: function( event ) {
                if ( event[ jQuery.expando ] ) {
                        return event;
                }

                // Create a writable copy of the event object and normalize some properties
                var i, prop, copy,
                        type = event.type,
                        originalEvent = event,
                        fixHook = this.fixHooks[ type ];

                if ( !fixHook ) {
                        this.fixHooks[ type ] = fixHook =
                                rmouseEvent.test( type ) ? this.mouseHooks :
                                rkeyEvent.test( type ) ? this.keyHooks :
                                {};
                }
                copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;

                event = new jQuery.Event( originalEvent );

                i = copy.length;
                while ( i-- ) {
                        prop = copy[ i ];
                        event[ prop ] = originalEvent[ prop ];
                }

                // Support: Cordova 2.5 (WebKit) (#13255)
                // All events should have a target; Cordova deviceready doesn't
                if ( !event.target ) {
                        event.target = document;
                }

                // Support: Safari 6.0+, Chrome<28
                // Target should not be a text node (#504, #13143)
                if ( event.target.nodeType === 3 ) {
                        event.target = event.target.parentNode;
                }

                return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
        },

        special: {
                load: {
                        // Prevent triggered image.load events from bubbling to window.load
                        noBubble: true
                },
                focus: {
                        // Fire native event if possible so blur/focus sequence is correct
                        trigger: function() {
                                if ( this !== safeActiveElement() && this.focus ) {
                                        this.focus();
                                        return false;
                                }
                        },
                        delegateType: "focusin"
                },
                blur: {
                        trigger: function() {
                                if ( this === safeActiveElement() && this.blur ) {
                                        this.blur();
                                        return false;
                                }
                        },
                        delegateType: "focusout"
                },
                click: {
                        // For checkbox, fire native event so checked state will be right
                        trigger: function() {
                                if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
                                        this.click();
                                        return false;
                                }
                        },

                        // For cross-browser consistency, don't fire native .click() on links
                        _default: function( event ) {
                                return jQuery.nodeName( event.target, "a" );
                        }
                },

                beforeunload: {
                        postDispatch: function( event ) {

                                // Support: Firefox 20+
                                // Firefox doesn't alert if the returnValue field is not set.
                                if ( event.result !== undefined && event.originalEvent ) {
                                        event.originalEvent.returnValue = event.result;
                                }
                        }
                }
        },

        simulate: function( type, elem, event, bubble ) {
                // Piggyback on a donor event to simulate a different one.
                // Fake originalEvent to avoid donor's stopPropagation, but if the
                // simulated event prevents default then we do the same on the donor.
                var e = jQuery.extend(
                        new jQuery.Event(),
                        event,
                        {
                                type: type,
                                isSimulated: true,
                                originalEvent: {}
                        }
                );
                if ( bubble ) {
                        jQuery.event.trigger( e, null, elem );
                } else {
                        jQuery.event.dispatch.call( elem, e );
                }
                if ( e.isDefaultPrevented() ) {
                        event.preventDefault();
                }
        }
};

jQuery.removeEvent = function( elem, type, handle ) {
        if ( elem.removeEventListener ) {
                elem.removeEventListener( type, handle, false );
        }
};

jQuery.Event = function( src, props ) {
        // Allow instantiation without the 'new' keyword
        if ( !(this instanceof jQuery.Event) ) {
                return new jQuery.Event( src, props );
        }

        // Event object
        if ( src && src.type ) {
                this.originalEvent = src;
                this.type = src.type;

                // Events bubbling up the document may have been marked as prevented
                // by a handler lower down the tree; reflect the correct value.
                this.isDefaultPrevented = src.defaultPrevented ||
                                src.defaultPrevented === undefined &&
                                // Support: Android<4.0
                                src.returnValue === false ?
                        returnTrue :
                        returnFalse;

        // Event type
        } else {
                this.type = src;
        }

        // Put explicitly provided properties onto the event object
        if ( props ) {
                jQuery.extend( this, props );
        }

        // Create a timestamp if incoming event doesn't have one
        this.timeStamp = src && src.timeStamp || jQuery.now();

        // Mark it as fixed
        this[ jQuery.expando ] = true;
};

// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
jQuery.Event.prototype = {
        isDefaultPrevented: returnFalse,
        isPropagationStopped: returnFalse,
        isImmediatePropagationStopped: returnFalse,

        preventDefault: function() {
                var e = this.originalEvent;

                this.isDefaultPrevented = returnTrue;

                if ( e && e.preventDefault ) {
                        e.preventDefault();
                }
        },
        stopPropagation: function() {
                var e = this.originalEvent;

                this.isPropagationStopped = returnTrue;

                if ( e && e.stopPropagation ) {
                        e.stopPropagation();
                }
        },
        stopImmediatePropagation: function() {
                var e = this.originalEvent;

                this.isImmediatePropagationStopped = returnTrue;

                if ( e && e.stopImmediatePropagation ) {
                        e.stopImmediatePropagation();
                }

                this.stopPropagation();
        }
};

// Create mouseenter/leave events using mouseover/out and event-time checks
// Support: Chrome 15+
jQuery.each({
        mouseenter: "mouseover",
        mouseleave: "mouseout",
        pointerenter: "pointerover",
        pointerleave: "pointerout"
}, function( orig, fix ) {
        jQuery.event.special[ orig ] = {
                delegateType: fix,
                bindType: fix,

                handle: function( event ) {
                        var ret,
                                target = this,
                                related = event.relatedTarget,
                                handleObj = event.handleObj;

                        // For mousenter/leave call the handler if related is outside the target.
                        // NB: No relatedTarget if the mouse left/entered the browser window
                        if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
                                event.type = handleObj.origType;
                                ret = handleObj.handler.apply( this, arguments );
                                event.type = fix;
                        }
                        return ret;
                }
        };
});

// Support: Firefox, Chrome, Safari
// Create "bubbling" focus and blur events
if ( !support.focusinBubbles ) {
        jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {

                // Attach a single capturing handler on the document while someone wants focusin/focusout
                var handler = function( event ) {
                                jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
                        };

                jQuery.event.special[ fix ] = {
                        setup: function() {
                                var doc = this.ownerDocument || this,
                                        attaches = data_priv.access( doc, fix );

                                if ( !attaches ) {
                                        doc.addEventListener( orig, handler, true );
                                }
                                data_priv.access( doc, fix, ( attaches || 0 ) + 1 );
                        },
                        teardown: function() {
                                var doc = this.ownerDocument || this,
                                        attaches = data_priv.access( doc, fix ) - 1;

                                if ( !attaches ) {
                                        doc.removeEventListener( orig, handler, true );
                                        data_priv.remove( doc, fix );

                                } else {
                                        data_priv.access( doc, fix, attaches );
                                }
                        }
                };
        });
}

jQuery.fn.extend({

        on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
                var origFn, type;

                // Types can be a map of types/handlers
                if ( typeof types === "object" ) {
                        // ( types-Object, selector, data )
                        if ( typeof selector !== "string" ) {
                                // ( types-Object, data )
                                data = data || selector;
                                selector = undefined;
                        }
                        for ( type in types ) {
                                this.on( type, selector, data, types[ type ], one );
                        }
                        return this;
                }

                if ( data == null && fn == null ) {
                        // ( types, fn )
                        fn = selector;
                        data = selector = undefined;
                } else if ( fn == null ) {
                        if ( typeof selector === "string" ) {
                                // ( types, selector, fn )
                                fn = data;
                                data = undefined;
                        } else {
                                // ( types, data, fn )
                                fn = data;
                                data = selector;
                                selector = undefined;
                        }
                }
                if ( fn === false ) {
                        fn = returnFalse;
                } else if ( !fn ) {
                        return this;
                }

                if ( one === 1 ) {
                        origFn = fn;
                        fn = function( event ) {
                                // Can use an empty set, since event contains the info
                                jQuery().off( event );
                                return origFn.apply( this, arguments );
                        };
                        // Use same guid so caller can remove using origFn
                        fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
                }
                return this.each( function() {
                        jQuery.event.add( this, types, fn, data, selector );
                });
        },
        one: function( types, selector, data, fn ) {
                return this.on( types, selector, data, fn, 1 );
        },
        off: function( types, selector, fn ) {
                var handleObj, type;
                if ( types && types.preventDefault && types.handleObj ) {
                        // ( event )  dispatched jQuery.Event
                        handleObj = types.handleObj;
                        jQuery( types.delegateTarget ).off(
                                handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
                                handleObj.selector,
                                handleObj.handler
                        );
                        return this;
                }
                if ( typeof types === "object" ) {
                        // ( types-object [, selector] )
                        for ( type in types ) {
                                this.off( type, selector, types[ type ] );
                        }
                        return this;
                }
                if ( selector === false || typeof selector === "function" ) {
                        // ( types [, fn] )
                        fn = selector;
                        selector = undefined;
                }
                if ( fn === false ) {
                        fn = returnFalse;
                }
                return this.each(function() {
                        jQuery.event.remove( this, types, fn, selector );
                });
        },

        trigger: function( type, data ) {
                return this.each(function() {
                        jQuery.event.trigger( type, data, this );
                });
        },
        triggerHandler: function( type, data ) {
                var elem = this[0];
                if ( elem ) {
                        return jQuery.event.trigger( type, data, elem, true );
                }
        }
});

return jQuery;
});