Subversion Repositories Applications.papyrus

Rev

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