123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406 |
- if (!dojo._hasResource["dijit._tree.dndSource"]) { // _hasResource checks added
- // by build. Do not use
- // _hasResource directly in
- // your code.
- dojo._hasResource["dijit._tree.dndSource"] = true;
- dojo.provide("dijit._tree.dndSource");
- dojo.require("dijit._tree.dndSelector");
- dojo.require("dojo.dnd.Manager");
- dojo.declare("dijit._tree.dndSource", dijit._tree.dndSelector, {
- // summary: a Source object, which can be used as a DnD source, or a DnD
- // target
- // object attributes (for markup)
- isSource : true,
- copyOnly : false,
- skipForm : false,
- accept : ["text"],
- constructor : function(node, params) {
- // summary: a constructor of the Source
- // node: Node: node or node's id to build the source on
- // params: Object: a dict of parameters, recognized parameters are:
- // isSource: Boolean: can be used as a DnD source, if true; assumed
- // to be "true" if omitted
- // accept: Array: list of accepted types (text strings) for a
- // target; assumed to be ["text"] if omitted
- // horizontal: Boolean: a horizontal container, if true, vertical
- // otherwise or when omitted
- // copyOnly: Boolean: always copy items, if true, use a state of
- // Ctrl key otherwise
- // skipForm: Boolean: don't start the drag operation, if clicked on
- // form elements
- // the rest of parameters are passed to the selector
- if (!params) {
- params = {};
- }
- dojo.mixin(this, params);
- this.isSource = typeof params.isSource == "undefined"
- ? true
- : params.isSource;
- var type = params.accept instanceof Array
- ? params.accept
- : ["text"];
- this.accept = null;
- if (type.length) {
- this.accept = {};
- for (var i = 0; i < type.length; ++i) {
- this.accept[type[i]] = 1;
- }
- }
- // class-specific variables
- this.isDragging = false;
- this.mouseDown = false;
- this.targetAnchor = null;
- this.targetBox = null;
- this.before = true;
- // states
- this.sourceState = "";
- if (this.isSource) {
- dojo.addClass(this.node, "dojoDndSource");
- }
- this.targetState = "";
- if (this.accept) {
- dojo.addClass(this.node, "dojoDndTarget");
- }
- if (this.horizontal) {
- dojo.addClass(this.node, "dojoDndHorizontal");
- }
- // set up events
- this.topics = [
- dojo.subscribe("/dnd/source/over", this, "onDndSourceOver"),
- dojo.subscribe("/dnd/start", this, "onDndStart"),
- dojo.subscribe("/dnd/drop", this, "onDndDrop"),
- dojo.subscribe("/dnd/cancel", this, "onDndCancel")];
- },
- startup : function() {
- },
- // methods
- checkAcceptance : function(source, nodes) {
- // summary: checks, if the target can accept nodes from this source
- // source: Object: the source which provides items
- // nodes: Array: the list of transferred items
- return true; // Boolean
- },
- copyState : function(keyPressed) {
- // summary: Returns true, if we need to copy items, false to move.
- // It is separated to be overwritten dynamically, if needed.
- // keyPressed: Boolean: the "copy" was pressed
- return this.copyOnly || keyPressed; // Boolean
- },
- destroy : function() {
- // summary: prepares the object to be garbage-collected
- this.inherited("destroy", arguments);
- dojo.forEach(this.topics, dojo.unsubscribe);
- this.targetAnchor = null;
- },
- // markup methods
- markupFactory : function(params, node) {
- params._skipStartup = true;
- return new dijit._tree.dndSource(node, params);
- },
- // mouse event processors
- onMouseMove : function(e) {
- // summary: event processor for onmousemove
- // e: Event: mouse event
- if (this.isDragging && this.targetState == "Disabled") {
- return;
- }
- this.inherited("onMouseMove", arguments);
- var m = dojo.dnd.manager();
- if (this.isDragging) {
- // calculate before/after
- if (this.allowBetween) { // not implemented yet for tree
- // since it has no concept of order
- var before = false;
- if (this.current) {
- if (!this.targetBox
- || this.targetAnchor != this.current) {
- this.targetBox = {
- xy : dojo.coords(this.current, true),
- w : this.current.offsetWidth,
- h : this.current.offsetHeight
- };
- }
- if (this.horizontal) {
- before = (e.pageX - this.targetBox.xy.x) < (this.targetBox.w / 2);
- } else {
- before = (e.pageY - this.targetBox.xy.y) < (this.targetBox.h / 2);
- }
- }
- if (this.current != this.targetAnchor
- || before != this.before) {
- this._markTargetAnchor(before);
- m.canDrop(!this.current || m.source != this
- || !(this.current.id in this.selection));
- }
- }
- } else {
- if (this.mouseDown && this.isSource) {
- var n = this.getSelectedNodes();
- var nodes = [];
- for (var i in n) {
- nodes.push(n[i]);
- }
- if (nodes.length) {
- m.startDrag(this, nodes, this.copyState(dojo.dnd
- .getCopyKeyState(e)));
- }
- }
- }
- },
- onMouseDown : function(e) {
- // summary: event processor for onmousedown
- // e: Event: mouse event
- this.mouseDown = true;
- this.mouseButton = e.button;
- this.inherited("onMouseDown", arguments);
- },
- onMouseUp : function(e) {
- // summary: event processor for onmouseup
- // e: Event: mouse event
- if (this.mouseDown) {
- this.mouseDown = false;
- this.inherited("onMouseUp", arguments);
- }
- },
- onMouseOver : function(e) {
- // summary: event processor for onmouseover
- // e: Event: mouse event
- var n = e.relatedTarget;
- while (n) {
- if (n == this.node) {
- break;
- }
- try {
- n = n.parentNode;
- } catch (x) {
- n = null;
- }
- }
- if (!n) {
- this._changeState("Container", "Over");
- this.onOverEvent();
- }
- n = this._getChildByEvent(e);
- if (this.current == n) {
- return;
- }
- if (this.current) {
- this._removeItemClass(this.current, "Over");
- }
- if (n) {
- this._addItemClass(n, "Over");
- if (this.isDragging) {
- var m = dojo.dnd.manager();
- if (this.checkItemAcceptance(n, m.source)) {
- m
- .canDrop(this.targetState != "Disabled"
- && (!this.current || m.source != this || !(this.current.id in this.selection)));
- } else {
- m.canDrop(false);
- }
- }
- } else {
- if (this.isDragging) {
- var m = dojo.dnd.manager();
- if (m.source
- && this.checkAcceptance(m.source, m.source
- .getSelectedNodes())) {
- m
- .canDrop(this.targetState != "Disabled"
- && (!this.current || m.source != this || !(this.current.id in this.selection)));
- } else {
- m.canDrop(false);
- }
- }
- }
- this.current = n;
- },
- checkItemAcceptance : function(node, source) {
- // summary: stub funciton to be overridden if one wants to check for
- // the ability to drop at the node/item level
- return true;
- },
- // topic event processors
- onDndSourceOver : function(source) {
- // summary: topic event processor for /dnd/source/over, called when
- // detected a current source
- // source: Object: the source which has the mouse over it
- if (this != source) {
- this.mouseDown = false;
- if (this.targetAnchor) {
- this._unmarkTargetAnchor();
- }
- } else if (this.isDragging) {
- var m = dojo.dnd.manager();
- m
- .canDrop(this.targetState != "Disabled"
- && (!this.current || m.source != this || !(this.current.id in this.selection)));
- }
- },
- onDndStart : function(source, nodes, copy) {
- // summary: topic event processor for /dnd/start, called to initiate
- // the DnD operation
- // source: Object: the source which provides items
- // nodes: Array: the list of transferred items
- // copy: Boolean: copy items, if true, move items otherwise
- if (this.isSource) {
- this._changeState("Source", this == source ? (copy
- ? "Copied"
- : "Moved") : "");
- }
- var accepted = this.checkAcceptance(source, nodes);
- this._changeState("Target", accepted ? "" : "Disabled");
- if (accepted) {
- dojo.dnd.manager().overSource(this);
- }
- this.isDragging = true;
- },
- itemCreator : function(nodes) {
- var items = []
- for (var i = 0; i < nodes.length; i++) {
- items.push({
- "name" : nodes[i].textContent,
- "id" : nodes[i].id
- });
- }
- return items;
- },
- onDndDrop : function(source, nodes, copy) {
- // summary: topic event processor for /dnd/drop, called to finish
- // the DnD operation
- // source: Object: the source which provides items
- // nodes: Array: the list of transferred items
- // copy: Boolean: copy items, if true, move items otherwise
- if (this.containerState == "Over") {
- this.isDragging = false;
- var target = this.current;
- var items = this.itemCreator(nodes, target);
- if (!target || target == this.tree.domNode) {
- for (var i = 0; i < items.length; i++) {
- this.tree.store.newItem(items[i], null);
- }
- } else {
- for (var i = 0; i < items.length; i++) {
- pInfo = {
- parent : dijit.getEnclosingWidget(target).item,
- attribute : "children"
- };
- var newItem = this.tree.store.newItem(items[i], pInfo);
- console.log("newItem:", newItem);
- }
- }
- }
- this.onDndCancel();
- },
- onDndCancel : function() {
- // summary: topic event processor for /dnd/cancel, called to cancel
- // the DnD operation
- if (this.targetAnchor) {
- this._unmarkTargetAnchor();
- this.targetAnchor = null;
- }
- this.before = true;
- this.isDragging = false;
- this.mouseDown = false;
- delete this.mouseButton;
- this._changeState("Source", "");
- this._changeState("Target", "");
- },
- // utilities
- onOverEvent : function() {
- // summary: this function is called once, when mouse is over our
- // container
- this.inherited("onOverEvent", arguments);
- dojo.dnd.manager().overSource(this);
- },
- onOutEvent : function() {
- // summary: this function is called once, when mouse is out of our
- // container
- this.inherited("onOutEvent", arguments);
- dojo.dnd.manager().outSource(this);
- },
- _markTargetAnchor : function(before) {
- // summary: assigns a class to the current target anchor based on
- // "before" status
- // before: Boolean: insert before, if true, after otherwise
- if (this.current == this.targetAnchor && this.before == before) {
- return;
- }
- if (this.targetAnchor) {
- this._removeItemClass(this.targetAnchor, this.before
- ? "Before"
- : "After");
- }
- this.targetAnchor = this.current;
- this.targetBox = null;
- this.before = before;
- if (this.targetAnchor) {
- this._addItemClass(this.targetAnchor, this.before
- ? "Before"
- : "After");
- }
- },
- _unmarkTargetAnchor : function() {
- // summary: removes a class of the current target anchor based on
- // "before" status
- if (!this.targetAnchor) {
- return;
- }
- this._removeItemClass(this.targetAnchor, this.before
- ? "Before"
- : "After");
- this.targetAnchor = null;
- this.targetBox = null;
- this.before = true;
- },
- _markDndStatus : function(copy) {
- // summary: changes source's state based on "copy" status
- this._changeState("Source", copy ? "Copied" : "Moved");
- }
- });
- dojo.declare("dijit._tree.dndTarget", dijit._tree.dndSource, {
- // summary: a Target object, which can be used as a DnD target
- constructor : function(node, params) {
- // summary: a constructor of the Target --- see the Source
- // constructor for details
- this.isSource = false;
- dojo.removeClass(this.node, "dojoDndSource");
- },
- // markup methods
- markupFactory : function(params, node) {
- params._skipStartup = true;
- return new dijit._tree.dndTarget(node, params);
- }
- });
- }
|