Skip to content

Commit

Permalink
refactor specialAll into add and remove hooks for existing special ev…
Browse files Browse the repository at this point in the history
…ents, live now accepts optional data param like bind, fixes #4612 and #4613, thanks to Mike Helgeson
  • Loading branch information
brandonaaron committed Apr 30, 2009
1 parent 287ecdb commit 71efbdd
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 42 deletions.
75 changes: 34 additions & 41 deletions src/event.js
Expand Up @@ -60,10 +60,15 @@ jQuery.event = {
handler.type = namespaces.slice().sort().join(".");

// Get the current list of functions bound to this event
var handlers = events[ type ];

if ( this.specialAll[ type ] ) {
this.specialAll[ type ].setup.call( elem, data, namespaces );
var handlers = events[ type ],
special = this.special[ type ] || {};

if ( special.add ) {
var modifiedHandler = special.add.call( elem, handler, data, namespaces );
if ( modifiedHandler && jQuery.isFunction( modifiedHandler ) ) {
modifiedHandler.guid = handler.guid;
handler = modifiedHandler;
}
}

// Init the event handler queue
Expand All @@ -73,7 +78,7 @@ jQuery.event = {
// Check for a special event handler
// Only use addEventListener/attachEvent if the special
// events handler returns false
if ( !this.special[ type ] || this.special[ type ].setup.call( elem, data, namespaces ) === false ) {
if ( !special.setup || special.setup.call( elem, data, namespaces ) === false ) {
// Bind the global event handler to the element
if ( elem.addEventListener ) {
elem.addEventListener( type, handle, false );
Expand Down Expand Up @@ -128,9 +133,10 @@ jQuery.event = {
var namespaces = type.split(".");
type = namespaces.shift();
var all = !namespaces.length,
namespace = new RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
namespace = new RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)"),
special = this.special[ type ] || {};

if ( events[type] ) {
if ( events[ type ] ) {
// remove the given handler for the given type
if ( handler ) {
delete events[ type ][ handler.guid ];
Expand All @@ -145,8 +151,8 @@ jQuery.event = {
}
}

if ( this.specialAll[ type ] ) {
this.specialAll[ type ].teardown.call( elem, namespaces );
if ( special.remove ) {
special.remove.call( elem, namespaces );
}

// remove generic event handler if no more handlers exist
Expand Down Expand Up @@ -381,28 +387,17 @@ jQuery.event = {
// Make sure the ready event is setup
setup: bindReady,
teardown: function() {}
}
},

specialAll: {
},

live: {
setup: function( selector, namespaces ) {
jQuery.event.add( this, namespaces[0], liveHandler );
add: function( proxy, data, namespaces ) {
jQuery.extend( proxy, data || {} );
proxy.guid += data.selector + data.live;
jQuery.event.add( this, data.live, liveHandler );
},
teardown: function( namespaces ) {
if ( namespaces.length ) {
var remove = 0, name = new RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");

jQuery.each( (jQuery.data(this, "events").live || {}), function() {
if ( name.test(this.type) ) {
remove++;
}
});

if ( remove < 1 ) {
jQuery.event.remove( this, namespaces[0], liveHandler );
}
}

teardown: function( namespaces ) {
jQuery.event.remove( this, namespaces[0], liveHandler );
}
}
}
Expand Down Expand Up @@ -592,28 +587,25 @@ jQuery.fn.extend({
return this;
},

live: function( type, fn ) {
var proxy = jQuery.event.proxy( fn );
proxy.guid += this.selector + type;

jQuery( this.context ).bind( liveConvert( type, this.selector ), this.selector, proxy );

live: function( type, data, fn ) {
jQuery( this.context ).bind( liveConvert( type, this.selector ), {
data: fn && data, selector: this.selector, live: type
}, fn || data );
return this;
},

die: function( type, fn ) {
jQuery( this.context ).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null );
return this;
}
});

function liveHandler( event ) {
var check = new RegExp("(^|\\.)" + event.type + "(\\.|$)"),
stop = true, elems = [];
var stop = true, elems = [];

jQuery.each( jQuery.data( this, "events" ).live || [], function( i, fn ) {
if ( check.test( fn.type ) ) {
var elem = jQuery( event.target ).closest( fn.data )[0];
if ( fn.live === event.type ) {
var elem = jQuery( event.target ).closest( fn.selector )[0];
if ( elem ) {
elems.push({ elem: elem, fn: fn });
}
Expand All @@ -626,7 +618,8 @@ function liveHandler( event ) {

jQuery.each(elems, function() {
event.currentTarget = this.elem;
if ( this.fn.call( this.elem, event, this.fn.data ) === false ) {
event.data = this.fn.data
if ( this.fn.call( this.elem, event, this.fn.selector ) === false ) {
return (stop = false);
}
});
Expand Down
5 changes: 4 additions & 1 deletion test/unit/event.js
Expand Up @@ -490,7 +490,7 @@ test("toggle(Function, Function, ...)", function() {
});

test(".live()/.die()", function() {
expect(52);
expect(53);

var submit = 0, div = 0, livea = 0, liveb = 0;

Expand Down Expand Up @@ -579,6 +579,9 @@ test(".live()/.die()", function() {
jQuery("#foo").trigger('click');
equals( clicked, 2, "die with a context");

// Test binding with event data
jQuery("#foo").live("click", true, function(e){ equals( e.data, true, "live with event data" ); });
jQuery("#foo").trigger("click").die("click");

// Verify that return false prevents default action
jQuery("#anchor2").live("click", function(){ return false; });
Expand Down

0 comments on commit 71efbdd

Please sign in to comment.