Bug Tracker

Ticket #3662: event-object[5953].diff

File event-object[5953].diff, 12.1 KB (added by flesler, 13 years ago)
  • src/event.js

     
    155155                }
    156156        },
    157157
    158         trigger: function(type, data, elem, donative, extra) {
    159                 // Clone the incoming data, if any
    160                 data = jQuery.makeArray(data);
    161 
    162                 if ( type.indexOf("!") >= 0 ) {
    163                         type = type.slice(0, -1);
    164                         var exclusive = true;
    165                 }
    166 
     158        trigger: function( e, args, elem, donative, extra) {
     159                // Event object or event type
     160                var type = e.type || e;
     161               
    167162                // Handle a global trigger
    168163                if ( !elem ) {
    169164                        // Only trigger if we've ever bound an event for it
    170165                        if ( this.global[type] )
    171166                                jQuery.each( jQuery.cache, function(){
    172167                                        if ( this.events && this.events[type] )
    173                                                 jQuery.event.trigger( type, data, this.handle.elem );
     168                                                jQuery.event.trigger( type, args, this.handle.elem );
    174169                                });
    175170
    176171                // Handle triggering a single element
    177172                } else {
     173
    178174                        // don't do events on text and comment nodes
    179175                        if ( elem.nodeType == 3 || elem.nodeType == 8 )
    180                                 return undefined;
     176                                return;
    181177
    182                         var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
    183                                 // Check to see if we need to provide a fake event, or not
    184                                 event = !data[0] || !data[0].preventDefault;
    185 
    186                         // Pass along a fake event
    187                         if ( event ) {
    188                                 data.unshift({
    189                                         type: type,
    190                                         target: elem,
    191                                         preventDefault: function(){},
    192                                         stopPropagation: function(){},
    193                                         stopImmediatePropagation:stopImmediatePropagation,
    194                                         timeStamp: now()
    195                                 });
    196                                 data[0][expando] = true; // no need to fix fake event
     178                        // Clone the incoming args, if any
     179                        args = jQuery.makeArray(args);
     180                       
     181                        if ( type.indexOf("!") >= 0 ) {
     182                                type = type.slice(0, -1);
     183                                var exclusive = true;
    197184                        }
     185                       
     186                        if( !e.type )
     187                                e = new jQuery.Event(type);
     188                        e.target = elem;
     189                        e.exclusive = exclusive;
     190                       
     191                        args.unshift( e );
    198192
    199                         // Enforce the right trigger type
    200                         data[0].type = type;
    201                         if ( exclusive )
    202                                 data[0].exclusive = true;
     193                        var val, ret, fn = jQuery.isFunction( elem[ type ] );
    203194
    204195                        // Trigger the event, it is assumed that "handle" is a function
    205196                        var handle = jQuery.data(elem, "handle");
    206197                        if ( handle )
    207                                 val = handle.apply( elem, data );
     198                                val = handle.apply( elem, args );
    208199
    209200                        // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
    210                         if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
     201                        if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, args ) === false )
    211202                                val = false;
    212203
    213204                        // Extra functions don't get the custom event object
    214                         if ( event )
    215                                 data.shift();
     205                        args.shift();
    216206
    217207                        // Handle triggering of extra function
    218208                        if ( extra && jQuery.isFunction( extra ) ) {
    219209                                // call the extra function and tack the current return value on the end for possible inspection
    220                                 ret = extra.apply( elem, val == null ? data : data.concat( val ) );
     210                                ret = extra.apply( elem, val == null ? args : args.concat( val ) );
    221211                                // if anything is returned, give it precedence and have it overwrite the previous value
    222212                                if ( ret !== undefined )
    223213                                        val = ret;
     
    239229        },
    240230
    241231        handle: function(event) {
    242                 // returned undefined or false
    243                 var val, ret, namespace, all, handlers;
    244 
    245232                event = arguments[0] = jQuery.event.fix( event || window.event );
    246233
     234                var val,
     235                        ns = event.type.split("."),
     236                        // Cache this now, all = true means, any handler
     237                        all = !ns[1] && !event.exclusive,
     238                        handlers = ( jQuery.data(this, "events") || {} )[ns[0]];
     239
    247240                // Namespaced event handlers
    248                 namespace = event.type.split(".");
    249                 event.type = namespace[0];
    250                 namespace = namespace[1];
    251                 // Cache this now, all = true means, any handler
    252                 all = !namespace && !event.exclusive;
     241                event.type = ns[0];
     242                ns = ns[1];
    253243
    254                 handlers = ( jQuery.data(this, "events") || {} )[event.type];
    255 
    256244                for ( var j in handlers ) {
    257245                        var handler = handlers[j];
    258246
    259247                        // Filter the functions by class
    260                         if ( all || handler.type == namespace ) {
     248                        if ( all || handler.type == ns ) {
    261249                                // Pass in a reference to the handler function itself
    262250                                // So that we can later remove it
    263251                                event.handler = handler;
    264252                                event.data = handler.data;
    265253
    266                                 ret = handler.apply( this, arguments );
     254                                var ret = handler.apply( this, arguments );
    267255
    268256                                if ( val !== false )
    269257                                        val = ret;
     
    282270                return val;
    283271        },
    284272
    285         props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" "),
     273        props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement type view wheelDelta which".split(" "),
    286274
    287275        fix: function(event) {
    288276                if ( event[expando] )
     
    291279                // store a copy of the original event object
    292280                // and "clone" to set read-only properties
    293281                var originalEvent = event;
    294                 event = { originalEvent: originalEvent };
     282                event = new jQuery.Event( originalEvent );
    295283
    296284                for ( var i = this.props.length, prop; i; ){
    297285                        prop = this.props[ --i ];
    298286                        event[ prop ] = originalEvent[ prop ];
    299287                }
    300288
    301                 // Mark it as fixed
    302                 event[expando] = true;
    303 
    304                 // add preventDefault and stopPropagation since
    305                 // they will not work on the clone
    306                 event.preventDefault = function() {
    307                         // if preventDefault exists run it on the original event
    308                         if (originalEvent.preventDefault)
    309                                 originalEvent.preventDefault();
    310                         // otherwise set the returnValue property of the original event to false (IE)
    311                         originalEvent.returnValue = false;
    312                 };
    313                 event.stopPropagation = function() {
    314                         // if stopPropagation exists run it on the original event
    315                         if (originalEvent.stopPropagation)
    316                                 originalEvent.stopPropagation();
    317                         // otherwise set the cancelBubble property of the original event to true (IE)
    318                         originalEvent.cancelBubble = true;
    319                 };
    320 
    321                 event.stopImmediatePropagation = stopImmediatePropagation;
    322 
    323                 // Fix timeStamp
    324                 event.timeStamp = event.timeStamp || now();
    325 
    326289                // Fix target property, if necessary
    327290                if ( !event.target )
    328291                        event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
     
    374337        }
    375338};
    376339
    377 function stopImmediatePropagation(){
    378         this._sip = 1;
    379         this.stopPropagation();
    380 }
     340jQuery.Event = function( src ){
     341        // Event object
     342        if( src && src.type ){
     343                this.originalEvent = src;
     344                this.type = src.type;
     345               
     346                // Fix timeStamp
     347                this.timeStamp = src.timeStamp || now();
     348        // Event type
     349        }else
     350                this.type = src;
    381351
     352        // Mark it as fixed
     353        this[expando] = true;
     354};
     355
     356jQuery.Event.prototype = {
     357        // add preventDefault and stopPropagation since
     358        // they will not work on the clone
     359        preventDefault: function() {
     360                if( !this.originalEvent )
     361                        return;
     362                // if preventDefault exists run it on the original event
     363                if (this.originalEvent.preventDefault)
     364                        this.originalEvent.preventDefault();
     365                // otherwise set the returnValue property of the original event to false (IE)
     366                this.originalEvent.returnValue = false;
     367        },
     368        stopPropagation: function() {
     369                if( !this.originalEvent )
     370                        return;
     371                // if stopPropagation exists run it on the original event
     372                if (this.originalEvent.stopPropagation)
     373                        this.originalEvent.stopPropagation();
     374                // otherwise set the cancelBubble property of the original event to true (IE)
     375                this.originalEvent.cancelBubble = true;
     376        },
     377        stopImmediatePropagation:function(){
     378                this._sip = 1;
     379                this.stopPropagation();
     380        }
     381};
     382
    382383if ( !jQuery.browser.msie ){   
    383384        // Checks if an event happened on an element within another element
    384385        // Used in jQuery.event.special.mouseenter and mouseleave handlers
  • test/unit/event.js

     
    182182});
    183183
    184184test("trigger(event, [data], [fn])", function() {
    185         expect(67);
     185        expect(62);
    186186
    187187        var handler = function(event, a, b, c) {
    188188                equals( event.type, "click", "check passed data" );
     
    213213                equals( c, "abc", "check passed data" );
    214214                equals( v, "test", "check current value" );
    215215        };
     216       
     217        var $elem = jQuery("#firstp");
    216218
    217219        // Simulate a "native" click
    218         jQuery("#firstp")[0].click = function(){
     220        $elem[0].click = function(){
    219221                ok( true, "Native call was triggered" );
    220222        };
    221223
    222224        // Triggers handlrs and native
    223225        // Trigger 5
    224         jQuery("#firstp").bind("click", handler).trigger("click", [1, "2", "abc"]);
     226        $elem.bind("click", handler).trigger("click", [1, "2", "abc"]);
    225227
    226228        // Triggers handlers, native, and extra fn
    227229        // Triggers 9
    228         jQuery("#firstp").trigger("click", [1, "2", "abc"], handler4);
     230        $elem.trigger("click", [1, "2", "abc"], handler4);
    229231
    230232        // Simulate a "native" click
    231         jQuery("#firstp")[0].click = function(){
     233        $elem[0].click = function(){
    232234                ok( false, "Native call was triggered" );
    233235        };
    234236
    235         // Triggers handlers, native, and extra fn
    236         // Triggers 7
    237         jQuery("#firstp").trigger("click", [1, "2", "abc"], handler2);
    238 
    239237        // Trigger only the handlers (no native)
    240238        // Triggers 5
    241         equals( jQuery("#firstp").triggerHandler("click", [1, "2", "abc"]), "test", "Verify handler response" );
     239        equals( $elem.triggerHandler("click", [1, "2", "abc"]), "test", "Verify handler response" );
    242240
    243241        // Trigger only the handlers (no native) and extra fn
    244242        // Triggers 8
    245         equals( jQuery("#firstp").triggerHandler("click", [1, "2", "abc"], handler2), false, "Verify handler response" );
     243        equals( $elem.triggerHandler("click", [1, "2", "abc"], handler2), false, "Verify handler response" );
    246244
    247245        // Build fake click event to pass in
    248         var eventObj = jQuery.event.fix({ type: "foo", target: document.body });
     246        var eventObj = new jQuery.Event("click");
    249247
    250248        // Trigger only the handlers (no native), with external event obj
    251249        // Triggers 5
    252         equals( jQuery("#firstp").triggerHandler("click", [eventObj, 1, "2", "abc"]), "test", "Verify handler response" );
     250        equals( $elem.triggerHandler(eventObj, [1, "2", "abc"]), "test", "Verify handler response" );
    253251
    254252        // Trigger only the handlers (no native) and extra fn, with external event obj
    255253        // Triggers 9
    256         eventObj = jQuery.event.fix({ type: "foo", target: document.body });
    257         equals( jQuery("#firstp").triggerHandler("click", [eventObj, 1, "2", "abc"], handler), "test", "Verify handler response" );
     254        eventObj = new jQuery.Event("click");
     255        equals( $elem.triggerHandler(eventObj, [1, "2", "abc"], handler2), false, "Verify handler response" );
    258256       
    259257        var pass = true;
    260258        try {
     
    268266
    269267        // have the extra handler override the return
    270268        // Triggers 9
    271         equals( jQuery("#firstp").triggerHandler("click", [1, "2", "abc"], handler3), "newVal", "Verify triggerHandler return is overwritten by extra function" );
     269        equals( $elem.triggerHandler("click", [1, "2", "abc"], handler3), "newVal", "Verify triggerHandler return is overwritten by extra function" );
    272270
    273271        // have the extra handler leave the return value alone
    274272        // Triggers 9
    275         equals( jQuery("#firstp").triggerHandler("click", [1, "2", "abc"], handler4), "test", "Verify triggerHandler return is not overwritten by extra function" );
     273        equals( $elem.triggerHandler("click", [1, "2", "abc"], handler4), "test", "Verify triggerHandler return is not overwritten by extra function" );
     274       
     275        eventObj = new jQuery.Event('foo');
     276        eventObj.secret = 'boo!';
     277       
     278        $elem.unbind('click').bind('foo',function(e){
     279                equals( e.type, 'foo', 'Verify event type when passed passing an event object' );
     280                equals( e.target.id, 'firstp', 'Verify event.target when passed passing an event object' );
     281                equals( e.secret, 'boo!', 'Verify event object\'s custom attribute when passed passing an event object' );
     282        });
     283       
     284        $elem.triggerHandler( eventObj );
     285        $elem.unbind('foo');
    276286});
    277287
    278288test("toggle(Function, Function, ...)", function() {