jquery-mobile's `$.Widget.prototype._trigger` is different from jquery-ui's `$.Widget.prototype._trigger` #3853

Closed
zzzzBov opened this Issue Mar 19, 2012 · 2 comments

Comments

Projects
None yet
3 participants

zzzzBov commented Mar 19, 2012

After having just been burned by this minor difference, I thought I'd bring up that jQuery mobile overrides jQuery UI's widget factory, but isn't identical:

In jQuery UI, the $.Widget.prototype._trigger code is:

_trigger: function( type, event, data ) {
    var prop, orig,
        callback = this.options[ type ];

    data = data || {};
    event = $.Event( event );
    event.type = ( type === this.widgetEventPrefix ?
        type :
        this.widgetEventPrefix + type ).toLowerCase();
    // the original event may come from any element
    // so we need to reset the target on the new event
    event.target = this.element[ 0 ];

    // copy original event properties over to the new event
    orig = event.originalEvent;
    if ( orig ) {
        for ( prop in orig ) {
            if ( !( prop in event ) ) {
                event[ prop ] = orig[ prop ];
            }
        }
    }

    this.element.trigger( event, data );

    return !( $.isFunction(callback) &&
        callback.call( this.element[0], event, data ) === false ||
        event.isDefaultPrevented() );
}

Whereas jQuery Mobile uses:

_trigger: function( type, event, data ) {
    var callback = this.options[ type ];

    event = $.Event( event );
    event.type = ( type === this.widgetEventPrefix ?
        type :
        this.widgetEventPrefix + type ).toLowerCase();
    data = data || {};

    // copy original event properties over to the new event
    // this would happen if we could call $.event.fix instead of $.Event
    // but we don't have a way to force an event to be fixed multiple times
    if ( event.originalEvent ) {
        for ( var i = $.event.props.length, prop; i; ) {
            prop = $.event.props[ --i ];
            event[ prop ] = event.originalEvent[ prop ];
        }
    }

    this.element.trigger( event, data );

    return !( $.isFunction(callback) &&
        callback.call( this.element[0], event, data ) === false ||
        event.isDefaultPrevented() );
}

The subtle difference is between how _trigger sets properties on the event. In jQuery UI's version any properties on the old event which are missing from the new event are added to the new event:

    orig = event.originalEvent;
    if ( orig ) {
        for ( prop in orig ) {
            if ( !( prop in event ) ) {
                event[ prop ] = orig[ prop ];
            }
        }
    }

In jQuery mobile's version, all of the properties named in $.event.props that exist on the old event are copied to the new event.

tl; dr:

I had some code to call _trigger as:

_trigger('someevent', {type: 'widgetnamesomeevent', index: 0})

so that I could use:

element.on('widgetnamesomeevent', function (e) {
    console.log(e.index); //should be `0`, but with jQuery mobile is `undefined`
});
Contributor

johnbender commented Mar 19, 2012

Just to be clear we don't override _trigger, it's a vendored version of the UI widget (sadly without information on the version from which it came). We do need to upgrade to pull in bug fixes like this though so the point is well taken. Thanks for logging the issue.

Member

jaspermdegroot commented May 29, 2013

We updated the widget factory. Closing as fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment