Commit f28c774f authored by Colin Snover's avatar Colin Snover

Update cloneCopyEvent so that it does not create superfluous data objects when...

Update cloneCopyEvent so that it does not create superfluous data objects when cloning elements. Exposes a new method, $.hasData. Fixes #7165. Thanks to DaveMethvin and iliakan for their help.
parents 291b1edf a2bf7ab3
...@@ -21,6 +21,14 @@ jQuery.extend({ ...@@ -21,6 +21,14 @@ jQuery.extend({
"applet": true "applet": true
}, },
hasData: function( elem ) {
if ( elem.nodeType ) {
elem = jQuery.cache[ elem[jQuery.expando] ];
}
return !!elem && !jQuery.isEmptyObject(elem);
},
data: function( elem, name, data ) { data: function( elem, name, data ) {
if ( !jQuery.acceptData( elem ) ) { if ( !jQuery.acceptData( elem ) ) {
return; return;
......
...@@ -370,14 +370,18 @@ function root( elem, cur ) { ...@@ -370,14 +370,18 @@ function root( elem, cur ) {
} }
function cloneCopyEvent(orig, ret) { function cloneCopyEvent(orig, ret) {
var i = 0; ret.each(function (nodeIndex) {
if ( this.nodeType !== 1 || !jQuery.hasData(orig[nodeIndex]) ) {
ret.each(function() {
if ( this.nodeType !== 1 || this.nodeName !== (orig[i] && orig[i].nodeName) ) {
return; return;
} }
var oldData = jQuery.data( orig[i++] ), // XXX remove for 1.5 RC or merge back in if there is actually a reason for this check that has been
// unexposed by unit tests
if ( this.nodeName !== (orig[nodeIndex] && orig[nodeIndex].nodeName) ) {
throw "Cloned data mismatch";
}
var oldData = jQuery.data( orig[nodeIndex] ),
curData = jQuery.data( this, oldData ), curData = jQuery.data( this, oldData ),
events = oldData && oldData.events; events = oldData && oldData.events;
......
...@@ -78,6 +78,21 @@ test("jQuery.data", function() { ...@@ -78,6 +78,21 @@ test("jQuery.data", function() {
ok( jQuery.data( window, "BAD" ), "Make sure that the value was set." ); ok( jQuery.data( window, "BAD" ), "Make sure that the value was set." );
}); });
test("jQuery.hasData", function() {
expect(6);
function testData(obj) {
equals( jQuery.hasData(obj), false, "No data exists" );
jQuery.data( obj, "foo", "bar" );
equals( jQuery.hasData(obj), true, "Data exists" );
jQuery.removeData( obj, "foo" );
equals( jQuery.hasData(obj), false, "Data was removed" );
}
testData(document.createElement('div'));
testData({});
});
test(".data()", function() { test(".data()", function() {
expect(5); expect(5);
......
...@@ -51,7 +51,7 @@ test("text(Function) with incoming value", function() { ...@@ -51,7 +51,7 @@ test("text(Function) with incoming value", function() {
}); });
var testWrap = function(val) { var testWrap = function(val) {
expect(18); expect(19);
var defaultText = 'Try them out:' var defaultText = 'Try them out:'
var result = jQuery('#first').wrap(val( '<div class="red"><span></span></div>' )).text(); var result = jQuery('#first').wrap(val( '<div class="red"><span></span></div>' )).text();
equals( defaultText, result, 'Check for wrapping of on-the-fly html' ); equals( defaultText, result, 'Check for wrapping of on-the-fly html' );
...@@ -80,10 +80,20 @@ var testWrap = function(val) { ...@@ -80,10 +80,20 @@ var testWrap = function(val) {
equals( jQuery("#nonnodes > i").text(), j.text(), "Check node,textnode,comment wraps doesn't hurt text" ); equals( jQuery("#nonnodes > i").text(), j.text(), "Check node,textnode,comment wraps doesn't hurt text" );
// Try wrapping a disconnected node // Try wrapping a disconnected node
var cacheLength = 0;
for (var i in jQuery.cache) {
cacheLength++;
}
j = jQuery("<label/>").wrap(val( "<li/>" )); j = jQuery("<label/>").wrap(val( "<li/>" ));
equals( j[0].nodeName.toUpperCase(), "LABEL", "Element is a label" ); equals( j[0].nodeName.toUpperCase(), "LABEL", "Element is a label" );
equals( j[0].parentNode.nodeName.toUpperCase(), "LI", "Element has been wrapped" ); equals( j[0].parentNode.nodeName.toUpperCase(), "LI", "Element has been wrapped" );
for (i in jQuery.cache) {
cacheLength--;
}
equals(cacheLength, 0, "No memory leak in jQuery.cache (bug #7165)");
// Wrap an element containing a text node // Wrap an element containing a text node
j = jQuery("<span/>").wrap("<div>test</div>"); j = jQuery("<span/>").wrap("<div>test</div>");
equals( j[0].previousSibling.nodeType, 3, "Make sure the previous node is a text element" ); equals( j[0].previousSibling.nodeType, 3, "Make sure the previous node is a text element" );
...@@ -856,7 +866,7 @@ test("replaceAll(String|Element|Array&lt;Element&gt;|jQuery)", function() { ...@@ -856,7 +866,7 @@ test("replaceAll(String|Element|Array&lt;Element&gt;|jQuery)", function() {
}); });
test("clone()", function() { test("clone()", function() {
expect(36); expect(37);
equals( 'This is a normal link: Yahoo', jQuery('#en').text(), 'Assert text for #en' ); equals( 'This is a normal link: Yahoo', jQuery('#en').text(), 'Assert text for #en' );
var clone = jQuery('#yahoo').clone(); var clone = jQuery('#yahoo').clone();
equals( 'Try them out:Yahoo', jQuery('#first').append(clone).text(), 'Check for clone' ); equals( 'Try them out:Yahoo', jQuery('#first').append(clone).text(), 'Check for clone' );
...@@ -914,10 +924,12 @@ test("clone()", function() { ...@@ -914,10 +924,12 @@ test("clone()", function() {
equals( clone.html(), div.html(), "Element contents cloned" ); equals( clone.html(), div.html(), "Element contents cloned" );
equals( clone[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" ); equals( clone[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" );
div = jQuery("<div/>").data({ a: true, b: true }); div = jQuery("<div/>").data({ a: true });
div = div.clone(true); var div2 = div.clone(true);
equals( div.data("a"), true, "Data cloned." ); equals( div2.data("a"), true, "Data cloned." );
equals( div.data("b"), true, "Data cloned." ); div2.data("a", false);
equals( div2.data("a"), false, "Ensure cloned element data object was correctly modified" );
equals( div.data("a"), true, "Ensure cloned element data object is copied, not referenced" );
var form = document.createElement("form"); var form = document.createElement("form");
form.action = "/test/"; form.action = "/test/";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment