Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit fc0c11d

Browse files
mgolpetebacondarwin
authored andcommitted
fix(jqLite): camelCase keys in jqLite#data
This change aligns jqLite with jQuery 3. The relevant bit of jQuery code is https://github.com/jquery/jquery/blob/3.1.1/src/data/Data.js Close #15126 BREAKING CHANGE: Previously, keys passed to the data method were left untouched. Now they are internally camelCased similarly to how jQuery handles it, i.e. only single (!) hyphens followed by a lowercase letter get converted to an uppercase letter. This means keys `a-b` and `aB` represent the same data piece; writing to one of them will also be reflected if you ask for the other one. If you use Angular with jQuery, it already behaved in this way so no changes are required on your part. To migrate the code follow the examples below: BEFORE: /* 1 */ elem.data('my-key', 2); elem.data('myKey', 3); /* 2 */ elem.data('foo-bar', 42); elem.data()['foo-bar']; // 42 elem.data()['fooBar']; // undefined /* 3 */ elem.data()['foo-bar'] = 1; elem.data()['fooBar'] = 2; elem.data()['foo-bar']; // 1 AFTER: /* 1 */ // Rename one of the keys as they would now map to the same data slot. elem.data('my-key', 2); elem.data('my-key2', 3); /* 2 */ elem.data('foo-bar', 42); elem.data()['foo-bar']; // undefined elem.data()['fooBar']; // 42 /* 3 */ elem.data()['foo-bar'] = 1; elem.data()['fooBar'] = 2; elem.data()['foo-bar']; // 2
1 parent 73050cd commit fc0c11d

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

src/jqLite.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ function jqLiteExpandoStore(element, createIfNecessary) {
394394

395395
function jqLiteData(element, key, value) {
396396
if (jqLiteAcceptsData(element)) {
397+
var prop;
397398

398399
var isSimpleSetter = isDefined(value);
399400
var isSimpleGetter = !isSimpleSetter && key && !isObject(key);
@@ -402,16 +403,18 @@ function jqLiteData(element, key, value) {
402403
var data = expandoStore && expandoStore.data;
403404

404405
if (isSimpleSetter) { // data('key', value)
405-
data[key] = value;
406+
data[kebabToCamel(key)] = value;
406407
} else {
407408
if (massGetter) { // data()
408409
return data;
409410
} else {
410411
if (isSimpleGetter) { // data('key')
411412
// don't force creation of expandoStore if it doesn't exist yet
412-
return data && data[key];
413+
return data && data[kebabToCamel(key)];
413414
} else { // mass-setter: data({key1: val1, key2: val2})
414-
extend(data, key);
415+
for (prop in key) {
416+
data[kebabToCamel(prop)] = key[prop];
417+
}
415418
}
416419
}
417420
}

test/jqLiteSpec.js

+33
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,39 @@ describe('jqLite', function() {
594594
}).not.toThrow();
595595
});
596596
});
597+
598+
describe('camelCasing keys', function() {
599+
// jQuery 2.x has different behavior; skip the tests.
600+
if (isJQuery2x()) return;
601+
602+
it('should camelCase the key in a setter', function() {
603+
var element = jqLite(a);
604+
605+
element.data('a-B-c-d-42--e', 'z-x');
606+
expect(element.data()).toEqual({'a-BCD-42-E': 'z-x'});
607+
});
608+
609+
it('should camelCase the key in a getter', function() {
610+
var element = jqLite(a);
611+
612+
element.data()['a-BCD-42-E'] = 'x-c';
613+
expect(element.data('a-B-c-d-42--e')).toBe('x-c');
614+
});
615+
616+
it('should camelCase the key in a mass setter', function() {
617+
var element = jqLite(a);
618+
619+
element.data({'a-B-c-d-42--e': 'c-v', 'r-t-v': 42});
620+
expect(element.data()).toEqual({'a-BCD-42-E': 'c-v', 'rTV': 42});
621+
});
622+
623+
it('should ignore non-camelCase keys in the data in a getter', function() {
624+
var element = jqLite(a);
625+
626+
element.data()['a-b'] = 'b-n';
627+
expect(element.data('a-b')).toBe(undefined);
628+
});
629+
});
597630
});
598631

599632

0 commit comments

Comments
 (0)