OSDN Git Service

original file
[nucleus-jp/nucleus-plugins.git] / trunk / NP_TinyMCE2j / tinymce2j / plugins / filemanager / InsertFile / js / selectableelements.js
1 /*----------------------------------------------------------------------------\
2 |                          Selectable Elements 1.02                           |
3 |-----------------------------------------------------------------------------|
4 |                         Created by Erik Arvidsson                           |
5 |                  (http://webfx.eae.net/contact.html#erik)                   |
6 |                      For WebFX (http://webfx.eae.net/)                      |
7 |-----------------------------------------------------------------------------|
8 |          A script that allows children of any element to be selected        |
9 |-----------------------------------------------------------------------------|
10 |                  Copyright (c) 1999 - 2004 Erik Arvidsson                   |
11 |-----------------------------------------------------------------------------|
12 | This software is provided "as is", without warranty of any kind, express or |
13 | implied, including  but not limited  to the warranties of  merchantability, |
14 | fitness for a particular purpose and noninfringement. In no event shall the |
15 | authors or  copyright  holders be  liable for any claim,  damages or  other |
16 | liability, whether  in an  action of  contract, tort  or otherwise, arising |
17 | from,  out of  or in  connection with  the software or  the  use  or  other |
18 | dealings in the software.                                                   |
19 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
20 | This  software is  available under the  three different licenses  mentioned |
21 | below.  To use this software you must chose, and qualify, for one of those. |
22 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
23 | The WebFX Non-Commercial License          http://webfx.eae.net/license.html |
24 | Permits  anyone the right to use the  software in a  non-commercial context |
25 | free of charge.                                                             |
26 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
27 | The WebFX Commercial license           http://webfx.eae.net/commercial.html |
28 | Permits the  license holder the right to use  the software in a  commercial |
29 | context. Such license must be specifically obtained, however it's valid for |
30 | any number of  implementations of the licensed software.                    |
31 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
32 | GPL - The GNU General Public License    http://www.gnu.org/licenses/gpl.txt |
33 | Permits anyone the right to use and modify the software without limitations |
34 | as long as proper  credits are given  and the original  and modified source |
35 | code are included. Requires  that the final product, software derivate from |
36 | the original  source or any  software  utilizing a GPL  component, such  as |
37 | this, is also licensed under the GPL license.                               |
38 |-----------------------------------------------------------------------------|
39 | 2002-09-19 | Original Version Posted.                                       |
40 | 2002-09-27 | Fixed a bug in IE when mouse down and up occured on different  |
41 |            | rows.                                                          |
42 | 2003-02-11 | Minor problem with addClassName and removeClassName that       |
43 |            | triggered a bug in Opera 7. Added destroy method               |
44 |-----------------------------------------------------------------------------|
45 | Created 2002-09-04 | All changes are in the log above. | Updated 2003-02-11 |
46 \----------------------------------------------------------------------------*/
47
48 function SelectableElements(oElement, bMultiple) {
49         if (oElement == null)
50                 return;
51
52         this._htmlElement = oElement;
53         this._multiple = Boolean(bMultiple);
54
55         this._selectedItems = [];
56         this._fireChange = true;
57
58         var oThis = this;
59         this._onclick = function (e) {
60                 if (e == null) e = oElement.ownerDocument.parentWindow.event;
61                 oThis.click(e);
62         };
63
64         if (oElement.addEventListener)
65                 oElement.addEventListener("click", this._onclick, false);
66         else if (oElement.attachEvent)
67                 oElement.attachEvent("onclick", this._onclick);
68 }
69
70 SelectableElements.prototype.setItemSelected = function (oEl, bSelected) {
71         if (!this._multiple) {
72                 if (bSelected) {
73                         var old = this._selectedItems[0]
74                         if (oEl == old)
75                                 return;
76                         if (old != null)
77                                 this.setItemSelectedUi(old, false);
78                         this.setItemSelectedUi(oEl, true);
79                         this._selectedItems = [oEl];
80                         this.fireChange();
81                 }
82                 else {
83                         if (this._selectedItems[0] == oEl) {
84                                 this.setItemSelectedUi(oEl, false);
85                                 this._selectedItems = [];
86                         }
87                 }
88         }
89         else {
90                 if (Boolean(oEl._selected) == Boolean(bSelected))
91                         return;
92
93                 this.setItemSelectedUi(oEl, bSelected);
94
95                 if (bSelected)
96                         this._selectedItems[this._selectedItems.length] = oEl;
97                 else {
98                         // remove
99                         var tmp = [];
100                         var j = 0;
101                         for (var i = 0; i < this._selectedItems.length; i++) {
102                                 if (this._selectedItems[i] != oEl)
103                                         tmp[j++] = this._selectedItems[i];
104                         }
105                         this._selectedItems = tmp;
106                 }
107                 this.fireChange();
108         }
109 };
110
111 // This method updates the UI of the item
112 SelectableElements.prototype.setItemSelectedUi = function (oEl, bSelected) {
113         if (bSelected)
114                 addClassName(oEl, "selected");
115         else
116                 removeClassName(oEl, "selected");
117
118         oEl._selected = bSelected;
119 };
120
121 SelectableElements.prototype.getItemSelected = function (oEl) {
122         return Boolean(oEl._selected);
123 };
124
125 SelectableElements.prototype.fireChange = function () {
126         if (!this._fireChange)
127                 return;
128         if (typeof this.onchange == "string")
129                 this.onchange = new Function(this.onchange);
130         if (typeof this.onchange == "function")
131                 this.onchange();
132 };
133
134
135 SelectableElements.prototype.click = function (e) {
136         var oldFireChange = this._fireChange;
137         this._fireChange = false;
138
139         // create a copy to compare with after changes
140         var selectedBefore = this.getSelectedItems();   // is a cloned array
141
142         // find row
143         var el = e.target != null ? e.target : e.srcElement;
144         while (el != null && !this.isItem(el))
145                 el = el.parentNode;
146
147         if (el == null) {       // happens in IE when down and up occur on different items
148                 this._fireChange = oldFireChange;
149                 return;
150         }
151
152         var rIndex = el;
153         var aIndex = this._anchorIndex;
154
155         // test whether the current row should be the anchor
156         if (this._selectedItems.length == 0 || (e.ctrlKey && !e.shiftKey && this._multiple)) {
157                 aIndex = this._anchorIndex = rIndex;
158         }
159
160         if (!e.ctrlKey && !e.shiftKey || !this._multiple) {
161                 // deselect all
162                 var items = this._selectedItems;
163                 for (var i = items.length - 1; i >= 0; i--) {
164                         if (items[i]._selected && items[i] != el)
165                                 this.setItemSelectedUi(items[i], false);
166                 }
167                 this._anchorIndex = rIndex;
168                 if (!el._selected) {
169                         this.setItemSelectedUi(el, true);
170                 }
171                 this._selectedItems = [el];
172         }
173
174         // ctrl
175         else if (this._multiple && e.ctrlKey && !e.shiftKey) {
176                 this.setItemSelected(el, !el._selected);
177                 this._anchorIndex = rIndex;
178         }
179
180         // ctrl + shift
181         else if (this._multiple && e.ctrlKey && e.shiftKey) {
182                 // up or down?
183                 var dirUp = this.isBefore(rIndex, aIndex);
184
185                 var item = aIndex;
186                 while (item != null && item != rIndex) {
187                         if (!item._selected && item != el)
188                                 this.setItemSelected(item, true);
189                         item = dirUp ? this.getPrevious(item) : this.getNext(item);
190                 }
191
192                 if (!el._selected)
193                         this.setItemSelected(el, true);
194         }
195
196         // shift
197         else if (this._multiple && !e.ctrlKey && e.shiftKey) {
198                 // up or down?
199                 var dirUp = this.isBefore(rIndex, aIndex);
200
201                 // deselect all
202                 var items = this._selectedItems;
203                 for (var i = items.length - 1; i >= 0; i--)
204                         this.setItemSelectedUi(items[i], false);
205                 this._selectedItems = [];
206
207                 // select items in range
208                 var item = aIndex;
209                 while (item != null) {
210                         this.setItemSelected(item, true);
211                         if (item == rIndex)
212                                 break;
213                         item = dirUp ? this.getPrevious(item) : this.getNext(item);
214                 }
215         }
216
217         // find change!!!
218         var found;
219         var changed = selectedBefore.length != this._selectedItems.length;
220         if (!changed) {
221                 for (var i = 0; i < selectedBefore.length; i++) {
222                         found = false;
223                         for (var j = 0; j < this._selectedItems.length; j++) {
224                                 if (selectedBefore[i] == this._selectedItems[j]) {
225                                         found = true;
226                                         break;
227                                 }
228                         }
229                         if (!found) {
230                                 changed = true;
231                                 break;
232                         }
233                 }
234         }
235
236         this._fireChange = oldFireChange;
237         if (changed && this._fireChange)
238                 this.fireChange();
239 };
240
241 SelectableElements.prototype.getSelectedItems = function () {
242         //clone
243         var items = this._selectedItems;
244         var l = items.length;
245         var tmp = new Array(l);
246         for (var i = 0; i < l; i++)
247                 tmp[i] = items[i];
248         return tmp;
249 };
250
251 SelectableElements.prototype.isItem = function (node) {
252         return node != null && node.nodeType == 1 && node.parentNode == this._htmlElement;
253 };
254
255 SelectableElements.prototype.destroy = function () {
256         if (this._htmlElement.removeEventListener)
257                 this._htmlElement.removeEventListener("click", this._onclick, false);
258         else if (this._htmlElement.detachEvent)
259                 this._htmlElement.detachEvent("onclick", this._onclick);
260
261         this._htmlElement = null;
262         this._onclick = null;
263         this._selectedItems = null;
264 };
265
266 /* Traversable Collection Interface */
267
268 SelectableElements.prototype.getNext = function (el) {
269         var n = el.nextSibling;
270         if (n == null || this.isItem(n))
271                 return n;
272         return this.getNext(n);
273 };
274
275 SelectableElements.prototype.getPrevious = function (el) {
276         var p = el.previousSibling;
277         if (p == null || this.isItem(p))
278                 return p;
279         return this.getPrevious(p);
280 };
281
282 SelectableElements.prototype.isBefore = function (n1, n2) {
283         var next = this.getNext(n1);
284         while (next != null) {
285                 if (next == n2)
286                         return true;
287                 next = this.getNext(next);
288         }
289         return false;
290 };
291
292 /* End Traversable Collection Interface */
293
294 /* Indexable Collection Interface */
295
296 SelectableElements.prototype.getItems = function () {
297         var tmp = [];
298         var j = 0;
299         var cs = this._htmlElement.childNodes;
300         var l = cs.length;
301         for (var i = 0; i < l; i++) {
302                 if (cs[i].nodeType == 1)
303                         tmp[j++] = cs[i]
304         }
305         return tmp;
306 };
307
308 SelectableElements.prototype.getItem = function (nIndex) {
309         var j = 0;
310         var cs = this._htmlElement.childNodes;
311         var l = cs.length;
312         for (var i = 0; i < l; i++) {
313                 if (cs[i].nodeType == 1) {
314                         if (j == nIndex)
315                                 return cs[i];
316                         j++;
317                 }
318         }
319         return null;
320 };
321
322 SelectableElements.prototype.getSelectedIndexes = function () {
323         var items = this.getSelectedItems();
324         var l = items.length;
325         var tmp = new Array(l);
326         for (var i = 0; i < l; i++)
327                 tmp[i] = this.getItemIndex(items[i]);
328         return tmp;
329 };
330
331
332 SelectableElements.prototype.getItemIndex = function (el) {
333         var j = 0;
334         var cs = this._htmlElement.childNodes;
335         var l = cs.length;
336         for (var i = 0; i < l; i++) {
337                 if (cs[i] == el)
338                         return j;
339                 if (cs[i].nodeType == 1)
340                         j++;
341         }
342         return -1;
343 };
344
345 /* End Indexable Collection Interface */
346
347
348
349 function addClassName(el, sClassName) {
350         var s = el.className;
351         var p = s.split(" ");
352         if (p.length == 1 && p[0] == "")
353                 p = [];
354
355         var l = p.length;
356         for (var i = 0; i < l; i++) {
357                 if (p[i] == sClassName)
358                         return;
359         }
360         p[p.length] = sClassName;
361         el.className = p.join(" ");
362 }
363
364 function removeClassName(el, sClassName) {
365         var s = el.className;
366         var p = s.split(" ");
367         var np = [];
368         var l = p.length;
369         var j = 0;
370         for (var i = 0; i < l; i++) {
371                 if (p[i] != sClassName)
372                         np[j++] = p[i];
373         }
374         el.className = np.join(" ");
375 }