30
|
1 |
// script.aculo.us dragdrop.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
|
|
2 |
|
|
3 |
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
|
4 |
// (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
|
|
5 |
//
|
|
6 |
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
|
7 |
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
|
8 |
//
|
|
9 |
// Modified by Tero Marttila to strip unused code
|
|
10 |
|
|
11 |
var Draggables = {
|
|
12 |
drags: [],
|
|
13 |
observers: [],
|
|
14 |
|
|
15 |
register: function(draggable) {
|
|
16 |
if(this.drags.length == 0) {
|
|
17 |
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
|
|
18 |
this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
|
|
19 |
this.eventKeypress = this.keyPress.bindAsEventListener(this);
|
|
20 |
|
|
21 |
Event.observe(document, "mouseup", this.eventMouseUp);
|
|
22 |
Event.observe(document, "mousemove", this.eventMouseMove);
|
|
23 |
Event.observe(document, "keypress", this.eventKeypress);
|
|
24 |
}
|
|
25 |
this.drags.push(draggable);
|
|
26 |
},
|
|
27 |
|
|
28 |
unregister: function(draggable) {
|
|
29 |
this.drags = this.drags.reject(function(d) { return d==draggable });
|
|
30 |
if(this.drags.length == 0) {
|
|
31 |
Event.stopObserving(document, "mouseup", this.eventMouseUp);
|
|
32 |
Event.stopObserving(document, "mousemove", this.eventMouseMove);
|
|
33 |
Event.stopObserving(document, "keypress", this.eventKeypress);
|
|
34 |
}
|
|
35 |
},
|
|
36 |
|
|
37 |
activate: function(draggable) {
|
|
38 |
if(draggable.options.delay) {
|
|
39 |
this._timeout = setTimeout(function() {
|
|
40 |
Draggables._timeout = null;
|
|
41 |
window.focus();
|
|
42 |
Draggables.activeDraggable = draggable;
|
|
43 |
}.bind(this), draggable.options.delay);
|
|
44 |
} else {
|
|
45 |
window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
|
|
46 |
this.activeDraggable = draggable;
|
|
47 |
}
|
|
48 |
},
|
|
49 |
|
|
50 |
deactivate: function() {
|
|
51 |
this.activeDraggable = null;
|
|
52 |
},
|
|
53 |
|
|
54 |
updateDrag: function(event) {
|
|
55 |
if(!this.activeDraggable) return;
|
|
56 |
var pointer = [Event.pointerX(event), Event.pointerY(event)];
|
|
57 |
// Mozilla-based browsers fire successive mousemove events with
|
|
58 |
// the same coordinates, prevent needless redrawing (moz bug?)
|
|
59 |
if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
|
|
60 |
this._lastPointer = pointer;
|
|
61 |
|
|
62 |
this.activeDraggable.updateDrag(event, pointer);
|
|
63 |
},
|
|
64 |
|
|
65 |
endDrag: function(event) {
|
|
66 |
if(this._timeout) {
|
|
67 |
clearTimeout(this._timeout);
|
|
68 |
this._timeout = null;
|
|
69 |
}
|
|
70 |
if(!this.activeDraggable) return;
|
|
71 |
this._lastPointer = null;
|
|
72 |
this.activeDraggable.endDrag(event);
|
|
73 |
this.activeDraggable = null;
|
|
74 |
},
|
|
75 |
|
|
76 |
keyPress: function(event) {
|
|
77 |
if(this.activeDraggable)
|
|
78 |
this.activeDraggable.keyPress(event);
|
|
79 |
},
|
|
80 |
|
|
81 |
addObserver: function(observer) {
|
|
82 |
this.observers.push(observer);
|
|
83 |
this._cacheObserverCallbacks();
|
|
84 |
},
|
|
85 |
|
|
86 |
removeObserver: function(element) { // element instead of observer fixes mem leaks
|
|
87 |
this.observers = this.observers.reject( function(o) { return o.element==element });
|
|
88 |
this._cacheObserverCallbacks();
|
|
89 |
},
|
|
90 |
|
|
91 |
notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
|
|
92 |
if(this[eventName+'Count'] > 0)
|
|
93 |
this.observers.each( function(o) {
|
|
94 |
if(o[eventName]) o[eventName](eventName, draggable, event);
|
|
95 |
});
|
|
96 |
if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
|
|
97 |
},
|
|
98 |
|
|
99 |
_cacheObserverCallbacks: function() {
|
|
100 |
['onStart','onEnd','onDrag'].each( function(eventName) {
|
|
101 |
Draggables[eventName+'Count'] = Draggables.observers.select(
|
|
102 |
function(o) { return o[eventName]; }
|
|
103 |
).length;
|
|
104 |
});
|
|
105 |
}
|
|
106 |
}
|
|
107 |
|
|
108 |
/*--------------------------------------------------------------------------*/
|
|
109 |
|
|
110 |
var Draggable = Class.create({
|
|
111 |
initialize: function(element) {
|
|
112 |
var defaults = {
|
|
113 |
handle: false,
|
|
114 |
zindex: 1000,
|
|
115 |
quiet: false,
|
|
116 |
delay: 0
|
|
117 |
};
|
|
118 |
|
|
119 |
var options = Object.extend(defaults, arguments[1] || { });
|
|
120 |
|
|
121 |
this.element = $(element);
|
|
122 |
|
|
123 |
if(options.handle && Object.isString(options.handle))
|
|
124 |
this.handle = this.element.down('.'+options.handle, 0);
|
|
125 |
|
|
126 |
if(!this.handle) this.handle = $(options.handle);
|
|
127 |
if(!this.handle) this.handle = this.element;
|
|
128 |
|
|
129 |
Element.makePositioned(this.element); // fix IE
|
|
130 |
|
|
131 |
this.options = options;
|
|
132 |
this.dragging = false;
|
|
133 |
|
|
134 |
this.eventMouseDown = this.initDrag.bindAsEventListener(this);
|
|
135 |
Event.observe(this.handle, "mousedown", this.eventMouseDown);
|
|
136 |
|
|
137 |
Draggables.register(this);
|
|
138 |
},
|
|
139 |
|
|
140 |
destroy: function() {
|
|
141 |
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
|
|
142 |
Draggables.unregister(this);
|
|
143 |
},
|
|
144 |
|
|
145 |
currentDelta: function() {
|
|
146 |
return([
|
|
147 |
parseInt(Element.getStyle(this.element,'left') || '0'),
|
|
148 |
parseInt(Element.getStyle(this.element,'top') || '0')]);
|
|
149 |
},
|
|
150 |
|
|
151 |
initDrag: function(event) {
|
|
152 |
if(!Object.isUndefined(Draggable._dragging[this.element]) &&
|
|
153 |
Draggable._dragging[this.element]) return;
|
|
154 |
if(Event.isLeftClick(event)) {
|
|
155 |
// abort on form elements, fixes a Firefox issue
|
|
156 |
var src = Event.element(event);
|
|
157 |
if((tag_name = src.tagName.toUpperCase()) && (
|
|
158 |
tag_name=='INPUT' ||
|
|
159 |
tag_name=='SELECT' ||
|
|
160 |
tag_name=='OPTION' ||
|
|
161 |
tag_name=='BUTTON' ||
|
|
162 |
tag_name=='TEXTAREA')) return;
|
|
163 |
|
|
164 |
var pointer = [Event.pointerX(event), Event.pointerY(event)];
|
|
165 |
var pos = Position.cumulativeOffset(this.element);
|
|
166 |
this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
|
|
167 |
|
|
168 |
Draggables.activate(this);
|
|
169 |
Event.stop(event);
|
|
170 |
}
|
|
171 |
},
|
|
172 |
|
|
173 |
startDrag: function(event) {
|
|
174 |
this.dragging = true;
|
|
175 |
if(!this.delta)
|
|
176 |
this.delta = this.currentDelta();
|
|
177 |
|
|
178 |
if(this.options.zindex) {
|
|
179 |
this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
|
|
180 |
this.element.style.zIndex = this.options.zindex;
|
|
181 |
}
|
|
182 |
|
|
183 |
Draggables.notify('onStart', this, event);
|
|
184 |
},
|
|
185 |
|
|
186 |
updateDrag: function(event, pointer) {
|
|
187 |
if(!this.dragging) this.startDrag(event);
|
|
188 |
|
|
189 |
Draggables.notify('onDrag', this, event);
|
|
190 |
|
|
191 |
this.draw(pointer);
|
|
192 |
if(this.options.change) this.options.change(this);
|
|
193 |
|
|
194 |
// fix AppleWebKit rendering
|
|
195 |
if(Prototype.Browser.WebKit) window.scrollBy(0,0);
|
|
196 |
|
|
197 |
Event.stop(event);
|
|
198 |
},
|
|
199 |
|
|
200 |
finishDrag: function(event, success) {
|
|
201 |
this.dragging = false;
|
|
202 |
|
|
203 |
Draggables.notify('onEnd', this, event);
|
|
204 |
|
|
205 |
var d = this.currentDelta();
|
|
206 |
this.delta = d;
|
|
207 |
|
|
208 |
if(this.options.zindex)
|
|
209 |
this.element.style.zIndex = this.originalZ;
|
|
210 |
|
|
211 |
Draggables.deactivate(this);
|
|
212 |
},
|
|
213 |
|
|
214 |
keyPress: function(event) {
|
|
215 |
if(event.keyCode!=Event.KEY_ESC) return;
|
|
216 |
this.finishDrag(event, false);
|
|
217 |
Event.stop(event);
|
|
218 |
},
|
|
219 |
|
|
220 |
endDrag: function(event) {
|
|
221 |
if(!this.dragging) return;
|
|
222 |
this.finishDrag(event, true);
|
|
223 |
Event.stop(event);
|
|
224 |
},
|
|
225 |
|
|
226 |
draw: function(point) {
|
|
227 |
var pos = Position.cumulativeOffset(this.element);
|
|
228 |
|
|
229 |
var d = this.currentDelta();
|
|
230 |
pos[0] -= d[0]; pos[1] -= d[1];
|
|
231 |
|
|
232 |
var p = [0,1].map(function(i){
|
|
233 |
return (point[i]-pos[i]-this.offset[i])
|
|
234 |
}.bind(this));
|
|
235 |
|
|
236 |
var style = this.element.style;
|
|
237 |
if((!this.options.constraint) || (this.options.constraint=='horizontal'))
|
|
238 |
style.left = p[0] + "px";
|
|
239 |
if((!this.options.constraint) || (this.options.constraint=='vertical'))
|
|
240 |
style.top = p[1] + "px";
|
|
241 |
|
|
242 |
if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
|
46
|
243 |
}
|
30
|
244 |
});
|
|
245 |
|
|
246 |
Draggable._dragging = { };
|
|
247 |
|