+ return dataAttr.call($(node), name)
+ }
+ }
+
+ // Store value under camelized key on node
+ function setData(node, name, value) {
+ var id = node[exp] || (node[exp] = ++$.uuid),
+ store = data[id] || (data[id] = attributeData(node))
+ if (name !== undefined) store[camelize(name)] = value
+ return store
+ }
+
+ // Read all "data-*" attributes from a node
+ function attributeData(node) {
+ var store = {}
+ $.each(node.attributes || emptyArray, function(i, attr){
+ if (attr.name.indexOf('data-') == 0)
+ store[camelize(attr.name.replace('data-', ''))] =
+ $.zepto.deserializeValue(attr.value)
+ })
+ return store
+ }
+
+ $.fn.data = function(name, value) {
+ return value === undefined ?
+ // set multiple values via object
+ $.isPlainObject(name) ?
+ this.each(function(i, node){
+ $.each(name, function(key, value){ setData(node, key, value) })
+ }) :
+ // get value from first element
+ (0 in this ? getData(this[0], name) : undefined) :
+ // set value on all elements
+ this.each(function(){ setData(this, name, value) })
+ }
+
+ $.fn.removeData = function(names) {
+ if (typeof names == 'string') names = names.split(/\s+/)
+ return this.each(function(){
+ var id = this[exp], store = id && data[id]
+ if (store) $.each(names || store, function(key){
+ delete store[names ? camelize(this) : key]
+ })