Subversion Repositories Applications.papyrus

Rev

Rev 1987 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1318 alexandre_ 1
/*
2
	Copyright (c) 2004-2006, The Dojo Foundation
3
	All Rights Reserved.
4
 
5
	Licensed under the Academic Free License version 2.1 or above OR the
6
	modified BSD license. For more information on Dojo licensing, see:
7
 
8
		http://dojotoolkit.org/community/licensing.shtml
9
*/
10
 
1422 alexandre_ 11
 
12
 
1318 alexandre_ 13
dojo.provide("dojo.dnd.HtmlDragAndDrop");
14
dojo.require("dojo.dnd.HtmlDragManager");
15
dojo.require("dojo.dnd.DragAndDrop");
16
dojo.require("dojo.html.*");
17
dojo.require("dojo.html.display");
18
dojo.require("dojo.html.util");
19
dojo.require("dojo.html.selection");
20
dojo.require("dojo.html.iframe");
21
dojo.require("dojo.lang.extras");
22
dojo.require("dojo.lfx.*");
23
dojo.require("dojo.event.*");
24
dojo.declare("dojo.dnd.HtmlDragSource", dojo.dnd.DragSource, {dragClass:"", onDragStart:function () {
25
	var dragObj = new dojo.dnd.HtmlDragObject(this.dragObject, this.type);
26
	if (this.dragClass) {
27
		dragObj.dragClass = this.dragClass;
28
	}
29
	if (this.constrainToContainer) {
30
		dragObj.constrainTo(this.constrainingContainer || this.domNode.parentNode);
31
	}
32
	return dragObj;
33
}, setDragHandle:function (node) {
34
	node = dojo.byId(node);
35
	dojo.dnd.dragManager.unregisterDragSource(this);
36
	this.domNode = node;
37
	dojo.dnd.dragManager.registerDragSource(this);
38
}, setDragTarget:function (node) {
39
	this.dragObject = node;
40
}, constrainTo:function (container) {
41
	this.constrainToContainer = true;
42
	if (container) {
43
		this.constrainingContainer = container;
44
	}
45
}, onSelected:function () {
46
	for (var i = 0; i < this.dragObjects.length; i++) {
47
		dojo.dnd.dragManager.selectedSources.push(new dojo.dnd.HtmlDragSource(this.dragObjects[i]));
48
	}
49
}, addDragObjects:function (el) {
50
	for (var i = 0; i < arguments.length; i++) {
51
		this.dragObjects.push(dojo.byId(arguments[i]));
52
	}
53
}}, function (node, type) {
54
	node = dojo.byId(node);
55
	this.dragObjects = [];
56
	this.constrainToContainer = false;
57
	if (node) {
58
		this.domNode = node;
59
		this.dragObject = node;
60
		this.type = (type) || (this.domNode.nodeName.toLowerCase());
61
		dojo.dnd.DragSource.prototype.reregister.call(this);
62
	}
63
});
64
dojo.declare("dojo.dnd.HtmlDragObject", dojo.dnd.DragObject, {dragClass:"", opacity:0.5, createIframe:true, disableX:false, disableY:false, createDragNode:function () {
65
	var node = this.domNode.cloneNode(true);
66
	if (this.dragClass) {
67
		dojo.html.addClass(node, this.dragClass);
68
	}
69
	if (this.opacity < 1) {
70
		dojo.html.setOpacity(node, this.opacity);
71
	}
72
	var ltn = node.tagName.toLowerCase();
73
	var isTr = (ltn == "tr");
74
	if ((isTr) || (ltn == "tbody")) {
75
		var doc = this.domNode.ownerDocument;
76
		var table = doc.createElement("table");
77
		if (isTr) {
78
			var tbody = doc.createElement("tbody");
79
			table.appendChild(tbody);
80
			tbody.appendChild(node);
81
		} else {
82
			table.appendChild(node);
83
		}
84
		var tmpSrcTr = ((isTr) ? this.domNode : this.domNode.firstChild);
85
		var tmpDstTr = ((isTr) ? node : node.firstChild);
86
		var domTds = tmpSrcTr.childNodes;
87
		var cloneTds = tmpDstTr.childNodes;
88
		for (var i = 0; i < domTds.length; i++) {
89
			if ((cloneTds[i]) && (cloneTds[i].style)) {
90
				cloneTds[i].style.width = dojo.html.getContentBox(domTds[i]).width + "px";
91
			}
92
		}
93
		node = table;
94
	}
95
	if ((dojo.render.html.ie55 || dojo.render.html.ie60) && this.createIframe) {
96
		with (node.style) {
97
			top = "0px";
98
			left = "0px";
99
		}
100
		var outer = document.createElement("div");
101
		outer.appendChild(node);
102
		this.bgIframe = new dojo.html.BackgroundIframe(outer);
103
		outer.appendChild(this.bgIframe.iframe);
104
		node = outer;
105
	}
106
	node.style.zIndex = 999;
107
	return node;
108
}, onDragStart:function (e) {
109
	dojo.html.clearSelection();
110
	this.scrollOffset = dojo.html.getScroll().offset;
111
	this.dragStartPosition = dojo.html.getAbsolutePosition(this.domNode, true);
112
	this.dragOffset = {y:this.dragStartPosition.y - e.pageY, x:this.dragStartPosition.x - e.pageX};
113
	this.dragClone = this.createDragNode();
114
	this.containingBlockPosition = this.domNode.offsetParent ? dojo.html.getAbsolutePosition(this.domNode.offsetParent, true) : {x:0, y:0};
115
	if (this.constrainToContainer) {
116
		this.constraints = this.getConstraints();
117
	}
118
	with (this.dragClone.style) {
119
		position = "absolute";
120
		top = this.dragOffset.y + e.pageY + "px";
121
		left = this.dragOffset.x + e.pageX + "px";
122
	}
123
	dojo.body().appendChild(this.dragClone);
124
	dojo.event.topic.publish("dragStart", {source:this});
125
}, getConstraints:function () {
126
	if (this.constrainingContainer.nodeName.toLowerCase() == "body") {
127
		var viewport = dojo.html.getViewport();
128
		var width = viewport.width;
129
		var height = viewport.height;
130
		var scroll = dojo.html.getScroll().offset;
131
		var x = scroll.x;
132
		var y = scroll.y;
133
	} else {
134
		var content = dojo.html.getContentBox(this.constrainingContainer);
135
		width = content.width;
136
		height = content.height;
137
		x = this.containingBlockPosition.x + dojo.html.getPixelValue(this.constrainingContainer, "padding-left", true) + dojo.html.getBorderExtent(this.constrainingContainer, "left");
138
		y = this.containingBlockPosition.y + dojo.html.getPixelValue(this.constrainingContainer, "padding-top", true) + dojo.html.getBorderExtent(this.constrainingContainer, "top");
139
	}
140
	var mb = dojo.html.getMarginBox(this.domNode);
141
	return {minX:x, minY:y, maxX:x + width - mb.width, maxY:y + height - mb.height};
142
}, updateDragOffset:function () {
143
	var scroll = dojo.html.getScroll().offset;
144
	if (scroll.y != this.scrollOffset.y) {
145
		var diff = scroll.y - this.scrollOffset.y;
146
		this.dragOffset.y += diff;
147
		this.scrollOffset.y = scroll.y;
148
	}
149
	if (scroll.x != this.scrollOffset.x) {
150
		var diff = scroll.x - this.scrollOffset.x;
151
		this.dragOffset.x += diff;
152
		this.scrollOffset.x = scroll.x;
153
	}
154
}, onDragMove:function (e) {
155
	this.updateDragOffset();
156
	var x = this.dragOffset.x + e.pageX;
157
	var y = this.dragOffset.y + e.pageY;
158
	if (this.constrainToContainer) {
159
		if (x < this.constraints.minX) {
160
			x = this.constraints.minX;
161
		}
162
		if (y < this.constraints.minY) {
163
			y = this.constraints.minY;
164
		}
165
		if (x > this.constraints.maxX) {
166
			x = this.constraints.maxX;
167
		}
168
		if (y > this.constraints.maxY) {
169
			y = this.constraints.maxY;
170
		}
171
	}
172
	this.setAbsolutePosition(x, y);
173
	dojo.event.topic.publish("dragMove", {source:this});
174
}, setAbsolutePosition:function (x, y) {
175
	if (!this.disableY) {
176
		this.dragClone.style.top = y + "px";
177
	}
178
	if (!this.disableX) {
179
		this.dragClone.style.left = x + "px";
180
	}
181
}, onDragEnd:function (e) {
182
	switch (e.dragStatus) {
183
	  case "dropSuccess":
184
		dojo.html.removeNode(this.dragClone);
185
		this.dragClone = null;
186
		break;
187
	  case "dropFailure":
188
		var startCoords = dojo.html.getAbsolutePosition(this.dragClone, true);
189
		var endCoords = {left:this.dragStartPosition.x + 1, top:this.dragStartPosition.y + 1};
190
		var anim = dojo.lfx.slideTo(this.dragClone, endCoords, 300);
191
		var dragObject = this;
192
		dojo.event.connect(anim, "onEnd", function (e) {
193
			dojo.html.removeNode(dragObject.dragClone);
194
			dragObject.dragClone = null;
195
		});
196
		anim.play();
197
		break;
198
	}
199
	dojo.event.topic.publish("dragEnd", {source:this});
200
}, constrainTo:function (container) {
201
	this.constrainToContainer = true;
202
	if (container) {
203
		this.constrainingContainer = container;
204
	} else {
205
		this.constrainingContainer = this.domNode.parentNode;
206
	}
207
}}, function (node, type) {
208
	this.domNode = dojo.byId(node);
209
	this.type = type;
210
	this.constrainToContainer = false;
211
	this.dragSource = null;
212
	dojo.dnd.DragObject.prototype.register.call(this);
213
});
214
dojo.declare("dojo.dnd.HtmlDropTarget", dojo.dnd.DropTarget, {vertical:false, onDragOver:function (e) {
215
	if (!this.accepts(e.dragObjects)) {
216
		return false;
217
	}
218
	this.childBoxes = [];
219
	for (var i = 0, child; i < this.domNode.childNodes.length; i++) {
220
		child = this.domNode.childNodes[i];
221
		if (child.nodeType != dojo.html.ELEMENT_NODE) {
222
			continue;
223
		}
224
		var pos = dojo.html.getAbsolutePosition(child, true);
225
		var inner = dojo.html.getBorderBox(child);
226
		this.childBoxes.push({top:pos.y, bottom:pos.y + inner.height, left:pos.x, right:pos.x + inner.width, height:inner.height, width:inner.width, node:child});
227
	}
228
	return true;
229
}, _getNodeUnderMouse:function (e) {
230
	for (var i = 0, child; i < this.childBoxes.length; i++) {
231
		with (this.childBoxes[i]) {
232
			if (e.pageX >= left && e.pageX <= right && e.pageY >= top && e.pageY <= bottom) {
233
				return i;
234
			}
235
		}
236
	}
237
	return -1;
238
}, createDropIndicator:function () {
239
	this.dropIndicator = document.createElement("div");
240
	with (this.dropIndicator.style) {
241
		position = "absolute";
242
		zIndex = 999;
243
		if (this.vertical) {
244
			borderLeftWidth = "1px";
245
			borderLeftColor = "black";
246
			borderLeftStyle = "solid";
247
			height = dojo.html.getBorderBox(this.domNode).height + "px";
248
			top = dojo.html.getAbsolutePosition(this.domNode, true).y + "px";
249
		} else {
250
			borderTopWidth = "1px";
251
			borderTopColor = "black";
252
			borderTopStyle = "solid";
253
			width = dojo.html.getBorderBox(this.domNode).width + "px";
254
			left = dojo.html.getAbsolutePosition(this.domNode, true).x + "px";
255
		}
256
	}
257
}, onDragMove:function (e, dragObjects) {
258
	var i = this._getNodeUnderMouse(e);
259
	if (!this.dropIndicator) {
260
		this.createDropIndicator();
261
	}
262
	var gravity = this.vertical ? dojo.html.gravity.WEST : dojo.html.gravity.NORTH;
263
	var hide = false;
264
	if (i < 0) {
265
		if (this.childBoxes.length) {
266
			var before = (dojo.html.gravity(this.childBoxes[0].node, e) & gravity);
267
			if (before) {
268
				hide = true;
269
			}
270
		} else {
271
			var before = true;
272
		}
273
	} else {
274
		var child = this.childBoxes[i];
275
		var before = (dojo.html.gravity(child.node, e) & gravity);
276
		if (child.node === dragObjects[0].dragSource.domNode) {
277
			hide = true;
278
		} else {
279
			var currentPosChild = before ? (i > 0 ? this.childBoxes[i - 1] : child) : (i < this.childBoxes.length - 1 ? this.childBoxes[i + 1] : child);
280
			if (currentPosChild.node === dragObjects[0].dragSource.domNode) {
281
				hide = true;
282
			}
283
		}
284
	}
285
	if (hide) {
286
		this.dropIndicator.style.display = "none";
287
		return;
288
	} else {
289
		this.dropIndicator.style.display = "";
290
	}
291
	this.placeIndicator(e, dragObjects, i, before);
292
	if (!dojo.html.hasParent(this.dropIndicator)) {
293
		dojo.body().appendChild(this.dropIndicator);
294
	}
295
}, placeIndicator:function (e, dragObjects, boxIndex, before) {
296
	var targetProperty = this.vertical ? "left" : "top";
297
	var child;
298
	if (boxIndex < 0) {
299
		if (this.childBoxes.length) {
300
			child = before ? this.childBoxes[0] : this.childBoxes[this.childBoxes.length - 1];
301
		} else {
302
			this.dropIndicator.style[targetProperty] = dojo.html.getAbsolutePosition(this.domNode, true)[this.vertical ? "x" : "y"] + "px";
303
		}
304
	} else {
305
		child = this.childBoxes[boxIndex];
306
	}
307
	if (child) {
308
		this.dropIndicator.style[targetProperty] = (before ? child[targetProperty] : child[this.vertical ? "right" : "bottom"]) + "px";
309
		if (this.vertical) {
310
			this.dropIndicator.style.height = child.height + "px";
311
			this.dropIndicator.style.top = child.top + "px";
312
		} else {
313
			this.dropIndicator.style.width = child.width + "px";
314
			this.dropIndicator.style.left = child.left + "px";
315
		}
316
	}
317
}, onDragOut:function (e) {
318
	if (this.dropIndicator) {
319
		dojo.html.removeNode(this.dropIndicator);
320
		delete this.dropIndicator;
321
	}
322
}, onDrop:function (e) {
323
	this.onDragOut(e);
324
	var i = this._getNodeUnderMouse(e);
325
	var gravity = this.vertical ? dojo.html.gravity.WEST : dojo.html.gravity.NORTH;
326
	if (i < 0) {
327
		if (this.childBoxes.length) {
328
			if (dojo.html.gravity(this.childBoxes[0].node, e) & gravity) {
329
				return this.insert(e, this.childBoxes[0].node, "before");
330
			} else {
331
				return this.insert(e, this.childBoxes[this.childBoxes.length - 1].node, "after");
332
			}
333
		}
334
		return this.insert(e, this.domNode, "append");
335
	}
336
	var child = this.childBoxes[i];
337
	if (dojo.html.gravity(child.node, e) & gravity) {
338
		return this.insert(e, child.node, "before");
339
	} else {
340
		return this.insert(e, child.node, "after");
341
	}
342
}, insert:function (e, refNode, position) {
343
	var node = e.dragObject.domNode;
344
	if (position == "before") {
345
		return dojo.html.insertBefore(node, refNode);
346
	} else {
347
		if (position == "after") {
348
			return dojo.html.insertAfter(node, refNode);
349
		} else {
350
			if (position == "append") {
351
				refNode.appendChild(node);
352
				return true;
353
			}
354
		}
355
	}
356
	return false;
357
}}, function (node, types) {
358
	if (arguments.length == 0) {
359
		return;
360
	}
361
	this.domNode = dojo.byId(node);
362
	dojo.dnd.DropTarget.call(this);
363
	if (types && dojo.lang.isString(types)) {
364
		types = [types];
365
	}
366
	this.acceptedTypes = types || [];
367
	dojo.dnd.dragManager.registerDropTarget(this);
368
});
369