Skip to content

Commit 72b195b

Browse files
committed
refactor(data): 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: elem.data('my-key', 2); elem.data('myKey', 3); AFTER: // 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);
1 parent 99b2dde commit 72b195b

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
@@ -392,6 +392,7 @@ function jqLiteExpandoStore(element, createIfNecessary) {
392392

393393
function jqLiteData(element, key, value) {
394394
if (jqLiteAcceptsData(element)) {
395+
var prop;
395396

396397
var isSimpleSetter = isDefined(value);
397398
var isSimpleGetter = !isSimpleSetter && key && !isObject(key);
@@ -400,16 +401,18 @@ function jqLiteData(element, key, value) {
400401
var data = expandoStore && expandoStore.data;
401402

402403
if (isSimpleSetter) { // data('key', value)
403-
data[key] = value;
404+
data[kebabToCamel(key)] = value;
404405
} else {
405406
if (massGetter) { // data()
406407
return data;
407408
} else {
408409
if (isSimpleGetter) { // data('key')
409410
// don't force creation of expandoStore if it doesn't exist yet
410-
return data && data[key];
411+
return data && data[kebabToCamel(key)];
411412
} else { // mass-setter: data({key1: val1, key2: val2})
412-
extend(data, key);
413+
for (prop in key) {
414+
data[kebabToCamel(prop)] = key[prop];
415+
}
413416
}
414417
}
415418
}

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)