Commit 7f94a5cc authored by Rick Waldron's avatar Rick Waldron

2.0: Rewrite data.js (Incl. event, manipulation, tests)

parent ed0e2d1e
This diff is collapsed.
...@@ -24,7 +24,7 @@ jQuery.event = { ...@@ -24,7 +24,7 @@ jQuery.event = {
var handleObjIn, eventHandle, tmp, var handleObjIn, eventHandle, tmp,
events, t, handleObj, events, t, handleObj,
special, handlers, type, namespaces, origType, special, handlers, type, namespaces, origType,
elemData = jQuery._data( elem ); elemData = data_priv.get( elem );
// Don't attach events to noData or text/comment nodes (but allow plain objects) // Don't attach events to noData or text/comment nodes (but allow plain objects)
if ( !elemData ) { if ( !elemData ) {
...@@ -130,7 +130,7 @@ jQuery.event = { ...@@ -130,7 +130,7 @@ jQuery.event = {
var j, origCount, tmp, var j, origCount, tmp,
events, t, handleObj, events, t, handleObj,
special, handlers, type, namespaces, origType, special, handlers, type, namespaces, origType,
elemData = jQuery.hasData( elem ) && jQuery._data( elem ); elemData = data_priv.hasData( elem ) && data_priv.get( elem );
if ( !elemData || !(events = elemData.events) ) { if ( !elemData || !(events = elemData.events) ) {
return; return;
......
...@@ -328,7 +328,7 @@ jQuery.fn.extend({ ...@@ -328,7 +328,7 @@ jQuery.fn.extend({
for ( i = 0; i < hasScripts; i++ ) { for ( i = 0; i < hasScripts; i++ ) {
node = scripts[ i ]; node = scripts[ i ];
if ( rscriptType.test( node.type || "" ) && if ( rscriptType.test( node.type || "" ) &&
!jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
if ( node.src ) { if ( node.src ) {
// Hope ajax is available... // Hope ajax is available...
...@@ -511,11 +511,9 @@ jQuery.extend({ ...@@ -511,11 +511,9 @@ jQuery.extend({
}, },
cleanData: function( elems, /* internal */ acceptData ) { cleanData: function( elems, /* internal */ acceptData ) {
var id, data, elem, type, var data, elem, type,
l = elems.length, l = elems.length,
i = 0, i = 0,
internalKey = jQuery.expando,
cache = jQuery.cache,
special = jQuery.event.special; special = jQuery.event.special;
for ( ; i < l; i++ ) { for ( ; i < l; i++ ) {
...@@ -523,8 +521,7 @@ jQuery.extend({ ...@@ -523,8 +521,7 @@ jQuery.extend({
if ( acceptData || jQuery.acceptData( elem ) ) { if ( acceptData || jQuery.acceptData( elem ) ) {
id = elem[ internalKey ]; data = data_priv.access( elem );
data = id && cache[ id ];
if ( data ) { if ( data ) {
for ( type in data.events ) { for ( type in data.events ) {
...@@ -536,14 +533,10 @@ jQuery.extend({ ...@@ -536,14 +533,10 @@ jQuery.extend({
jQuery.removeEvent( elem, type, data.handle ); jQuery.removeEvent( elem, type, data.handle );
} }
} }
// Remove cache only if it was not already removed by jQuery.event.remove
if ( cache[ id ] ) {
delete cache[ id ];
delete elem[ internalKey ];
}
} }
} }
// Discard any remaining `private` and `user` data
data_discard( elem );
} }
} }
}); });
...@@ -576,24 +569,30 @@ function setGlobalEval( elems, refElements ) { ...@@ -576,24 +569,30 @@ function setGlobalEval( elems, refElements ) {
i = 0; i = 0;
for ( ; i < l; i++ ) { for ( ; i < l; i++ ) {
jQuery._data( elems[ i ], "globalEval", !refElements || jQuery._data( refElements[ i ], "globalEval" ) ); data_priv.set(
elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" )
);
} }
} }
function cloneCopyEvent( src, dest ) { function cloneCopyEvent( src, dest ) {
var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { if ( dest.nodeType !== 1 ) {
return; return;
} }
var i, l, type, // 1. Copy private data: events, handlers, etc.
oldData = jQuery._data( src ), if ( data_priv.hasData( src ) ) {
curData = jQuery._data( dest, oldData ), pdataOld = data_priv.access( src );
events = oldData.events; pdataCur = jQuery.extend( {}, pdataOld );
events = pdataOld.events;
data_priv.set( dest, pdataCur );
if ( events ) { if ( events ) {
delete curData.handle; delete pdataCur.handle;
curData.events = {}; pdataCur.events = {};
for ( type in events ) { for ( type in events ) {
for ( i = 0, l = events[ type ].length; i < l; i++ ) { for ( i = 0, l = events[ type ].length; i < l; i++ ) {
...@@ -601,13 +600,18 @@ function cloneCopyEvent( src, dest ) { ...@@ -601,13 +600,18 @@ function cloneCopyEvent( src, dest ) {
} }
} }
} }
}
// 2. Copy user data
if ( data_user.hasData( src ) ) {
udataOld = data_user.access( src );
udataCur = jQuery.extend( {}, udataOld );
// make the cloned public data object a copy from the original data_user.set( dest, udataCur );
if ( curData.data ) {
curData.data = jQuery.extend( {}, curData.data );
} }
} }
function getAll( context, tag ) { function getAll( context, tag ) {
var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) :
context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : context.querySelectorAll ? context.querySelectorAll( tag || "*" ) :
......
<!doctype html>
<html>
<script src="/dist/jquery.js"></script>
<script>
function report( event ) {
var payload = {
event: event.type
};
return top.postMessage( JSON.stringify(payload), "*" );
}
jQuery( window ).on( "beforeunload", function( event ) {
report( event );
}).on( "load", function( event ) {
setTimeout(function() {
window.location.reload();
}, 50);
});
</script>
</html>
...@@ -200,6 +200,10 @@ var Globals = (function() { ...@@ -200,6 +200,10 @@ var Globals = (function() {
*/ */
QUnit.expectJqData = function( elems, key ) { QUnit.expectJqData = function( elems, key ) {
var i, elem, expando; var i, elem, expando;
// As of jQuery 2.0, there will be no "cache"-data is
// stored and managed completely below the API surface
if ( jQuery.cache ) {
QUnit.current_testEnvironment.checkJqData = true; QUnit.current_testEnvironment.checkJqData = true;
if ( elems.jquery && elems.toArray ) { if ( elems.jquery && elems.toArray ) {
...@@ -241,6 +245,8 @@ var Globals = (function() { ...@@ -241,6 +245,8 @@ var Globals = (function() {
} }
} }
} }
}
}; };
QUnit.config.urlConfig.push( { QUnit.config.urlConfig.push( {
id: "jqdata", id: "jqdata",
......
...@@ -6,6 +6,33 @@ test("expando", function(){ ...@@ -6,6 +6,33 @@ test("expando", function(){
equal(jQuery.expando !== undefined, true, "jQuery is exposing the expando"); equal(jQuery.expando !== undefined, true, "jQuery is exposing the expando");
}); });
test( "jQuery.data & removeData, expected returns", function() {
expect(2);
equal(
jQuery.data( document.body, "hello", "world" ), "world",
"jQuery.data( elem, key, value ) returns value"
);
equal(
jQuery.removeData( document.body, "hello" ), undefined,
"jQuery.removeData( elem, key, value ) returns undefined"
);
});
test( "jQuery._data & _removeData, expected returns", function() {
expect(2);
equal(
jQuery._data( document.body, "hello", "world" ), "world",
"jQuery.data( elem, key, value ) returns value"
);
equal(
jQuery._removeData( document.body, "hello" ), undefined,
"jQuery.removeData( elem, key, value ) returns undefined"
);
});
function dataTests (elem) { function dataTests (elem) {
var oldCacheLength, dataObj, internalDataObj, expected, actual; var oldCacheLength, dataObj, internalDataObj, expected, actual;
...@@ -106,6 +133,10 @@ test("Data is not being set on comment and text nodes", function() { ...@@ -106,6 +133,10 @@ test("Data is not being set on comment and text nodes", function() {
ok( !jQuery.hasData( jQuery("<span>text</span>").contents().data("foo", 0) ) ); ok( !jQuery.hasData( jQuery("<span>text</span>").contents().data("foo", 0) ) );
}); });
/*
// Since the new data system does not rely on exandos, limiting the type of
// nodes that can have data is no longer necessary. jQuery.acceptData is now irrelevant
// and should be removed from the library.
test("jQuery.acceptData", function() { test("jQuery.acceptData", function() {
expect(9); expect(9);
...@@ -127,7 +158,7 @@ test("jQuery.acceptData", function() { ...@@ -127,7 +158,7 @@ test("jQuery.acceptData", function() {
ok( !jQuery.acceptData( document.createComment("") ), "comment" ); ok( !jQuery.acceptData( document.createComment("") ), "comment" );
ok( !jQuery.acceptData( document.createTextNode("") ), "text" ); ok( !jQuery.acceptData( document.createTextNode("") ), "text" );
}); });
*/
test(".data()", function() { test(".data()", function() {
expect(5); expect(5);
...@@ -424,7 +455,7 @@ if (window.JSON && window.JSON.stringify) { ...@@ -424,7 +455,7 @@ if (window.JSON && window.JSON.stringify) {
} }
test("jQuery.data should follow html5 specification regarding camel casing", function() { test("jQuery.data should follow html5 specification regarding camel casing", function() {
expect(10); expect(12);
var div = jQuery("<div id='myObject' data-w-t-f='ftw' data-big-a-little-a='bouncing-b' data-foo='a' data-foo-bar='b' data-foo-bar-baz='c'></div>") var div = jQuery("<div id='myObject' data-w-t-f='ftw' data-big-a-little-a='bouncing-b' data-foo='a' data-foo-bar='b' data-foo-bar-baz='c'></div>")
.prependTo("body"); .prependTo("body");
...@@ -445,6 +476,9 @@ test("jQuery.data should follow html5 specification regarding camel casing", fun ...@@ -445,6 +476,9 @@ test("jQuery.data should follow html5 specification regarding camel casing", fun
equal( div.data("fooBar"), "d", "Verify updated data-* key" ); equal( div.data("fooBar"), "d", "Verify updated data-* key" );
equal( div.data("foo-bar"), "d", "Verify updated data-* key" ); equal( div.data("foo-bar"), "d", "Verify updated data-* key" );
equal( div.data("fooBar"), "d", "Verify updated data-* key (fooBar)" );
equal( div.data("foo-bar"), "d", "Verify updated data-* key (foo-bar)" );
div.remove(); div.remove();
}); });
......
...@@ -1371,75 +1371,20 @@ test("Submit event can be stopped (#11049)", function() { ...@@ -1371,75 +1371,20 @@ test("Submit event can be stopped (#11049)", function() {
// Test beforeunload event only if it supported (i.e. not Opera) // Test beforeunload event only if it supported (i.e. not Opera)
if ( window.onbeforeunload === null ) { if ( window.onbeforeunload === null ) {
asyncTest("on(beforeunload)", 4, function() { asyncTest("on(beforeunload)", 1, function() {
var win, var iframe = jQuery(jQuery.parseHTML("<iframe src='data/onbeforeunload.html'><iframe>"));
forIE6 = 0,
fired = false,
iframe = jQuery("<iframe src='data/iframe.html' />");
iframe.appendTo("#qunit-fixture").one( "load", function() { window.onmessage = function( event ) {
win = this.contentWindow || this.contentDocument; var payload = JSON.parse( event.data );
jQuery( win ).on( "beforeunload", function() { ok( payload.event, "beforeunload", "beforeunload event" );
fired = true;
ok( true, "beforeunload event is fired" );
});
strictEqual( win.onbeforeunload, null, "onbeforeunload property on window object still equals null" );
// In old Safari beforeunload event will not fire on iframes
jQuery( win ).on( "unload", function() {
if ( !fired ) {
ok( true, "This is suppose to be true only in old Safari" );
checker();
}
});
jQuery( win ).on( "beforeunload", function() {
// On iframe in IE6 beforeunload event will not fire if event is binded through window object,
// nevertheless, test should continue
window.setTimeout(function() {
if ( !forIE6 ) {
checker();
}
});
});
win.onbeforeunload = function() {
if ( !forIE6 ) {
forIE6++;
checker();
}
};
function checker() {
ok( true, "window.onbeforeunload handler is called" );
iframe = jQuery("<iframe src='data/iframe.html' />");
iframe.appendTo("#qunit-fixture").one( "load", function() {
win = iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument;
jQuery( win ).on( "beforeunload", function() {
strictEqual( win.onbeforeunload, null, "Event handler is fired, even when onbeforeunload property on window is nulled" );
iframe.remove();
window.onmessage = null;
start(); start();
}); };
jQuery( win ).on( "unload", function() {
if ( !fired ) {
jQuery( win ).trigger("beforeunload");
}
});
win.onbeforeunload = null;
win.location.reload();
});
}
win.location.reload(); iframe.appendTo("#qunit-fixture");
});
}); });
} }
......
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