]> git.wh0rd.org - tt-rss.git/blame - lib/dojo/NodeList-data.js.uncompressed.js
make precache_headlines_idle() start slower
[tt-rss.git] / lib / dojo / NodeList-data.js.uncompressed.js
CommitLineData
1354d172
AD
1define("dojo/NodeList-data", [
2 "./_base/kernel", "./query", "./_base/lang", "./_base/array", "./dom-attr"
3], function(dojo, query, lang, array, attr) {
4 // module:
5 // dojo/NodeList-data
6 // summary:
7 // TODOC
8
9var NodeList = query.NodeList;
10/*=====
11// doc alias helpers:
12var NodeList = dojo.NodeList;
13
14 dojo.NodeList.prototype.data = function(key, value){
15 // summary: stash or get some arbitrary data on/from these nodes.
16 //
17 // description:
18 // Stash or get some arbirtrary data on/from these nodes. This private _data function is
19 // exposed publicly on `dojo.NodeList`, eg: as the result of a `dojo.query` call.
20 // DIFFERS from jQuery.data in that when used as a getter, the entire list is ALWAYS
21 // returned. EVEN WHEN THE LIST IS length == 1.
22 //
23 // A single-node version of this function is provided as `dojo._nodeData`, which follows
24 // the same signature, though expects a String ID or DomNode reference in the first
25 // position, before key/value arguments.
26 //
27 // node: String|DomNode
28 // The node to associate data with
29 //
30 // key: Object?|String?
31 // If an object, act as a setter and iterate over said object setting data items as defined.
32 // If a string, and `value` present, set the data for defined `key` to `value`
33 // If a string, and `value` absent, act as a getter, returning the data associated with said `key`
34 //
35 // value: Anything?
36 // The value to set for said `key`, provided `key` is a string (and not an object)
37 //
38 // example:
39 // Set a key `bar` to some data, then retrieve it.
40 // | dojo.query(".foo").data("bar", "touched");
41 // | var touched = dojo.query(".foo").data("bar");
42 // | if(touched[0] == "touched"){ alert('win'); }
43 //
44 // example:
45 // Get all the data items for a given node.
46 // | var list = dojo.query(".foo").data();
47 // | var first = list[0];
48 //
49 // example:
50 // Set the data to a complex hash. Overwrites existing keys with new value
51 // | dojo.query(".foo").data({ bar:"baz", foo:"bar" });
52 // Then get some random key:
53 // | dojo.query(".foo").data("foo"); // returns [`bar`]
54 //
55 // returns: Object|Anything|Nothing
56 // When used as a setter via `dojo.NodeList`, a NodeList instance is returned
57 // for further chaning. When used as a getter via `dojo.NodeList` an ARRAY
58 // of items is returned. The items in the array correspond to the elements
59 // in the original list. This is true even when the list length is 1, eg:
60 // when looking up a node by ID (#foo)
61 };
62
63 dojo.NodeList.prototype.removeData = function(key){
64 // summary: Remove the data associated with these nodes.
65 // key: String?
66 // If ommitted, clean all data for this node.
67 // If passed, remove the data item found at `key`
68 };
69
70=====*/
71
72 var dataCache = {}, x = 0, dataattr = "data-dojo-dataid",
73 dopid = function(node){
74 // summary: Return a uniqueish ID for the passed node reference
75 var pid = attr.get(node, dataattr);
76 if(!pid){
77 pid = "pid" + (x++);
78 attr.set(node, dataattr, pid);
79 }
80 return pid;
81 }
82 ;
83
84
85 var dodata = dojo._nodeData = function(node, key, value){
86 // summary: Private helper for dojo.NodeList.data for single node data access. Refer to NodeList.data
87 // documentation for more information.
88 //
89 // node: String|DomNode
90 // The node to associate data with
91 //
92 // key: Object?|String?
93 // If an object, act as a setter and iterate over said object setting data items as defined.
94 // If a string, and `value` present, set the data for defined `key` to `value`
95 // If a string, and `value` absent, act as a getter, returning the data associated with said `key`
96 //
97 // value: Anything?
98 // The value to set for said `key`, provided `key` is a string (and not an object)
99 //
100 var pid = dopid(node), r;
101 if(!dataCache[pid]){ dataCache[pid] = {}; }
102
103 // API discrepency: calling with only a node returns the whole object. $.data throws
104 if(arguments.length == 1){ r = dataCache[pid]; }
105 if(typeof key == "string"){
106 // either getter or setter, based on `value` presence
107 if(arguments.length > 2){
108 dataCache[pid][key] = value;
109 }else{
110 r = dataCache[pid][key];
111 }
112 }else{
113 // must be a setter, mix `value` into data hash
114 // API discrepency: using object as setter works here
115 r = lang.mixin(dataCache[pid], key);
116 }
117
118 return r; // Object|Anything|Nothing
119 };
120
121 var removeData = dojo._removeNodeData = function(node, key){
122 // summary: Remove some data from this node
123 // node: String|DomNode
124 // The node reference to remove data from
125 // key: String?
126 // If omitted, remove all data in this dataset.
127 // If passed, remove only the passed `key` in the associated dataset
128 var pid = dopid(node);
129 if(dataCache[pid]){
130 if(key){
131 delete dataCache[pid][key];
132 }else{
133 delete dataCache[pid];
134 }
135 }
136 };
137
138 dojo._gcNodeData = function(){
139 // summary: super expensive: GC all data in the data for nodes that no longer exist in the dom.
140 // description:
141 // super expensive: GC all data in the data for nodes that no longer exist in the dom.
142 // MUCH safer to do this yourself, manually, on a per-node basis (via `NodeList.removeData()`)
143 // provided as a stop-gap for exceptionally large/complex applications with constantly changing
144 // content regions (eg: a dijit.layout.ContentPane with replacing data)
145 // There is NO automatic GC going on. If you dojo.destroy() a node, you should _removeNodeData
146 // prior to destruction.
147 var livePids = query("[" + dataattr + "]").map(dopid);
148 for(var i in dataCache){
149 if(array.indexOf(livePids, i) < 0){ delete dataCache[i]; }
150 }
151 };
152
153 // make nodeData and removeNodeData public on dojo.NodeList:
154 lang.extend(NodeList, {
155 data: NodeList._adaptWithCondition(dodata, function(a){
156 return a.length === 0 || a.length == 1 && (typeof a[0] == "string");
157 }),
158 removeData: NodeList._adaptAsForEach(removeData)
159 });
160
161// TODO: this is the basic implemetation of adaptWithCondtionAndWhenMappedConsiderLength, for lack of a better API name
162// it conflicts with the the `dojo.NodeList` way: always always return an arrayLike thinger. Consider for 2.0:
163//
164// NodeList.prototype.data = function(key, value){
165// var a = arguments, r;
166// if(a.length === 0 || a.length == 1 && (typeof a[0] == "string")){
167// r = this.map(function(node){
168// return d._data(node, key);
169// });
170// if(r.length == 1){ r = r[0]; } // the offending line, and the diff on adaptWithCondition
171// }else{
172// r = this.forEach(function(node){
173// d._data(node, key, value);
174// });
175// }
176// return r; // dojo.NodeList|Array|SingleItem
177// };
178
179 return NodeList;
180
181});