e8fdd82e1d48b782898628cb6f2686fe45fa6776
[atutor.git] / mods / photo_album / fluid / component-templates / js / jquery.ui-1.0 / ui.sortable.js
1 if (window.Node && Node.prototype && !Node.prototype.contains) {\r
2         Node.prototype.contains = function (arg) {\r
3                 return !!(this.compareDocumentPosition(arg) & 16)\r
4         }\r
5 }\r
6 \r
7 (function($) {\r
8 \r
9         //Make nodes selectable by expression\r
10         $.extend($.expr[':'], { sortable: "(' '+a.className+' ').indexOf(' ui-sortable ')" });\r
11 \r
12         $.fn.sortable = function(o) {\r
13                 return this.each(function() {\r
14                         new $.ui.sortable(this,o);      \r
15                 });\r
16         }\r
17         \r
18         //Macros for external methods that support chaining\r
19         var methods = "destroy,enable,disable,refresh".split(",");\r
20         for(var i=0;i<methods.length;i++) {\r
21                 var cur = methods[i], f;\r
22                 eval('f = function() { var a = arguments; return this.each(function() { if(jQuery(this).is(".ui-sortable")) jQuery.data(this, "ui-sortable")["'+cur+'"](a); }); }');\r
23                 $.fn["sortable"+cur.substr(0,1).toUpperCase()+cur.substr(1)] = f;\r
24         };\r
25         \r
26         //get instance method\r
27         $.fn.sortableInstance = function() {\r
28                 if($(this[0]).is(".ui-sortable")) return $.data(this[0], "ui-sortable");\r
29                 return false;\r
30         };\r
31         \r
32         $.ui.sortable = function(el,o) {\r
33         \r
34                 this.element = el;\r
35                 this.set = [];\r
36                 var options = {};\r
37                 var self = this;\r
38                 $.data(this.element, "ui-sortable", this);\r
39                 $(el).addClass("ui-sortable");\r
40                 \r
41                 $.extend(options, o);\r
42                 $.extend(options, {\r
43                         items: options.items || '> li',\r
44                         smooth: options.smooth != undefined ? options.smooth : true,\r
45                         helper: 'clone',\r
46                         containment: options.containment ? (options.containment == 'sortable' ? el : options.containment) : null,\r
47                         zIndex: options.zIndex || 1000,\r
48                         _start: function(h,p,c,t,e) {\r
49                                 self.start.apply(t, [self, e]); // Trigger the onStart callback                         \r
50                         },\r
51                         _beforeStop: function(h,p,c,t,e) {\r
52                                 self.stop.apply(t, [self, e]); // Trigger the onStart callback\r
53                         },\r
54                         _drag: function(h,p,c,t,e) {\r
55                                 self.drag.apply(t, [self, e]); // Trigger the onStart callback\r
56                         },\r
57                         startCondition: function() {\r
58                                 return !self.disabled;  \r
59                         }                       \r
60                 });\r
61                 \r
62                 //Get the items\r
63                 var items = $(options.items, el);\r
64                 \r
65                 //Let's determine the floating mode\r
66                 options.floating = /left|right/.test(items.css('float'));\r
67                 \r
68                 //Let's determine the parent's offset\r
69                 if($(el).css('position') == 'static') $(el).css('position', 'relative');\r
70                 options.offset = $(el).offset({ border: false });\r
71 \r
72                 items.each(function() {\r
73                         new $.ui.mouseInteraction(this,options);\r
74                 });\r
75                 \r
76                 //Add current items to the set\r
77                 items.each(function() {\r
78                         self.set.push([this,null]);\r
79                 });\r
80                 \r
81                 this.options = options;\r
82         }\r
83         \r
84         $.extend($.ui.sortable.prototype, {\r
85                 plugins: {},\r
86                 currentTarget: null,\r
87                 lastTarget: null,\r
88                 prepareCallbackObj: function(self, that) {\r
89                         return {\r
90                                 helper: self.helper,\r
91                                 position: { left: self.pos[0], top: self.pos[1] },\r
92                                 offset: self.options.cursorAt,\r
93                                 draggable: self,\r
94                                 current: that,\r
95                                 options: self.options\r
96                         }                       \r
97                 },\r
98                 refresh: function() {\r
99 \r
100                         //Get the items\r
101                         var self = this;\r
102                         var items = $(this.options.items, this.element);\r
103 \r
104                         var unique = [];\r
105                         items.each(function() {\r
106                                 old = false;\r
107                                 for(var i=0;i<self.set.length;i++) { if(self.set[i][0] == this) old = true;     }\r
108                                 if(!old) unique.push(this);\r
109                         });\r
110                         \r
111                         for(var i=0;i<unique.length;i++) {\r
112                                 new $.ui.mouseInteraction(unique[i],self.options);\r
113                         }\r
114                         \r
115                         //Add current items to the set\r
116                         this.set = [];\r
117                         items.each(function() {\r
118                                 self.set.push([this,null]);\r
119                         });\r
120                         \r
121                 },\r
122                 destroy: function() {\r
123                         $(this.element).removeClass("ui-sortable").removeClass("ui-sortable-disabled");\r
124                         $(this.options.items, this.element).mouseInteractionDestroy();\r
125                         \r
126                 },\r
127                 enable: function() {\r
128                         $(this.element).removeClass("ui-sortable-disabled");\r
129                         this.disabled = false;\r
130                 },\r
131                 disable: function() {\r
132                         $(this.element).addClass("ui-sortable-disabled");\r
133                         this.disabled = true;\r
134                 },\r
135                 start: function(that, e) {\r
136                         \r
137                         var o = this.options;\r
138 \r
139                         if(o.hoverClass) {\r
140                                 that.helper = $('<div class="'+o.hoverClass+'"></div>').appendTo('body').css({\r
141                                         height: this.element.offsetHeight+'px',\r
142                                         width: this.element.offsetWidth+'px',\r
143                                         position: 'absolute'    \r
144                                 });\r
145                         }\r
146                         \r
147                         if(o.zIndex) {\r
148                                 if($(this.helper).css("zIndex")) o.ozIndex = $(this.helper).css("zIndex");\r
149                                 $(this.helper).css('zIndex', o.zIndex);\r
150                         }\r
151                         \r
152                         that.firstSibling = $(this.element).prev()[0];\r
153                                 \r
154                         $(this.element).triggerHandler("sortstart", [e, that.prepareCallbackObj(this)], o.start);\r
155                         $(this.element).css('visibility', 'hidden');\r
156                         \r
157                         return false;\r
158                                                 \r
159                 },\r
160                 stop: function(that, e) {                       \r
161                         \r
162                         var o = this.options;\r
163                         var self = this;\r
164                         var pos = this.pos;              // patch\r
165 \r
166                         if(o.smooth) {\r
167                                 var os = $(this.element).offset();\r
168                                 o.beQuietAtEnd = true;\r
169                                 $(this.helper).animate({ left: os.left - o.po.left, top: os.top - o.po.top }, 500, stopIt);\r
170                         } else {\r
171                                 stopIt();\r
172                         }\r
173                                 \r
174                         function stopIt() {\r
175                 self.pos = pos;               // patch\r
176                 \r
177                                 $(self.element).css('visibility', 'visible');\r
178                                 if(that.helper) that.helper.remove();\r
179                                 if(self.helper != self.element) $(self.helper).remove(); \r
180 \r
181                                 if(o.ozIndex)\r
182                                         $(self.helper).css('zIndex', o.ozIndex);\r
183                                         \r
184                                         \r
185                                 //Let's see if the position in DOM has changed\r
186                                 if($(self.element).prev()[0] != that.firstSibling) {\r
187                                         $(self.element).triggerHandler("sortupdate", [e, that.prepareCallbackObj(self, that)], o.update);\r
188                                 }                               \r
189                 $(self.element).triggerHandler("sortstop", [e, that.prepareCallbackObj(self, that)], o.stop);   // patch\r
190                         }\r
191                         \r
192 \r
193                         return false;\r
194                         \r
195                 },\r
196                 drag: function(that, e) {\r
197 \r
198                         var o = this.options;\r
199 \r
200                         this.pos = [this.pos[0]-(o.cursorAt.left ? o.cursorAt.left : 0), this.pos[1]-(o.cursorAt.top ? o.cursorAt.top : 0)];\r
201                         var nv =  $(this.element).triggerHandler("sort", [e, that.prepareCallbackObj(this)], o.sort);\r
202                         var nl = (nv && nv.left) ? nv.left :  this.pos[0];\r
203                         var nt = (nv && nv.top) ? nv.top :  this.pos[1];\r
204                         \r
205 \r
206                         var m = that.set;\r
207                         var p = this.pos[1];\r
208                         \r
209                         for(var i=0;i<m.length;i++) {\r
210                                 \r
211                                 var ci = $(m[i][0]); var cio = m[i][0];\r
212                                 if(this.element.contains(cio)) continue;\r
213                                 var cO = ci.offset(); //TODO: Caching\r
214                                 cO = { top: cO.top, left: cO.left };\r
215                                 \r
216                                 var mb = function(e) { if(true || o.lba != cio) { ci.before(e); o.lba = cio; } }\r
217                                 var ma = function(e) { if(true || o.laa != cio) { ci.after(e); o.laa = cio; } }\r
218                                 \r
219                                 if(o.floating) {\r
220                                         \r
221                                         var overlap = ((cO.left - (this.pos[0]+(this.options.po ? this.options.po.left : 0)))/this.helper.offsetWidth);\r
222 \r
223                                         if(!(cO.top < this.pos[1]+(this.options.po ? this.options.po.top : 0) + cio.offsetHeight/2 && cO.top + cio.offsetHeight > this.pos[1]+(this.options.po ? this.options.po.top : 0) + cio.offsetHeight/2)) continue;                                                              \r
224                                         \r
225                                 } else {\r
226 \r
227                                         var overlap = ((cO.top - (this.pos[1]+(this.options.po ? this.options.po.top : 0)))/this.helper.offsetHeight);\r
228 \r
229                                         if(!(cO.left < this.pos[0]+(this.options.po ? this.options.po.left : 0) + cio.offsetWidth/2 && cO.left + cio.offsetWidth > this.pos[0]+(this.options.po ? this.options.po.left : 0) + cio.offsetWidth/2)) continue;\r
230 \r
231                                 }\r
232                                 \r
233                                 if(overlap >= 0 && overlap <= 0.5) { //Overlapping at top\r
234                                         ci.prev().length ? ma(this.element) : mb(this.element);\r
235                                 }\r
236 \r
237                                 if(overlap < 0 && overlap > -0.5) { //Overlapping at bottom\r
238                                         ci.next()[0] == this.element ? mb(this.element) : ma(this.element);\r
239                                 }\r
240 \r
241                         }\r
242                         \r
243                         //Let's see if the position in DOM has changed\r
244                         if($(this.element).prev()[0] != that.lastSibling) {\r
245                                 $(this.element).triggerHandler("sortchange", [e, that.prepareCallbackObj(this, that)], this.options.change);\r
246                                 that.lastSibling = $(this.element).prev()[0];   \r
247                         }\r
248 \r
249                         if(that.helper) { //reposition helper if available\r
250                                 var to = $(this.element).offset();\r
251                                 that.helper.css({\r
252                                         top: to.top+'px',\r
253                                         left: to.left+'px'      \r
254                                 });\r
255                         }       \r
256                         \r
257                         $(this.helper).css('left', nl+'px').css('top', nt+'px'); // Stick the helper to the cursor\r
258                         return false;\r
259                         \r
260                 }\r
261         });\r
262 \r
263  })($);\r