forked from RubyLouvre/mass-Framework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
data.js
182 lines (170 loc) · 5.93 KB
/
data.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//==================================================
// 数据缓存模块
//==================================================
define("data", ["$lang"], function($) {
var owners = [],
caches = [];
/**
* 为目标对象指定一个缓存体
* @param {Any} owner
* @return {Object} 缓存体
* @api private
*/
function add(owner) {
var index = owners.push(owner);
return caches[index - 1] = {
data: {}
};
}
/**
* 为目标对象读写数据
* @param {Any} owner
* @param {Object|String} name ? 要处理的数据或数据包
* @param {Any} data ? 要写入的数据
* @param {Boolean} pvt ? 标识为内部数据
* @return {Any}
* @api private
*/
function innerData(owner, name, data, pvt) { //IE678不能为文本节点注释节点添加数据
var index = owners.indexOf(owner);
var table = index === -1 ? add(owner) : caches[index];
var getOne = typeof name === "string" //取得单个属性
var cache = table;
//私有数据都是直接放到table中,普通数据放到table.data中
if(!pvt) {
table = table.data;
}
if(name && typeof name == "object") {
$.mix(table, name); //写入一组属性
} else if(getOne && data !== void 0) {
table[name] = data; //写入单个属性
}
if(getOne) {
if(name in table) {
return table[name];
} else if(!pvt && owner && owner.nodeType == 1) {
//对于用HTML5 data-*属性保存的数据, 如<input id="test" data-full-name="Planet Earth"/>
//我们可以通过$("#test").data("full-name")或$("#test").data("fullName")访问到
return $.parseData(owner, name, cache);
}
} else {
return table;
}
}
/**
* 为目标对象移除数据
* @param {Any} owner
* @param {Any} name ? 要移除的数据
* @param {Boolean} pvt ? 标识为内部数据
* @return {Any}
* @api private
*/
function innerRemoveData(owner, name, pvt) {
var index = owners.indexOf(owner);
if(index > -1) {
var delOne = typeof name == "string",
table = caches[index],
cache = table,
clear = 1
if(delOne) {
if(!pvt) {
table = table.data;
}
if(table) {
delOne = table[name];
delete table[name];
}
for(var key in cache) {
if(key == "data") {
for(var i in cache.data) {
clear = 0;
break;
}
} else {
clear = 0;
break;
}
}
if(clear) {
owners.splice(index, 1);
caches.splice(index, 1);
}
}
return delOne; //返回被移除的数据
}
}
var rparse = /^(?:null|false|true|NaN|\{.*\}|\[.*\])$/
$.mix({
hasData: function(owner) {
//判定是否关联了数据
return owners.indexOf(owner) > -1;
},
data: function(target, name, data) {
//读写用户数据
return innerData(target, name, data);
},
_data: function(target, name, data) {
//读写内部数据
return innerData(target, name, data, true);
},
removeData: function(target, name) {
//删除用户数据
return innerRemoveData(target, name);
},
_removeData: function(target, name) {
//移除内部数据
return innerRemoveData(target, name, true);
},
parseData: function(target, name, cache, value) {
//将HTML5 data-*的属性转换为更丰富有用的数据类型,并保存起来
var data, _eval, key = $.String.camelize(name);
if(cache && (key in cache)) return cache[key];
if(arguments.length != 4) {
var attr = "data-" + name.replace(/([A-Z])/g, "-$1").toLowerCase();
value = target.getAttribute(attr);
}
if(typeof value === "string") { //转换 /^(?:\{.*\}|null|false|true|NaN)$/
if(rparse.test(value) || +value + "" === value) {
_eval = true;
}
try {
data = _eval ? eval("0," + value) : value;
} catch(e) {
data = value;
}
if(cache) {
cache[key] = data;
}
}
return data;
},
mergeData: function(cur, src) {
//合并数据
if($.hasData(cur)) {
var oldData = $._data(src),
curData = $._data(cur),
events = oldData.events;
$.Object.merge(curData, oldData);
if(events) {
curData.events = [];
for(var i = 0, item; item = events[i++];) {
$.event.bind(cur, item);
}
}
}
}
});
return $
});
/**
2011.9.27 uniqueID改为uniqueNumber 简化data与removeData
2011.9.28 添加$._data处理内部数据
2011.10.21 强化mergeData,可以拷贝事件
2012.1.31 简化$.Object.merge的调用
2012.4.5 修正mergeData BUG, 让$.data能获取HTML5 data-*
2012.5.2 $._db -> $["@data]
2012.5.21 抽象出validate私有方法
2012.9.29 对parseData的数据进行严格的验证后才转换 v2
2012.12.30 使用jquery2.0的新思路,通过存放目标的数组的索引值来关联目标与缓存体 v3
2013.1.2 升级到v4
*/