From 445dbd9d95e2df2f3cb454cb20ba3ae7a84e7eaf Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Thu, 3 Jan 2013 20:39:15 -0500 Subject: [PATCH] Revert data.js rewrite. Reverts the following commits: commit f717226b3a44f918eec30b2d59ab257270189bc3 Author: Rick Waldron Date: Mon Dec 31 18:06:38 2012 -0500 Only splice from internal arrays when item actually exists. commit b9cdc4136b688963d1dc4befb169be02a0216ba9 Author: Rick Waldron Date: Mon Dec 31 16:20:35 2012 -0500 Updates to data.js re-write to pass events and manipulation commit d1de3000c6d50c298de14fb1ae3381d75c303723 Author: Rick Waldron Date: Mon Dec 31 15:09:45 2012 -0500 2.0: Rewrite data.js --- src/data.js | 449 +++++++++++++++++++++------------------- src/event.js | 4 +- src/manipulation.js | 60 +++--- test/data/testrunner.js | 113 +++++----- test/unit/data.js | 41 +--- 5 files changed, 326 insertions(+), 341 deletions(-) diff --git a/src/data.js b/src/data.js index e6915e9b8..d5a25ff6c 100644 --- a/src/data.js +++ b/src/data.js @@ -1,182 +1,232 @@ -var user, priv, data_user, data_priv, - rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, rmultiDash = /([A-Z])/g; - -function Data() { - // Nodes|Objects - this.owners = []; - // Data objects - this.cache = []; -} - -Data.prototype = { - add: function( owner ) { - this.owners.push( owner ); - return (this.cache[ this.owners.length - 1 ] = {}); - }, - set: function( owner, data, value ) { - var prop, - index = this.owners.indexOf( owner ); - - if ( index === -1 ) { - this.add( owner ); - index = this.owners.length - 1; - } - if ( typeof data === "string" ) { - this.cache[ index ][ data ] = value; - } else { - - if ( jQuery.isEmptyObject( this.cache[ index ] ) ) { - this.cache[ index ] = data; - } else { - for ( prop in data ) { - this.cache[ index ][ prop ] = data[ prop ]; - } - } - } - return this; - }, - get: function( owner, key ) { - var cache, - index = this.owners.indexOf( owner ); - - // A valid cache is found, or needs to be created. - // New entries will be added and return the current - // empty data object to be used as a return reference - // return this.add( owner ); - cache = index === -1 ? - this.add( owner ) : this.cache[ index ]; - - return key === undefined ? - cache : cache[ key ]; - }, - access: function( owner, key, value ) { - if ( value === undefined && (key && typeof key !== "object") ) { - // Assume this is a request to read the cached data - return this.get( owner, key ); - } else { - - // If only an owner was specified, return the entire - // cache object. - if ( key === undefined ) { - return this.get( owner ); - } - - // Allow setting or extending (existing objects) with an - // object of properties, or a key and val - this.set( owner, key, value ); - return value !== undefined ? value : key; - } - // Otherwise, this is a read request. - return this.get( owner, key ); - }, - remove: function( owner, key ) { - var i, l, name, - camel = jQuery.camelCase, - index = this.owners.indexOf( owner ), - cache = this.cache[ index ]; - - if ( key === undefined ) { - cache = {}; - } else { - if ( cache ) { - // Support array or space separated string of keys - if ( !Array.isArray( key ) ) { - // Try the string as a key before any manipulation - // - - if ( key in cache ) { - name = [ key ]; - } else { - // split the camel cased version by spaces unless a key with the spaces exists - name = camel( key ); - name = name in cache ? - [ name ] : name.split(" "); - } - } else { - // If "name" is an array of keys... - // When data is initially created, via ("key", "val") signature, - // keys will be converted to camelCase. - // Since there is no way to tell _how_ a key was added, remove - // both plain key and camelCase key. #12786 - // This will only penalize the array argument path. - name = key.concat( key.map( camel ) ); - } - i = 0; - l = name.length; - - for ( ; i < l; i++ ) { - delete cache[ name[i] ]; - } - } - } - this.cache[ index ] = cache; - }, - hasData: function( owner ) { - var index = this.owners.indexOf( owner ); - - if ( index > -1 ) { - return !jQuery.isEmptyObject( this.cache[ index ] ); - } - return false; - }, - discard: function( owner ) { - var index = this.owners.indexOf( owner ); - - if ( index >= 0 ) { - this.owners.splice( index, 1 ); - this.cache.splice( index, 1 ); - } - return this; + +function internalData( elem, name, data, pvt /* Internal Use Only */ ){ + if ( !jQuery.acceptData( elem ) ) { + return; } -}; -// This will be used by remove() in manipulation to sever -// remaining references to node objects. One day we'll replace the dual -// arrays with a WeakMap and this won't be an issue. -function data_discard( owner ) { - user.discard( owner ); - priv.discard( owner ); + var thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = core_deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; } -// These may used throughout the jQuery core codebase -user = data_user = new Data(); -priv = data_priv = new Data(); +function internalRemoveData( elem, name, pvt /* For internal use only */ ){ + if ( !jQuery.acceptData( elem ) ) { + return; + } + var thisCache, i, l, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} jQuery.extend({ - acceptData: function() { - return true; - }, + cache: {}, + // Unique for each copy of jQuery on the page // Non-digits removed to match rinlinejQuery expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + hasData: function( elem ) { - return user.hasData( elem ) || priv.hasData( elem ); + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); }, data: function( elem, name, data ) { - return user.access( elem, name, data ); + return internalData( elem, name, data, false ); }, removeData: function( elem, name ) { - return user.remove( elem, name ); + return internalRemoveData( elem, name, false ); }, - // TODO: Replace all calls to _data and _removeData with direct - // calls to - // - // priv.access( elem, name, data ); - // - // priv.remove( elem, name ); - // + // For internal use only. _data: function( elem, name, data ) { - return priv.access( elem, name, data ); + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); }, - _removeData: function( elem, name ) { - return priv.remove( elem, name ); + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; } }); @@ -190,19 +240,20 @@ jQuery.fn.extend({ // Gets all values if ( key === undefined ) { if ( this.length ) { - data = user.get( elem ); + data = jQuery.data( elem ); - if ( elem.nodeType === 1 && !priv.get( elem, "hasDataAttrs" ) ) { + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { attrs = elem.attributes; for ( ; i < attrs.length; i++ ) { name = attrs[i].name; - if ( name.indexOf( "data-" ) === 0 ) { + if ( !name.indexOf( "data-" ) ) { name = jQuery.camelCase( name.substring(5) ); + dataAttr( elem, name, data[ name ] ); } } - priv.set( elem, "hasDataAttrs", true ); + jQuery._data( elem, "parsedAttrs", true ); } } @@ -212,79 +263,37 @@ jQuery.fn.extend({ // Sets multiple values if ( typeof key === "object" ) { return this.each(function() { - user.set( this, key ); + jQuery.data( this, key ); }); } return jQuery.access( this, function( value ) { - var data, - camelKey = jQuery.camelCase( key ); - // Get the Data... if ( value === undefined ) { - - // Attempt to get data from the cache - // with the key as-is - data = user.get( elem, key ); - if ( data !== undefined ) { - return data; - } - - // Attempt to "discover" the data in - // HTML5 custom data-* attrs - data = dataAttr( elem, key, undefined ); - if ( data !== undefined ) { - return data; - } - - // As a last resort, attempt to find - // the data by checking AGAIN, but with - // a camelCased key. - data = user.get( elem, camelKey ); - if ( data !== undefined ) { - return data; - } - - // We tried really hard, but the data doesn't exist. - return undefined; + // Try to fetch any internally stored data first + return elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null; } - // Set the data... this.each(function() { - // First, attempt to store a copy or reference of any - // data that might've been store with a camelCased key. - var data = user.get( this, camelKey ); - - // For HTML5 data-* attribute interop, we have to - // store property names with dashes in a camelCase form. - // This might not apply to all properties...* - user.set( this, camelKey, value ); - - // *... In the case of properties that might ACTUALLY - // have dashes, we need to also store a copy of that - // unchanged property. - if ( /-/.test( key ) && data !== undefined ) { - user.set( this, key, value ); - } + jQuery.data( this, key, value ); }); }, null, value, arguments.length > 1, null, true ); }, removeData: function( key ) { return this.each(function() { - user.remove( this, key ); + jQuery.removeData( this, key ); }); } }); function dataAttr( elem, key, data ) { - var name; - // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { - name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + data = elem.getAttribute( name ); if ( typeof data === "string" ) { @@ -294,12 +303,13 @@ function dataAttr( elem, key, data ) { data === "null" ? null : // Only convert to a number if it doesn't change the string +data + "" === data ? +data : - rbrace.test( data ) ? - JSON.parse( data ) : data; + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; } catch( e ) {} // Make sure we set the data so it isn't changed later - user.set( elem, key, data ); + jQuery.data( elem, key, data ); + } else { data = undefined; } @@ -307,3 +317,20 @@ function dataAttr( elem, key, data ) { return data; } + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} diff --git a/src/event.js b/src/event.js index 4e7f7424c..733e563c2 100644 --- a/src/event.js +++ b/src/event.js @@ -16,7 +16,7 @@ jQuery.event = { t = 0; // Don't attach events to noData or text/comment nodes (allow plain objects tho) - if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = data_priv.get( elem )) ) { + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { return; } @@ -124,7 +124,7 @@ jQuery.event = { var tns, type, origType, namespaces, origCount, j, events, special, eventType, handleObj, t = 0, - elemData = data_priv.hasData( elem ) && data_priv.get( elem ); + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); if ( !elemData || !(events = elemData.events) ) { return; diff --git a/src/manipulation.js b/src/manipulation.js index a121ccbc7..9aea16f9d 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -327,7 +327,7 @@ jQuery.fn.extend({ for ( i = 0; i < hasScripts; i++ ) { node = scripts[ i ]; if ( rscriptType.test( node.type || "" ) && - !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { if ( node.src ) { // Hope ajax is available... @@ -514,16 +514,20 @@ jQuery.extend({ }, cleanData: function( elems, /* internal */ acceptData ) { - var data, elem, type, + var id, data, elem, type, l = elems.length, i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, special = jQuery.event.special; for ( ; i < l; i++ ) { elem = elems[ i ]; if ( acceptData || jQuery.acceptData( elem ) ) { - data = data_priv.access( elem ); + + id = elem[ internalKey ]; + data = id && cache[ id ]; if ( data ) { for ( type in data.events ) { @@ -535,12 +539,14 @@ jQuery.extend({ 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 - // (Splices the data objects out of the internal cache arrays) - data_discard( elem ); } } }); @@ -574,45 +580,35 @@ function setGlobalEval( elems, refElements ) { i = 0; for ( ; i < l; i++ ) { - data_priv.set( - elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) - ); + jQuery._data( elems[ i ], "globalEval", !refElements || jQuery._data( refElements[ i ], "globalEval" ) ); } } function cloneCopyEvent( src, dest ) { - var i, l, type, pOld, pCur, uOld, uCur, events; - if ( dest.nodeType !== 1 ) { + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { return; } - // 1. Copy private data: events, handlers, etc. - if ( data_priv.hasData( src ) ) { - pOld = data_priv.access( src ); - pCur = jQuery.extend( {}, pOld ); - events = pOld.events; + var i, l, type, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; - data_priv.set( dest, pCur ); + if ( events ) { + delete curData.handle; + curData.events = {}; - if ( events ) { - delete pCur.handle; - pCur.events = {}; - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); } } } - // 2. Copy user data - if ( data_user.hasData( src ) ) { - uOld = data_user.access( src ); - uCur = jQuery.extend( {}, uOld ); - - data_user.set( dest, uCur ); + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); } } diff --git a/test/data/testrunner.js b/test/data/testrunner.js index 6c9665867..f7aca724a 100644 --- a/test/data/testrunner.js +++ b/test/data/testrunner.js @@ -200,51 +200,47 @@ var Globals = (function() { */ QUnit.expectJqData = function( elems, key ) { var i, elem, expando; + QUnit.current_testEnvironment.checkJqData = true; - if ( jQuery.cache ) { - QUnit.current_testEnvironment.checkJqData = true; + if ( elems.jquery && elems.toArray ) { + elems = elems.toArray(); + } + if ( !jQuery.isArray( elems ) ) { + elems = [ elems ]; + } - if ( elems.jquery && elems.toArray ) { - elems = elems.toArray(); - } - if ( !jQuery.isArray( elems ) ) { - elems = [ elems ]; + for ( i = 0; i < elems.length; i++ ) { + elem = elems[i]; + + // jQuery.data only stores data for nodes in jQuery.cache, + // for other data targets the data is stored in the object itself, + // in that case we can't test that target for memory leaks. + // But we don't have to since in that case the data will/must will + // be available as long as the object is not garbage collected by + // the js engine, and when it is, the data will be removed with it. + if ( !elem.nodeType ) { + // Fixes false positives for dataTests(window), dataTests({}). + continue; } - for ( i = 0; i < elems.length; i++ ) { - elem = elems[i]; + expando = elem[ jQuery.expando ]; - // jQuery.data only stores data for nodes in jQuery.cache, - // for other data targets the data is stored in the object itself, - // in that case we can't test that target for memory leaks. - // But we don't have to since in that case the data will/must will - // be available as long as the object is not garbage collected by - // the js engine, and when it is, the data will be removed with it. - if ( !elem.nodeType ) { - // Fixes false positives for dataTests(window), dataTests({}). - continue; - } - - expando = elem[ jQuery.expando ]; - - if ( expando === undefined ) { - // In this case the element exists fine, but - // jQuery.data (or internal data) was never (in)directly - // called. - // Since this method was called it means some data was - // expected to be found, but since there is nothing, fail early - // (instead of in teardown). - notStrictEqual( expando, undefined, "Target for expectJqData must have an expando, for else there can be no data to expect." ); + if ( expando === undefined ) { + // In this case the element exists fine, but + // jQuery.data (or internal data) was never (in)directly + // called. + // Since this method was called it means some data was + // expected to be found, but since there is nothing, fail early + // (instead of in teardown). + notStrictEqual( expando, undefined, "Target for expectJqData must have an expando, for else there can be no data to expect." ); + } else { + if ( expectedDataKeys[expando] ) { + expectedDataKeys[expando].push( key ); } else { - if ( expectedDataKeys[expando] ) { - expectedDataKeys[expando].push( key ); - } else { - expectedDataKeys[expando] = [ key ]; - } + expectedDataKeys[expando] = [ key ]; } } } - }; QUnit.config.urlConfig.push( { id: "jqdata", @@ -262,38 +258,33 @@ var Globals = (function() { fragmentsLength = 0, cacheLength = 0; - if ( jQuery.cache ) { - // Only look for jQuery data problems if this test actually - // provided some information to compare against. - if ( QUnit.urlParams.jqdata || this.checkJqData ) { - for ( i in jQuery.cache ) { - expectedKeys = expectedDataKeys[i]; - actualKeys = jQuery.cache[i] ? keys( jQuery.cache[i] ) : jQuery.cache[i]; - if ( !QUnit.equiv( expectedKeys, actualKeys ) ) { - deepEqual( actualKeys, expectedKeys, "Expected keys exist in jQuery.cache" ); - } - delete jQuery.cache[i]; - delete expectedDataKeys[i]; - } - // In case it was removed from cache before (or never there in the first place) - for ( i in expectedDataKeys ) { - deepEqual( expectedDataKeys[i], undefined, "No unexpected keys were left in jQuery.cache (#" + i + ")" ); - delete expectedDataKeys[i]; + // Only look for jQuery data problems if this test actually + // provided some information to compare against. + if ( QUnit.urlParams.jqdata || this.checkJqData ) { + for ( i in jQuery.cache ) { + expectedKeys = expectedDataKeys[i]; + actualKeys = jQuery.cache[i] ? keys( jQuery.cache[i] ) : jQuery.cache[i]; + if ( !QUnit.equiv( expectedKeys, actualKeys ) ) { + deepEqual( actualKeys, expectedKeys, "Expected keys exist in jQuery.cache" ); } + delete jQuery.cache[i]; + delete expectedDataKeys[i]; + } + // In case it was removed from cache before (or never there in the first place) + for ( i in expectedDataKeys ) { + deepEqual( expectedDataKeys[i], undefined, "No unexpected keys were left in jQuery.cache (#" + i + ")" ); + delete expectedDataKeys[i]; } - - // Reset data register - expectedDataKeys = {}; } + // Reset data register + expectedDataKeys = {}; // Allow QUnit.reset to clean up any attached elements before checking for leaks QUnit.reset(); - if ( jQuery.cache ) { - for ( i in jQuery.cache ) { - ++cacheLength; - } + for ( i in jQuery.cache ) { + ++cacheLength; } jQuery.fragments = {}; @@ -343,7 +334,7 @@ var Globals = (function() { } else { delete jQuery.ajaxSettings; } - + // Cleanup globals Globals.cleanup(); diff --git a/test/unit/data.js b/test/unit/data.js index c4eca1660..c09149b65 100644 --- a/test/unit/data.js +++ b/test/unit/data.js @@ -1,38 +1,11 @@ -module( "data", { teardown: moduleTeardown }); +module("data", { teardown: moduleTeardown }); -test( "expando", function() { +test("expando", function(){ expect(1); 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", - "jjQuery.data( elem, key, value ) returns value" - ); - equal( - jQuery.removeData( document.body, "hello" ), undefined, - "jjQuery.removeData( elem, key, value ) returns undefined" - ); - -}); - -test( "jQuery._data & _removeData, expected returns", function() { - expect(2); - - equal( - jQuery._data( document.body, "hello", "world" ), "world", - "jjQuery.data( elem, key, value ) returns value" - ); - equal( - jQuery._removeData( document.body, "hello" ), undefined, - "jjQuery.removeData( elem, key, value ) returns undefined" - ); -}); - function dataTests (elem) { var oldCacheLength, dataObj, internalDataObj, expected, actual; @@ -126,7 +99,6 @@ test("jQuery.data(document)", 25, function() { QUnit.expectJqData(document, "foo"); }); -/* test("Expando cleanup", 4, function() { var expected, actual, div = document.createElement("div"); @@ -160,8 +132,7 @@ test("Expando cleanup", 4, function() { // Clean up unattached element jQuery(div).remove(); }); -*/ -/* + test("jQuery.acceptData", function() { expect(7); @@ -179,7 +150,7 @@ test("jQuery.acceptData", function() { applet.setAttribute("classid", "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"); ok( !jQuery.acceptData( applet ), "applet" ); }); -*/ + test(".data()", function() { expect(5); @@ -494,8 +465,8 @@ test("jQuery.data should follow html5 specification regarding camel casing", fun div.data("foo-bar", "d"); - equal( div.data("fooBar"), "d", "Verify updated data-* key (fooBar)" ); - equal( div.data("foo-bar"), "d", "Verify updated data-* key (foo-bar)" ); + equal( div.data("fooBar"), "d", "Verify updated data-* key" ); + equal( div.data("foo-bar"), "d", "Verify updated data-* key" ); div.remove(); });