Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Make sure that .data() (no args) returns a list of all the data- prop…

…erties as well. Also make sure that accessing a data- property via .data() doesn't cause it to change again at a later time (it should be static). Fixes #7222, #7223.
  • Loading branch information...
commit 8a5df39045292397a06d08b4fab2ad29819b5d44 1 parent a7d0b0b
John Resig jeresig authored

Showing 2 changed files with 66 additions and 23 deletions. Show diff stats Hide diff stats

  1. +45 21 src/data.js
  2. +21 2 test/unit/data.js
66 src/data.js
@@ -135,7 +135,23 @@ jQuery.extend({
135 135 jQuery.fn.extend({
136 136 data: function( key, value ) {
137 137 if ( typeof key === "undefined" ) {
138   - return this.length ? jQuery.data( this[0] ) : null;
  138 + var data = null;
  139 +
  140 + if ( this.length ) {
  141 + var attr = this[0].attributes, name;
  142 + data = jQuery.data( this[0] );
  143 +
  144 + for ( var i = 0, l = attr.length; i < l; i++ ) {
  145 + name = attr[i].name;
  146 +
  147 + if ( name.indexOf( "data-" ) === 0 ) {
  148 + name = name.substr( 5 );
  149 + dataAttr( this[0], name, data[ name ] );
  150 + }
  151 + }
  152 + }
  153 +
  154 + return data;
139 155
140 156 } else if ( typeof key === "object" ) {
141 157 return this.each(function() {
@@ -152,26 +168,7 @@ jQuery.fn.extend({
152 168 // Try to fetch any internally stored data first
153 169 if ( data === undefined && this.length ) {
154 170 data = jQuery.data( this[0], key );
155   -
156   - // If nothing was found internally, try to fetch any
157   - // data from the HTML5 data-* attribute
158   - if ( data === undefined && this[0].nodeType === 1 ) {
159   - data = this[0].getAttribute( "data-" + key );
160   -
161   - if ( typeof data === "string" ) {
162   - try {
163   - data = data === "true" ? true :
164   - data === "false" ? false :
165   - data === "null" ? null :
166   - !jQuery.isNaN( data ) ? parseFloat( data ) :
167   - rbrace.test( data ) ? jQuery.parseJSON( data ) :
168   - data;
169   - } catch( e ) {}
170   -
171   - } else {
172   - data = undefined;
173   - }
174   - }
  171 + data = dataAttr( this[0], key, data );
175 172 }
176 173
177 174 return data === undefined && parts[1] ?
@@ -196,4 +193,31 @@ jQuery.fn.extend({
196 193 }
197 194 });
198 195
  196 +function dataAttr( elem, key, data ) {
  197 + // If nothing was found internally, try to fetch any
  198 + // data from the HTML5 data-* attribute
  199 + if ( data === undefined && elem.nodeType === 1 ) {
  200 + data = elem.getAttribute( "data-" + key );
  201 +
  202 + if ( typeof data === "string" ) {
  203 + try {
  204 + data = data === "true" ? true :
  205 + data === "false" ? false :
  206 + data === "null" ? null :
  207 + !jQuery.isNaN( data ) ? parseFloat( data ) :
  208 + rbrace.test( data ) ? jQuery.parseJSON( data ) :
  209 + data;
  210 + } catch( e ) {}
  211 +
  212 + // Make sure we set the data so it isn't changed later
  213 + jQuery.data( elem, key, data );
  214 +
  215 + } else {
  216 + data = undefined;
  217 + }
  218 + }
  219 +
  220 + return data;
  221 +}
  222 +
199 223 })( jQuery );
23 test/unit/data.js
@@ -184,14 +184,17 @@ test(".data(String) and .data(String, Object)", function() {
184 184 });
185 185
186 186 test("data-* attributes", function() {
187   - expect(27);
  187 + expect(33);
188 188 var div = jQuery("<div>"),
189   - child = jQuery("<div data-myobj='old data' data-ignored=\"DOM\"></div>");
  189 + child = jQuery("<div data-myobj='old data' data-ignored=\"DOM\" data-other='test'></div>");
190 190
191 191 equals( div.data("attr"), undefined, "Check for non-existing data-attr attribute" );
192 192
193 193 div.attr("data-attr", "exists");
194 194 equals( div.data("attr"), "exists", "Check for existing data-attr attribute" );
  195 +
  196 + div.attr("data-attr", "exists2");
  197 + equals( div.data("attr"), "exists", "Check that updates to data- don't update .data()" );
195 198
196 199 div.data("attr", "internal").attr("data-attr", "external");
197 200 equals( div.data("attr"), "internal", "Check for .data('attr') precedence (internal > external data-* attribute)" );
@@ -205,6 +208,22 @@ test("data-* attributes", function() {
205 208 child.data("ignored", "cache");
206 209 equals( child.data("ignored"), "cache", "Cached data used before DOM data-* fallback");
207 210
  211 + var obj = child.data(), check = [ "myobj", "ignored", "other" ], num = 0;
  212 +
  213 + for ( var i = 0, l = check.length; i < l; i++ ) {
  214 + ok( obj[ check[i] ], "Make sure data- property exists when calling data-." );
  215 + }
  216 +
  217 + for ( var prop in obj ) {
  218 + num++;
  219 + }
  220 +
  221 + equals( num, check.length, "Make sure that the right number of properties came through." );
  222 +
  223 + child.attr("data-other", "newvalue");
  224 +
  225 + equals( child.data("other"), "test", "Make sure value was pulled in properly from a .data()." );
  226 +
208 227 child
209 228 .attr("data-true", "true")
210 229 .attr("data-false", "false")

0 comments on commit 8a5df39

Anton M.

JSLint doesn't like this. It now complains on Line 166 of src/data.js that data is already defined.

Please sign in to comment.
Something went wrong with that request. Please try again.