| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 | <!DOCTYPE html><html><head>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  <title>The source code</title>  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>  <style type="text/css">    .highlight { display: block; background-color: #ddd; }  </style>  <script type="text/javascript">    function highlight() {      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";    }  </script></head><body onload="prettyPrint(); highlight();">  <pre class="prettyprint lang-js"><span id='Ext-tree-ViewDropZone'>/**</span> * @private */Ext.define('Ext.tree.ViewDropZone', {    extend: 'Ext.view.DropZone',<span id='Ext-tree-ViewDropZone-cfg-allowParentInsert'>    /**</span>     * @cfg {Boolean} allowParentInsert     * Allow inserting a dragged node between an expanded parent node and its first child that will become a     * sibling of the parent when dropped.     */    allowParentInserts: false, <span id='Ext-tree-ViewDropZone-cfg-allowContainerDrop'>    /**</span>     * @cfg {String} allowContainerDrop     * True if drops on the tree container (outside of a specific tree node) are allowed.     */    allowContainerDrops: false,<span id='Ext-tree-ViewDropZone-cfg-appendOnly'>    /**</span>     * @cfg {String} appendOnly     * True if the tree should only allow append drops (use for trees which are sorted).     */    appendOnly: false,<span id='Ext-tree-ViewDropZone-cfg-expandDelay'>    /**</span>     * @cfg {String} expandDelay     * The delay in milliseconds to wait before expanding a target tree node while dragging a droppable node     * over the target.     */    expandDelay : 500,    indicatorCls: Ext.baseCSSPrefix + 'tree-ddindicator',    // private    expandNode : function(node) {        var view = this.view;        if (!node.isLeaf() && !node.isExpanded()) {            view.expand(node);            this.expandProcId = false;        }    },    // private    queueExpand : function(node) {        this.expandProcId = Ext.Function.defer(this.expandNode, this.expandDelay, this, [node]);    },    // private    cancelExpand : function() {        if (this.expandProcId) {            clearTimeout(this.expandProcId);            this.expandProcId = false;        }    },    getPosition: function(e, node) {        var view = this.view,            record = view.getRecord(node),            y = e.getPageY(),            noAppend = record.isLeaf(),            noBelow = false,            region = Ext.fly(node).getRegion(),            fragment;        // If we are dragging on top of the root node of the tree, we always want to append.        if (record.isRoot()) {            return 'append';        }        // Return 'append' if the node we are dragging on top of is not a leaf else return false.        if (this.appendOnly) {            return noAppend ? false : 'append';        }        if (!this.allowParentInsert) {            noBelow = record.hasChildNodes() && record.isExpanded();        }        fragment = (region.bottom - region.top) / (noAppend ? 2 : 3);        if (y >= region.top && y < (region.top + fragment)) {            return 'before';        }        else if (!noBelow && (noAppend || (y >= (region.bottom - fragment) && y <= region.bottom))) {            return 'after';        }        else {            return 'append';        }    },    isValidDropPoint : function(node, position, dragZone, e, data) {        if (!node || !data.item) {            return false;        }        var view = this.view,            targetNode = view.getRecord(node),            draggedRecords = data.records,            dataLength = draggedRecords.length,            ln = draggedRecords.length,            i, record;        // No drop position, or dragged records: invalid drop point        if (!(targetNode && position && dataLength)) {            return false;        }        // If the targetNode is within the folder we are dragging        for (i = 0; i < ln; i++) {            record = draggedRecords[i];            if (record.isNode && record.contains(targetNode)) {                return false;            }        }                // Respect the allowDrop field on Tree nodes        if (position === 'append' && targetNode.get('allowDrop') === false) {            return false;        }        else if (position != 'append' && targetNode.parentNode.get('allowDrop') === false) {            return false;        }        // If the target record is in the dragged dataset, then invalid drop        if (Ext.Array.contains(draggedRecords, targetNode)) {             return false;        }        // @TODO: fire some event to notify that there is a valid drop possible for the node you're dragging        // Yes: this.fireViewEvent(blah....) fires an event through the owning View.        return true;    },    onNodeOver : function(node, dragZone, e, data) {        var position = this.getPosition(e, node),            returnCls = this.dropNotAllowed,            view = this.view,            targetNode = view.getRecord(node),            indicator = this.getIndicator(),            indicatorX = 0,            indicatorY = 0;        // auto node expand check        this.cancelExpand();        if (position == 'append' && !this.expandProcId && !Ext.Array.contains(data.records, targetNode) && !targetNode.isLeaf() && !targetNode.isExpanded()) {            this.queueExpand(targetNode);        }                                if (this.isValidDropPoint(node, position, dragZone, e, data)) {            this.valid = true;            this.currentPosition = position;            this.overRecord = targetNode;            indicator.setWidth(Ext.fly(node).getWidth());            indicatorY = Ext.fly(node).getY() - Ext.fly(view.el).getY() - 1;            /*             * In the code below we show the proxy again. The reason for doing this is showing the indicator will             * call toFront, causing it to get a new z-index which can sometimes push the proxy behind it. We always              * want the proxy to be above, so calling show on the proxy will call toFront and bring it forward.             */            if (position == 'before') {                returnCls = targetNode.isFirst() ? Ext.baseCSSPrefix + 'tree-drop-ok-above' : Ext.baseCSSPrefix + 'tree-drop-ok-between';                indicator.showAt(0, indicatorY);                dragZone.proxy.show();            } else if (position == 'after') {                returnCls = targetNode.isLast() ? Ext.baseCSSPrefix + 'tree-drop-ok-below' : Ext.baseCSSPrefix + 'tree-drop-ok-between';                indicatorY += Ext.fly(node).getHeight();                indicator.showAt(0, indicatorY);                dragZone.proxy.show();            } else {                returnCls = Ext.baseCSSPrefix + 'tree-drop-ok-append';                // @TODO: set a class on the parent folder node to be able to style it                indicator.hide();            }        } else {            this.valid = false;        }        this.currentCls = returnCls;        return returnCls;    },    onContainerOver : function(dd, e, data) {        return e.getTarget('.' + this.indicatorCls) ? this.currentCls : this.dropNotAllowed;    },        notifyOut: function() {        this.callParent(arguments);        this.cancelExpand();    },    handleNodeDrop : function(data, targetNode, position) {        var me = this,            view = me.view,            parentNode = targetNode.parentNode,            store = view.getStore(),            recordDomNodes = [],            records, i, len,            insertionMethod, argList,            needTargetExpand,            transferData,            processDrop;        // If the copy flag is set, create a copy of the Models with the same IDs        if (data.copy) {            records = data.records;            data.records = [];            for (i = 0, len = records.length; i < len; i++) {                data.records.push(Ext.apply({}, records[i].data));            }        }        // Cancel any pending expand operation        me.cancelExpand();        // Grab a reference to the correct node insertion method.        // Create an arg list array intended for the apply method of the        // chosen node insertion method.        // Ensure the target object for the method is referenced by 'targetNode'        if (position == 'before') {            insertionMethod = parentNode.insertBefore;            argList = [null, targetNode];            targetNode = parentNode;        }        else if (position == 'after') {            if (targetNode.nextSibling) {                insertionMethod = parentNode.insertBefore;                argList = [null, targetNode.nextSibling];            }            else {                insertionMethod = parentNode.appendChild;                argList = [null];            }            targetNode = parentNode;        }        else {            if (!targetNode.isExpanded()) {                needTargetExpand = true;            }            insertionMethod = targetNode.appendChild;            argList = [null];        }        // A function to transfer the data into the destination tree        transferData = function() {            var node,                r, rLen, color, n;            for (i = 0, len = data.records.length; i < len; i++) {                argList[0] = data.records[i];                node = insertionMethod.apply(targetNode, argList);                                if (Ext.enableFx && me.dropHighlight) {                    recordDomNodes.push(view.getNode(node));                }            }                        // Kick off highlights after everything's been inserted, so they are            // more in sync without insertion/render overhead.            if (Ext.enableFx && me.dropHighlight) {                //FIXME: the check for n.firstChild is not a great solution here. Ideally the line should simply read                 //Ext.fly(n.firstChild) but this yields errors in IE6 and 7. See ticket EXTJSIV-1705 for more details                rLen  = recordDomNodes.length;                color = me.dropHighlightColor;                for (r = 0; r < rLen; r++) {                    n = recordDomNodes[r];                    if (n) {                        Ext.fly(n.firstChild ? n.firstChild : n).highlight(color);                    }                }            }        };        // If dropping right on an unexpanded node, transfer the data after it is expanded.        if (needTargetExpand) {            targetNode.expand(false, transferData);        }        // Otherwise, call the data transfer function immediately        else {            transferData();        }    }});</pre></body></html>
 |