Skip to content

Commit 2fb231b

Browse files
committed
support camelized names in data() method
- `data('fooBar')` reads from "data-foo-bar" attribute - data.js plugin is improved to store keys in camelCase form Closes madrobby#471
1 parent 4d27333 commit 2fb231b

File tree

4 files changed

+79
-24
lines changed

4 files changed

+79
-24
lines changed

src/data.js

+25-11
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,45 @@
55
// The following code is heavily inspired by jQuery's $.fn.data()
66

77
;(function($) {
8-
var data = {}, dataAttr = $.fn.data,
8+
var data = {}, dataAttr = $.fn.data, camelize = $.zepto.camelize,
99
uuid = $.uuid = +new Date(),
1010
exp = $.expando = 'Zepto' + uuid
1111

12+
// Get value from node:
13+
// 1. first try key as given,
14+
// 2. then try camelized key,
15+
// 3. fall back to reading "data-*" attribute.
1216
function getData(node, name) {
1317
var id = node[exp], store = id && data[id]
14-
return name === undefined ? store || setData(node) :
15-
(store && store[name]) || dataAttr.call($(node), name)
18+
if (name === undefined) return store || setData(node)
19+
else {
20+
if (store) {
21+
if (name in store) return store[name]
22+
var camelName = camelize(name)
23+
if (camelName in store) return store[camelName]
24+
}
25+
return dataAttr.call($(node), name)
26+
}
1627
}
1728

29+
// Store value under camelized key on node
1830
function setData(node, name, value) {
1931
var id = node[exp] || (node[exp] = ++uuid),
2032
store = data[id] || (data[id] = {})
21-
if (name !== undefined) store[name] = value
33+
if (name !== undefined) store[camelize(name)] = value
2234
return store
2335
}
2436

25-
function setDataAttributes(node, object) {
26-
node.each(function(){ for (var key in object) setData(this, key, object[key]) })
27-
}
28-
2937
$.fn.data = function(name, value) {
3038
return value === undefined ?
31-
this.length == 0 ? undefined :
32-
$.isPlainObject(name) ? setDataAttributes(this, name) : getData(this[0], name) :
33-
this.each(function(idx){ setData(this, name, value) })
39+
// set multiple values via object
40+
$.isPlainObject(name) ?
41+
this.each(function(i, node){
42+
$.each(name, function(key, value){ setData(node, key, value) })
43+
}) :
44+
// get value from first element
45+
this.length == 0 ? undefined : getData(this[0], name) :
46+
// set value on all elements
47+
this.each(function(){ setData(this, name, value) })
3448
}
3549
})(Zepto)

src/zepto.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ var Zepto = (function() {
2929
tagSelectorRE = /^[\w-]+$/,
3030
toString = ({}).toString,
3131
zepto = {},
32-
init, fragment, Z,
32+
camelize, fragment, Z,
3333
tempParent = document.createElement('div')
3434

3535
function matches(element, selector) {
@@ -60,7 +60,7 @@ var Zepto = (function() {
6060

6161
function compact(array) { return array.filter(function(item){ return item !== undefined && item !== null }) }
6262
function flatten(array) { return array.length > 0 ? [].concat.apply([], array) : array }
63-
function camelize(str) { return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) }
63+
camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) }
6464
function dasherize(str) {
6565
return str.replace(/::/g, '/')
6666
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
@@ -423,7 +423,7 @@ var Zepto = (function() {
423423
return this.each(function(){ this.removeAttribute(name) })
424424
},
425425
data: function(name, value){
426-
var data = this.attr('data-' + name, value)
426+
var data = this.attr('data-' + dasherize(name), value)
427427
return data !== null ? data : undefined
428428
},
429429
val: function(value){
@@ -562,6 +562,7 @@ var Zepto = (function() {
562562
Z.prototype = $.fn
563563

564564
// Export internal API functions in the `$.zepto` namespace
565+
zepto.camelize = camelize
565566
$.zepto = zepto
566567

567568
return $

test/data.html

+30-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ <h1>Zepto data() tests</h1>
1616
Running… see browser console for results
1717
</p>
1818
<div id="fixtures">
19-
<div id="data_attr" data-one="uno" data-two="due"></div>
19+
<div id="data_attr" data-one="uno" data-two="due" data-foo-bar="baz"></div>
2020
<div id="data_full" data-mode="awesome"></div>
2121
<div id="data_obj" data-mode="awesome"></div>
2222
<ol id="data_list">
@@ -46,6 +46,20 @@ <h1>Zepto data() tests</h1>
4646
t.assertEqual('uno', el.data('one'))
4747
},
4848

49+
testCamelized: function(t){
50+
var el = $('#data_attr')
51+
t.assertEqual('baz', el.data('foo-bar'))
52+
t.assertEqual('baz', el.data('fooBar'))
53+
54+
el.data('fooBar', 'bam')
55+
t.assertEqual('bam', el.data('foo-bar'))
56+
t.assertEqual('bam', el.data('fooBar'))
57+
58+
el.data('a-b', 'c')
59+
t.assertEqual('c', el.data().aB)
60+
t.assertUndefined(el.data()['a-b'])
61+
},
62+
4963
testNotChangingAttribute: function(t){
5064
var el = $('#data_attr')
5165
t.assertEqual('due', el.data('two'))
@@ -106,6 +120,21 @@ <h1>Zepto data() tests</h1>
106120
t.assertUndefined(all.mode)
107121
},
108122

123+
testGettingBlanks: function(t){
124+
var el = $('#data_attr'),
125+
store = el.data()
126+
127+
store.nil = null
128+
store.undef = undefined
129+
store.blank = ''
130+
store.bool = false
131+
132+
t.assertNull(el.data('nil'))
133+
t.assertUndefined(el.data('undef'))
134+
t.assertIdentical('', el.data('blank'))
135+
t.assertFalse(el.data('bool'))
136+
},
137+
109138
testSettingDataWithObj: function(t){
110139
var el = $('#data_obj')
111140

test/zepto.html

+20-9
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ <h1>Zepto DOM unit tests</h1>
4949
<div id="attr_remove" data-name="boom"></div>
5050
<form><input id="attr_val" value="Hello World"></form>
5151

52-
<div id="data_attr" data-blah="whatever" data-empty></div>
52+
<div id="data_attr" data-foo="bar" data-foo-bar="baz" data-empty></div>
5353

5454
<form id="attr_with_text_input">
5555
<input value="Default input">
@@ -1255,14 +1255,25 @@ <h1>Zepto DOM unit tests</h1>
12551255
},
12561256

12571257
testData: function(t) {
1258-
var els = $('#data_attr')
1259-
els.data('fun', 'hello')
1260-
t.assertEqual('hello', els.attr('data-fun'))
1261-
1262-
t.assertEqual('hello', els.data('fun'))
1263-
t.assertEqual('whatever', els.data('blah'))
1264-
1265-
t.assertUndefined($('body').data('does-not-exist'))
1258+
var el = $('#data_attr')
1259+
// existing attribute
1260+
t.assertEqual('bar', el.data('foo'))
1261+
t.assertEqual('baz', el.data('foo-bar'))
1262+
t.assertEqual('baz', el.data('fooBar'))
1263+
1264+
// camelCase
1265+
el.data('fooBar', 'bam')
1266+
t.assertEqual('bam', el.data('fooBar'))
1267+
t.assertEqual('bam', el.data('foo-bar'))
1268+
1269+
// new attribute
1270+
el.data('fun', 'hello')
1271+
t.assertEqual('hello', el.attr('data-fun'))
1272+
t.assertEqual('hello', el.data('fun'))
1273+
1274+
// blank values
1275+
t.assertIdentical('', el.data('empty'))
1276+
t.assertUndefined(el.data('does-not-exist'))
12661277
},
12671278

12681279
testVal: function(t) {

0 commit comments

Comments
 (0)