Change the way jQuery.data works so that there is no longer a chance of collision between user data and internal data. Fixes #6968.

This commit is contained in:
Colin Snover 2011-01-09 15:52:33 -06:00
parent 1d1d4fe112
commit 8e59a99e0a
10 changed files with 352 additions and 203 deletions

View file

@ -8,7 +8,8 @@ var rnamespaces = /\.(.*)$/,
fcleanup = function( nm ) {
return nm.replace(rescape, "\\$&");
},
focusCounts = { focusin: 0, focusout: 0 };
focusCounts = { focusin: 0, focusout: 0 },
eventKey = "events";
/*
* A number of helper functions used for managing events.
@ -50,7 +51,7 @@ jQuery.event = {
}
// Init the element's event structure
var elemData = jQuery.data( elem );
var elemData = jQuery._data( elem );
// If no elemData is found then we must be trying to bind to one of the
// banned noData elements
@ -58,10 +59,7 @@ jQuery.event = {
return;
}
// Use a key less likely to result in collisions for plain JS objects.
// Fixes bug #7150.
var eventKey = elem.nodeType ? "events" : "__events__",
events = elemData[ eventKey ],
var events = elemData[ eventKey ],
eventHandle = elemData.handle;
if ( typeof events === "function" ) {
@ -177,8 +175,7 @@ jQuery.event = {
}
var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
eventKey = elem.nodeType ? "events" : "__events__",
elemData = jQuery.data( elem ),
elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
events = elemData && elemData[ eventKey ];
if ( !elemData || !events ) {
@ -290,10 +287,10 @@ jQuery.event = {
delete elemData.handle;
if ( typeof elemData === "function" ) {
jQuery.removeData( elem, eventKey );
jQuery.removeData( elem, eventKey, true );
} else if ( jQuery.isEmptyObject( elemData ) ) {
jQuery.removeData( elem );
jQuery.removeData( elem, undefined, true );
}
}
},
@ -325,9 +322,16 @@ jQuery.event = {
// Only trigger if we've ever bound an event for it
if ( jQuery.event.global[ type ] ) {
// XXX This code smells terrible. event.js should not be directly
// inspecting the data cache
jQuery.each( jQuery.cache, function() {
if ( this.events && this.events[type] ) {
jQuery.event.trigger( event, data, this.handle.elem );
// internalKey variable is just used to make it easier to find
// and potentially change this stuff later; currently it just
// points to jQuery.expando
var internalKey = jQuery.expando,
internalCache = this[ internalKey ];
if ( internalCache && internalCache.events && internalCache.events[type] ) {
jQuery.event.trigger( event, data, internalCache.handle.elem );
}
});
}
@ -353,8 +357,8 @@ jQuery.event = {
// Trigger the event, it is assumed that "handle" is a function
var handle = elem.nodeType ?
jQuery.data( elem, "handle" ) :
(jQuery.data( elem, "__events__" ) || {}).handle;
jQuery._data( elem, "handle" ) :
(jQuery._data( elem, eventKey ) || {}).handle;
if ( handle ) {
handle.apply( elem, data );
@ -432,7 +436,7 @@ jQuery.event = {
event.namespace = event.namespace || namespace_sort.join(".");
events = jQuery.data(this, this.nodeType ? "events" : "__events__");
events = jQuery._data(this, eventKey);
if ( typeof events === "function" ) {
events = events.events;
@ -787,12 +791,12 @@ if ( !jQuery.support.changeBubbles ) {
return;
}
data = jQuery.data( elem, "_change_data" );
data = jQuery._data( elem, "_change_data" );
val = getVal(elem);
// the current data will be also retrieved by beforeactivate
if ( e.type !== "focusout" || elem.type !== "radio" ) {
jQuery.data( elem, "_change_data", val );
jQuery._data( elem, "_change_data", val );
}
if ( data === undefined || val === data ) {
@ -837,7 +841,7 @@ if ( !jQuery.support.changeBubbles ) {
// information
beforeactivate: function( e ) {
var elem = e.target;
jQuery.data( elem, "_change_data", getVal(elem) );
jQuery._data( elem, "_change_data", getVal(elem) );
}
},
@ -986,8 +990,8 @@ jQuery.fn.extend({
return this.click( jQuery.proxy( fn, function( event ) {
// Figure out which function to execute
var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
// Make sure that clicks stop
event.preventDefault();
@ -1075,7 +1079,7 @@ function liveHandler( event ) {
var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
elems = [],
selectors = [],
events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
events = jQuery._data( this, eventKey );
if ( typeof events === "function" ) {
events = events.events;