]> git.wh0rd.org - tt-rss.git/blob - lib/dojo/dnd/Selector.js.uncompressed.js
update dojo to 1.7.3
[tt-rss.git] / lib / dojo / dnd / Selector.js.uncompressed.js
1 define("dojo/dnd/Selector", ["../main", "./common", "./Container"], function(dojo) {
2 // module:
3 // dojo/dnd/Selector
4 // summary:
5 // TODOC
6
7
8 /*
9 Container item states:
10 "" - an item is not selected
11 "Selected" - an item is selected
12 "Anchor" - an item is selected, and is an anchor for a "shift" selection
13 */
14
15 /*=====
16 dojo.declare("dojo.dnd.__SelectorArgs", [dojo.dnd.__ContainerArgs], {
17 // singular: Boolean
18 // allows selection of only one element, if true
19 singular: false,
20
21 // autoSync: Boolean
22 // autosynchronizes the source with its list of DnD nodes,
23 autoSync: false
24 });
25 =====*/
26
27 dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
28 // summary:
29 // a Selector object, which knows how to select its children
30
31 /*=====
32 // selection: Set<String>
33 // The set of id's that are currently selected, such that this.selection[id] == 1
34 // if the node w/that id is selected. Can iterate over selected node's id's like:
35 // | for(var id in this.selection)
36 selection: {},
37 =====*/
38
39 constructor: function(node, params){
40 // summary:
41 // constructor of the Selector
42 // node: Node||String
43 // node or node's id to build the selector on
44 // params: dojo.dnd.__SelectorArgs?
45 // a dictionary of parameters
46 if(!params){ params = {}; }
47 this.singular = params.singular;
48 this.autoSync = params.autoSync;
49 // class-specific variables
50 this.selection = {};
51 this.anchor = null;
52 this.simpleSelection = false;
53 // set up events
54 this.events.push(
55 dojo.connect(this.node, "onmousedown", this, "onMouseDown"),
56 dojo.connect(this.node, "onmouseup", this, "onMouseUp"));
57 },
58
59 // object attributes (for markup)
60 singular: false, // is singular property
61
62 // methods
63 getSelectedNodes: function(){
64 // summary:
65 // returns a list (an array) of selected nodes
66 var t = new dojo.NodeList();
67 var e = dojo.dnd._empty;
68 for(var i in this.selection){
69 if(i in e){ continue; }
70 t.push(dojo.byId(i));
71 }
72 return t; // NodeList
73 },
74 selectNone: function(){
75 // summary:
76 // unselects all items
77 return this._removeSelection()._removeAnchor(); // self
78 },
79 selectAll: function(){
80 // summary:
81 // selects all items
82 this.forInItems(function(data, id){
83 this._addItemClass(dojo.byId(id), "Selected");
84 this.selection[id] = 1;
85 }, this);
86 return this._removeAnchor(); // self
87 },
88 deleteSelectedNodes: function(){
89 // summary:
90 // deletes all selected items
91 var e = dojo.dnd._empty;
92 for(var i in this.selection){
93 if(i in e){ continue; }
94 var n = dojo.byId(i);
95 this.delItem(i);
96 dojo.destroy(n);
97 }
98 this.anchor = null;
99 this.selection = {};
100 return this; // self
101 },
102 forInSelectedItems: function(/*Function*/ f, /*Object?*/ o){
103 // summary:
104 // iterates over selected items;
105 // see `dojo.dnd.Container.forInItems()` for details
106 o = o || dojo.global;
107 var s = this.selection, e = dojo.dnd._empty;
108 for(var i in s){
109 if(i in e){ continue; }
110 f.call(o, this.getItem(i), i, this);
111 }
112 },
113 sync: function(){
114 // summary:
115 // sync up the node list with the data map
116
117 dojo.dnd.Selector.superclass.sync.call(this);
118
119 // fix the anchor
120 if(this.anchor){
121 if(!this.getItem(this.anchor.id)){
122 this.anchor = null;
123 }
124 }
125
126 // fix the selection
127 var t = [], e = dojo.dnd._empty;
128 for(var i in this.selection){
129 if(i in e){ continue; }
130 if(!this.getItem(i)){
131 t.push(i);
132 }
133 }
134 dojo.forEach(t, function(i){
135 delete this.selection[i];
136 }, this);
137
138 return this; // self
139 },
140 insertNodes: function(addSelected, data, before, anchor){
141 // summary:
142 // inserts new data items (see `dojo.dnd.Container.insertNodes()` method for details)
143 // addSelected: Boolean
144 // all new nodes will be added to selected items, if true, no selection change otherwise
145 // data: Array
146 // a list of data items, which should be processed by the creator function
147 // before: Boolean
148 // insert before the anchor, if true, and after the anchor otherwise
149 // anchor: Node
150 // the anchor node to be used as a point of insertion
151 var oldCreator = this._normalizedCreator;
152 this._normalizedCreator = function(item, hint){
153 var t = oldCreator.call(this, item, hint);
154 if(addSelected){
155 if(!this.anchor){
156 this.anchor = t.node;
157 this._removeItemClass(t.node, "Selected");
158 this._addItemClass(this.anchor, "Anchor");
159 }else if(this.anchor != t.node){
160 this._removeItemClass(t.node, "Anchor");
161 this._addItemClass(t.node, "Selected");
162 }
163 this.selection[t.node.id] = 1;
164 }else{
165 this._removeItemClass(t.node, "Selected");
166 this._removeItemClass(t.node, "Anchor");
167 }
168 return t;
169 };
170 dojo.dnd.Selector.superclass.insertNodes.call(this, data, before, anchor);
171 this._normalizedCreator = oldCreator;
172 return this; // self
173 },
174 destroy: function(){
175 // summary:
176 // prepares the object to be garbage-collected
177 dojo.dnd.Selector.superclass.destroy.call(this);
178 this.selection = this.anchor = null;
179 },
180
181 // mouse events
182 onMouseDown: function(e){
183 // summary:
184 // event processor for onmousedown
185 // e: Event
186 // mouse event
187 if(this.autoSync){ this.sync(); }
188 if(!this.current){ return; }
189 if(!this.singular && !dojo.isCopyKey(e) && !e.shiftKey && (this.current.id in this.selection)){
190 this.simpleSelection = true;
191 if(e.button === dojo.mouseButtons.LEFT){
192 // accept the left button and stop the event
193 // for IE we don't stop event when multiple buttons are pressed
194 dojo.stopEvent(e);
195 }
196 return;
197 }
198 if(!this.singular && e.shiftKey){
199 if(!dojo.isCopyKey(e)){
200 this._removeSelection();
201 }
202 var c = this.getAllNodes();
203 if(c.length){
204 if(!this.anchor){
205 this.anchor = c[0];
206 this._addItemClass(this.anchor, "Anchor");
207 }
208 this.selection[this.anchor.id] = 1;
209 if(this.anchor != this.current){
210 var i = 0;
211 for(; i < c.length; ++i){
212 var node = c[i];
213 if(node == this.anchor || node == this.current){ break; }
214 }
215 for(++i; i < c.length; ++i){
216 var node = c[i];
217 if(node == this.anchor || node == this.current){ break; }
218 this._addItemClass(node, "Selected");
219 this.selection[node.id] = 1;
220 }
221 this._addItemClass(this.current, "Selected");
222 this.selection[this.current.id] = 1;
223 }
224 }
225 }else{
226 if(this.singular){
227 if(this.anchor == this.current){
228 if(dojo.isCopyKey(e)){
229 this.selectNone();
230 }
231 }else{
232 this.selectNone();
233 this.anchor = this.current;
234 this._addItemClass(this.anchor, "Anchor");
235 this.selection[this.current.id] = 1;
236 }
237 }else{
238 if(dojo.isCopyKey(e)){
239 if(this.anchor == this.current){
240 delete this.selection[this.anchor.id];
241 this._removeAnchor();
242 }else{
243 if(this.current.id in this.selection){
244 this._removeItemClass(this.current, "Selected");
245 delete this.selection[this.current.id];
246 }else{
247 if(this.anchor){
248 this._removeItemClass(this.anchor, "Anchor");
249 this._addItemClass(this.anchor, "Selected");
250 }
251 this.anchor = this.current;
252 this._addItemClass(this.current, "Anchor");
253 this.selection[this.current.id] = 1;
254 }
255 }
256 }else{
257 if(!(this.current.id in this.selection)){
258 this.selectNone();
259 this.anchor = this.current;
260 this._addItemClass(this.current, "Anchor");
261 this.selection[this.current.id] = 1;
262 }
263 }
264 }
265 }
266 dojo.stopEvent(e);
267 },
268 onMouseUp: function(e){
269 // summary:
270 // event processor for onmouseup
271 // e: Event
272 // mouse event
273 if(!this.simpleSelection){ return; }
274 this.simpleSelection = false;
275 this.selectNone();
276 if(this.current){
277 this.anchor = this.current;
278 this._addItemClass(this.anchor, "Anchor");
279 this.selection[this.current.id] = 1;
280 }
281 },
282 onMouseMove: function(e){
283 // summary:
284 // event processor for onmousemove
285 // e: Event
286 // mouse event
287 this.simpleSelection = false;
288 },
289
290 // utilities
291 onOverEvent: function(){
292 // summary:
293 // this function is called once, when mouse is over our container
294 this.onmousemoveEvent = dojo.connect(this.node, "onmousemove", this, "onMouseMove");
295 },
296 onOutEvent: function(){
297 // summary:
298 // this function is called once, when mouse is out of our container
299 dojo.disconnect(this.onmousemoveEvent);
300 delete this.onmousemoveEvent;
301 },
302 _removeSelection: function(){
303 // summary:
304 // unselects all items
305 var e = dojo.dnd._empty;
306 for(var i in this.selection){
307 if(i in e){ continue; }
308 var node = dojo.byId(i);
309 if(node){ this._removeItemClass(node, "Selected"); }
310 }
311 this.selection = {};
312 return this; // self
313 },
314 _removeAnchor: function(){
315 if(this.anchor){
316 this._removeItemClass(this.anchor, "Anchor");
317 this.anchor = null;
318 }
319 return this; // self
320 }
321 });
322
323 return dojo.dnd.Selector;
324 });