Skip to content

Commit 9921e7f

Browse files
committed
fix(jqLite): camelCase keys in jqLite#data
This change aligns jqLite with jQuery 3. Close angular#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 b9c338d commit 9921e7f

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)