3 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
4 <title>The source code</title>
5 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <body onload="prettyPrint();">
9 <pre class="prettyprint lang-js">/*!
10 * Ext JS Library 3.2.0
11 * Copyright(c) 2006-2010 Ext JS, Inc.
13 * http://www.extjs.com/license
15 <div id="cls-Ext.tree.TreeDropZone"></div>/**
16 * @class Ext.tree.TreeDropZone
17 * @extends Ext.dd.DropZone
19 * @param {String/HTMLElement/Element} tree The {@link Ext.tree.TreePanel} for which to enable dropping
20 * @param {Object} config
24 Ext.tree.TreeDropZone = function(tree, config){
25 <div id="cfg-Ext.tree.TreeDropZone-allowParentInsert"></div>/**
26 * @cfg {Boolean} allowParentInsert
27 * Allow inserting a dragged node between an expanded parent node and its first child that will become a
28 * sibling of the parent when dropped (defaults to false)
30 this.allowParentInsert = config.allowParentInsert || false;
31 <div id="cfg-Ext.tree.TreeDropZone-allowContainerDrop"></div>/**
32 * @cfg {String} allowContainerDrop
33 * True if drops on the tree container (outside of a specific tree node) are allowed (defaults to false)
35 this.allowContainerDrop = config.allowContainerDrop || false;
36 <div id="cfg-Ext.tree.TreeDropZone-appendOnly"></div>/**
37 * @cfg {String} appendOnly
38 * True if the tree should only allow append drops (use for trees which are sorted, defaults to false)
40 this.appendOnly = config.appendOnly || false;
42 Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.getTreeEl(), config);
43 <div id="prop-Ext.tree.TreeDropZone-tree"></div>/**
44 * The TreePanel for this drop zone
45 * @type Ext.tree.TreePanel
49 <div id="prop-Ext.tree.TreeDropZone-dragOverData"></div>/**
50 * Arbitrary data that can be associated with this tree and will be included in the event object that gets
51 * passed to any nodedragover event handler (defaults to {})
52 * @type Ext.tree.TreePanel
55 this.dragOverData = {};
57 this.lastInsertClass = "x-tree-no-status";
60 Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {
61 <div id="cfg-Ext.tree.TreeDropZone-ddGroup"></div>/**
62 * @cfg {String} ddGroup
63 * A named drag drop group to which this object belongs. If a group is specified, then this object will only
64 * interact with other drag drop objects in the same group (defaults to 'TreeDD').
68 <div id="cfg-Ext.tree.TreeDropZone-expandDelay"></div>/**
69 * @cfg {String} expandDelay
70 * The delay in milliseconds to wait before expanding a target tree node while dragging a droppable node
71 * over the target (defaults to 1000)
76 expandNode : function(node){
77 if(node.hasChildNodes() && !node.isExpanded()){
78 node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
83 queueExpand : function(node){
84 this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
88 cancelExpand : function(){
89 if(this.expandProcId){
90 clearTimeout(this.expandProcId);
91 this.expandProcId = false;
96 isValidDropPoint : function(n, pt, dd, e, data){
97 if(!n || !data){ return false; }
98 var targetNode = n.node;
99 var dropNode = data.node;
100 // default drop rules
101 if(!(targetNode && targetNode.isTarget && pt)){
104 if(pt == "append" && targetNode.allowChildren === false){
107 if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
110 if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
114 var overEvent = this.dragOverData;
115 overEvent.tree = this.tree;
116 overEvent.target = targetNode;
117 overEvent.data = data;
118 overEvent.point = pt;
119 overEvent.source = dd;
120 overEvent.rawEvent = e;
121 overEvent.dropNode = dropNode;
122 overEvent.cancel = false;
123 var result = this.tree.fireEvent("nodedragover", overEvent);
124 return overEvent.cancel === false && result !== false;
128 getDropPoint : function(e, n, dd){
131 return tn.allowChildren !== false ? "append" : false; // always append for root
134 var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
135 var y = Ext.lib.Event.getPageY(e);
136 var noAppend = tn.allowChildren === false || tn.isLeaf();
137 if(this.appendOnly || tn.parentNode.allowChildren === false){
138 return noAppend ? false : "append";
141 if(!this.allowParentInsert){
142 noBelow = tn.hasChildNodes() && tn.isExpanded();
144 var q = (b - t) / (noAppend ? 2 : 3);
145 if(y >= t && y < (t + q)){
147 }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
155 onNodeEnter : function(n, dd, e, data){
159 onContainerOver : function(dd, e, data) {
160 if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
161 return this.dropAllowed;
163 return this.dropNotAllowed;
167 onNodeOver : function(n, dd, e, data){
168 var pt = this.getDropPoint(e, n, dd);
171 // auto node expand check
172 if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
173 this.queueExpand(node);
174 }else if(pt != "append"){
178 // set the insert point style on the target node
179 var returnCls = this.dropNotAllowed;
180 if(this.isValidDropPoint(n, pt, dd, e, data)){
185 returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
186 cls = "x-tree-drag-insert-above";
187 }else if(pt == "below"){
188 returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
189 cls = "x-tree-drag-insert-below";
191 returnCls = "x-tree-drop-ok-append";
192 cls = "x-tree-drag-append";
194 if(this.lastInsertClass != cls){
195 Ext.fly(el).replaceClass(this.lastInsertClass, cls);
196 this.lastInsertClass = cls;
204 onNodeOut : function(n, dd, e, data){
206 this.removeDropIndicators(n);
210 onNodeDrop : function(n, dd, e, data){
211 var point = this.getDropPoint(e, n, dd);
212 var targetNode = n.node;
213 targetNode.ui.startDrop();
214 if(!this.isValidDropPoint(n, point, dd, e, data)){
215 targetNode.ui.endDrop();
218 // first try to find the drop node
219 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
220 return this.processDrop(targetNode, data, point, dd, e, dropNode);
223 onContainerDrop : function(dd, e, data){
224 if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
225 var targetNode = this.tree.getRootNode();
226 targetNode.ui.startDrop();
227 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, 'append', e) : null);
228 return this.processDrop(targetNode, data, 'append', dd, e, dropNode);
234 processDrop: function(target, data, point, dd, e, dropNode){
246 var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
247 if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
249 return dropEvent.dropStatus;
252 target = dropEvent.target;
253 if(point == 'append' && !target.isExpanded()){
254 target.expand(false, null, function(){
255 this.completeDrop(dropEvent);
256 }.createDelegate(this));
258 this.completeDrop(dropEvent);
264 completeDrop : function(de){
265 var ns = de.dropNode, p = de.point, t = de.target;
266 if(!Ext.isArray(ns)){
270 for(var i = 0, len = ns.length; i < len; i++){
273 t.parentNode.insertBefore(n, t);
274 }else if(p == "below"){
275 t.parentNode.insertBefore(n, t.nextSibling);
281 if(Ext.enableFx && this.tree.hlDrop){
285 this.tree.fireEvent("nodedrop", de);
289 afterNodeMoved : function(dd, data, e, targetNode, dropNode){
290 if(Ext.enableFx && this.tree.hlDrop){
292 dropNode.ui.highlight();
294 this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
298 getTree : function(){
303 removeDropIndicators : function(n){
306 Ext.fly(el).removeClass([
307 "x-tree-drag-insert-above",
308 "x-tree-drag-insert-below",
309 "x-tree-drag-append"]);
310 this.lastInsertClass = "_noclass";
315 beforeDragDrop : function(target, e, id){
321 afterRepair : function(data){
322 if(data && Ext.enableFx){
323 data.node.ui.highlight();