DDCore.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:96k
源码类别:

JavaScript

开发平台:

JavaScript

  1. /*!
  2.  * Ext JS Library 3.1.0
  3.  * Copyright(c) 2006-2009 Ext JS, LLC
  4.  * licensing@extjs.com
  5.  * http://www.extjs.com/license
  6.  */
  7. /*
  8.  * These classes are derivatives of the similarly named classes in the YUI Library.
  9.  * The original license:
  10.  * Copyright (c) 2006, Yahoo! Inc. All rights reserved.
  11.  * Code licensed under the BSD License:
  12.  * http://developer.yahoo.net/yui/license.txt
  13.  */
  14. (function() {
  15. var Event=Ext.EventManager;
  16. var Dom=Ext.lib.Dom;
  17. /**
  18.  * @class Ext.dd.DragDrop
  19.  * Defines the interface and base operation of items that that can be
  20.  * dragged or can be drop targets.  It was designed to be extended, overriding
  21.  * the event handlers for startDrag, onDrag, onDragOver and onDragOut.
  22.  * Up to three html elements can be associated with a DragDrop instance:
  23.  * <ul>
  24.  * <li>linked element: the element that is passed into the constructor.
  25.  * This is the element which defines the boundaries for interaction with
  26.  * other DragDrop objects.</li>
  27.  * <li>handle element(s): The drag operation only occurs if the element that
  28.  * was clicked matches a handle element.  By default this is the linked
  29.  * element, but there are times that you will want only a portion of the
  30.  * linked element to initiate the drag operation, and the setHandleElId()
  31.  * method provides a way to define this.</li>
  32.  * <li>drag element: this represents the element that would be moved along
  33.  * with the cursor during a drag operation.  By default, this is the linked
  34.  * element itself as in {@link Ext.dd.DD}.  setDragElId() lets you define
  35.  * a separate element that would be moved, as in {@link Ext.dd.DDProxy}.
  36.  * </li>
  37.  * </ul>
  38.  * This class should not be instantiated until the onload event to ensure that
  39.  * the associated elements are available.
  40.  * The following would define a DragDrop obj that would interact with any
  41.  * other DragDrop obj in the "group1" group:
  42.  * <pre>
  43.  *  dd = new Ext.dd.DragDrop("div1", "group1");
  44.  * </pre>
  45.  * Since none of the event handlers have been implemented, nothing would
  46.  * actually happen if you were to run the code above.  Normally you would
  47.  * override this class or one of the default implementations, but you can
  48.  * also override the methods you want on an instance of the class...
  49.  * <pre>
  50.  *  dd.onDragDrop = function(e, id) {
  51.  *  &nbsp;&nbsp;alert("dd was dropped on " + id);
  52.  *  }
  53.  * </pre>
  54.  * @constructor
  55.  * @param {String} id of the element that is linked to this instance
  56.  * @param {String} sGroup the group of related DragDrop objects
  57.  * @param {object} config an object containing configurable attributes
  58.  *                Valid properties for DragDrop:
  59.  *                    padding, isTarget, maintainOffset, primaryButtonOnly
  60.  */
  61. Ext.dd.DragDrop = function(id, sGroup, config) {
  62.     if(id) {
  63.         this.init(id, sGroup, config);
  64.     }
  65. };
  66. Ext.dd.DragDrop.prototype = {
  67.     /**
  68.      * Set to false to enable a DragDrop object to fire drag events while dragging
  69.      * over its own Element. Defaults to true - DragDrop objects do not by default
  70.      * fire drag events to themselves.
  71.      * @property ignoreSelf
  72.      * @type Boolean
  73.      */
  74.     /**
  75.      * The id of the element associated with this object.  This is what we
  76.      * refer to as the "linked element" because the size and position of
  77.      * this element is used to determine when the drag and drop objects have
  78.      * interacted.
  79.      * @property id
  80.      * @type String
  81.      */
  82.     id: null,
  83.     /**
  84.      * Configuration attributes passed into the constructor
  85.      * @property config
  86.      * @type object
  87.      */
  88.     config: null,
  89.     /**
  90.      * The id of the element that will be dragged.  By default this is same
  91.      * as the linked element , but could be changed to another element. Ex:
  92.      * Ext.dd.DDProxy
  93.      * @property dragElId
  94.      * @type String
  95.      * @private
  96.      */
  97.     dragElId: null,
  98.     /**
  99.      * The ID of the element that initiates the drag operation.  By default
  100.      * this is the linked element, but could be changed to be a child of this
  101.      * element.  This lets us do things like only starting the drag when the
  102.      * header element within the linked html element is clicked.
  103.      * @property handleElId
  104.      * @type String
  105.      * @private
  106.      */
  107.     handleElId: null,
  108.     /**
  109.      * An object who's property names identify HTML tags to be considered invalid as drag handles.
  110.      * A non-null property value identifies the tag as invalid. Defaults to the 
  111.      * following value which prevents drag operations from being initiated by &lt;a> elements:<pre><code>
  112. {
  113.     A: "A"
  114. }</code></pre>
  115.      * @property invalidHandleTypes
  116.      * @type Object
  117.      */
  118.     invalidHandleTypes: null,
  119.     /**
  120.      * An object who's property names identify the IDs of elements to be considered invalid as drag handles.
  121.      * A non-null property value identifies the ID as invalid. For example, to prevent
  122.      * dragging from being initiated on element ID "foo", use:<pre><code>
  123. {
  124.     foo: true
  125. }</code></pre>
  126.      * @property invalidHandleIds
  127.      * @type Object
  128.      */
  129.     invalidHandleIds: null,
  130.     /**
  131.      * An Array of CSS class names for elements to be considered in valid as drag handles.
  132.      * @property invalidHandleClasses
  133.      * @type Array
  134.      */
  135.     invalidHandleClasses: null,
  136.     /**
  137.      * The linked element's absolute X position at the time the drag was
  138.      * started
  139.      * @property startPageX
  140.      * @type int
  141.      * @private
  142.      */
  143.     startPageX: 0,
  144.     /**
  145.      * The linked element's absolute X position at the time the drag was
  146.      * started
  147.      * @property startPageY
  148.      * @type int
  149.      * @private
  150.      */
  151.     startPageY: 0,
  152.     /**
  153.      * The group defines a logical collection of DragDrop objects that are
  154.      * related.  Instances only get events when interacting with other
  155.      * DragDrop object in the same group.  This lets us define multiple
  156.      * groups using a single DragDrop subclass if we want.
  157.      * @property groups
  158.      * @type object An object in the format {'group1':true, 'group2':true}
  159.      */
  160.     groups: null,
  161.     /**
  162.      * Individual drag/drop instances can be locked.  This will prevent
  163.      * onmousedown start drag.
  164.      * @property locked
  165.      * @type boolean
  166.      * @private
  167.      */
  168.     locked: false,
  169.     /**
  170.      * Lock this instance
  171.      * @method lock
  172.      */
  173.     lock: function() { this.locked = true; },
  174.     /**
  175.      * When set to true, other DD objects in cooperating DDGroups do not receive
  176.      * notification events when this DD object is dragged over them. Defaults to false.
  177.      * @property moveOnly
  178.      * @type boolean
  179.      */
  180.     moveOnly: false,
  181.     /**
  182.      * Unlock this instace
  183.      * @method unlock
  184.      */
  185.     unlock: function() { this.locked = false; },
  186.     /**
  187.      * By default, all instances can be a drop target.  This can be disabled by
  188.      * setting isTarget to false.
  189.      * @property isTarget
  190.      * @type boolean
  191.      */
  192.     isTarget: true,
  193.     /**
  194.      * The padding configured for this drag and drop object for calculating
  195.      * the drop zone intersection with this object.
  196.      * @property padding
  197.      * @type int[] An array containing the 4 padding values: [top, right, bottom, left]
  198.      */
  199.     padding: null,
  200.     /**
  201.      * Cached reference to the linked element
  202.      * @property _domRef
  203.      * @private
  204.      */
  205.     _domRef: null,
  206.     /**
  207.      * Internal typeof flag
  208.      * @property __ygDragDrop
  209.      * @private
  210.      */
  211.     __ygDragDrop: true,
  212.     /**
  213.      * Set to true when horizontal contraints are applied
  214.      * @property constrainX
  215.      * @type boolean
  216.      * @private
  217.      */
  218.     constrainX: false,
  219.     /**
  220.      * Set to true when vertical contraints are applied
  221.      * @property constrainY
  222.      * @type boolean
  223.      * @private
  224.      */
  225.     constrainY: false,
  226.     /**
  227.      * The left constraint
  228.      * @property minX
  229.      * @type int
  230.      * @private
  231.      */
  232.     minX: 0,
  233.     /**
  234.      * The right constraint
  235.      * @property maxX
  236.      * @type int
  237.      * @private
  238.      */
  239.     maxX: 0,
  240.     /**
  241.      * The up constraint
  242.      * @property minY
  243.      * @type int
  244.      * @type int
  245.      * @private
  246.      */
  247.     minY: 0,
  248.     /**
  249.      * The down constraint
  250.      * @property maxY
  251.      * @type int
  252.      * @private
  253.      */
  254.     maxY: 0,
  255.     /**
  256.      * Maintain offsets when we resetconstraints.  Set to true when you want
  257.      * the position of the element relative to its parent to stay the same
  258.      * when the page changes
  259.      *
  260.      * @property maintainOffset
  261.      * @type boolean
  262.      */
  263.     maintainOffset: false,
  264.     /**
  265.      * Array of pixel locations the element will snap to if we specified a
  266.      * horizontal graduation/interval.  This array is generated automatically
  267.      * when you define a tick interval.
  268.      * @property xTicks
  269.      * @type int[]
  270.      */
  271.     xTicks: null,
  272.     /**
  273.      * Array of pixel locations the element will snap to if we specified a
  274.      * vertical graduation/interval.  This array is generated automatically
  275.      * when you define a tick interval.
  276.      * @property yTicks
  277.      * @type int[]
  278.      */
  279.     yTicks: null,
  280.     /**
  281.      * By default the drag and drop instance will only respond to the primary
  282.      * button click (left button for a right-handed mouse).  Set to true to
  283.      * allow drag and drop to start with any mouse click that is propogated
  284.      * by the browser
  285.      * @property primaryButtonOnly
  286.      * @type boolean
  287.      */
  288.     primaryButtonOnly: true,
  289.     /**
  290.      * The availabe property is false until the linked dom element is accessible.
  291.      * @property available
  292.      * @type boolean
  293.      */
  294.     available: false,
  295.     /**
  296.      * By default, drags can only be initiated if the mousedown occurs in the
  297.      * region the linked element is.  This is done in part to work around a
  298.      * bug in some browsers that mis-report the mousedown if the previous
  299.      * mouseup happened outside of the window.  This property is set to true
  300.      * if outer handles are defined.
  301.      *
  302.      * @property hasOuterHandles
  303.      * @type boolean
  304.      * @default false
  305.      */
  306.     hasOuterHandles: false,
  307.     /**
  308.      * Code that executes immediately before the startDrag event
  309.      * @method b4StartDrag
  310.      * @private
  311.      */
  312.     b4StartDrag: function(x, y) { },
  313.     /**
  314.      * Abstract method called after a drag/drop object is clicked
  315.      * and the drag or mousedown time thresholds have beeen met.
  316.      * @method startDrag
  317.      * @param {int} X click location
  318.      * @param {int} Y click location
  319.      */
  320.     startDrag: function(x, y) { /* override this */ },
  321.     /**
  322.      * Code that executes immediately before the onDrag event
  323.      * @method b4Drag
  324.      * @private
  325.      */
  326.     b4Drag: function(e) { },
  327.     /**
  328.      * Abstract method called during the onMouseMove event while dragging an
  329.      * object.
  330.      * @method onDrag
  331.      * @param {Event} e the mousemove event
  332.      */
  333.     onDrag: function(e) { /* override this */ },
  334.     /**
  335.      * Abstract method called when this element fist begins hovering over
  336.      * another DragDrop obj
  337.      * @method onDragEnter
  338.      * @param {Event} e the mousemove event
  339.      * @param {String|DragDrop[]} id In POINT mode, the element
  340.      * id this is hovering over.  In INTERSECT mode, an array of one or more
  341.      * dragdrop items being hovered over.
  342.      */
  343.     onDragEnter: function(e, id) { /* override this */ },
  344.     /**
  345.      * Code that executes immediately before the onDragOver event
  346.      * @method b4DragOver
  347.      * @private
  348.      */
  349.     b4DragOver: function(e) { },
  350.     /**
  351.      * Abstract method called when this element is hovering over another
  352.      * DragDrop obj
  353.      * @method onDragOver
  354.      * @param {Event} e the mousemove event
  355.      * @param {String|DragDrop[]} id In POINT mode, the element
  356.      * id this is hovering over.  In INTERSECT mode, an array of dd items
  357.      * being hovered over.
  358.      */
  359.     onDragOver: function(e, id) { /* override this */ },
  360.     /**
  361.      * Code that executes immediately before the onDragOut event
  362.      * @method b4DragOut
  363.      * @private
  364.      */
  365.     b4DragOut: function(e) { },
  366.     /**
  367.      * Abstract method called when we are no longer hovering over an element
  368.      * @method onDragOut
  369.      * @param {Event} e the mousemove event
  370.      * @param {String|DragDrop[]} id In POINT mode, the element
  371.      * id this was hovering over.  In INTERSECT mode, an array of dd items
  372.      * that the mouse is no longer over.
  373.      */
  374.     onDragOut: function(e, id) { /* override this */ },
  375.     /**
  376.      * Code that executes immediately before the onDragDrop event
  377.      * @method b4DragDrop
  378.      * @private
  379.      */
  380.     b4DragDrop: function(e) { },
  381.     /**
  382.      * Abstract method called when this item is dropped on another DragDrop
  383.      * obj
  384.      * @method onDragDrop
  385.      * @param {Event} e the mouseup event
  386.      * @param {String|DragDrop[]} id In POINT mode, the element
  387.      * id this was dropped on.  In INTERSECT mode, an array of dd items this
  388.      * was dropped on.
  389.      */
  390.     onDragDrop: function(e, id) { /* override this */ },
  391.     /**
  392.      * Abstract method called when this item is dropped on an area with no
  393.      * drop target
  394.      * @method onInvalidDrop
  395.      * @param {Event} e the mouseup event
  396.      */
  397.     onInvalidDrop: function(e) { /* override this */ },
  398.     /**
  399.      * Code that executes immediately before the endDrag event
  400.      * @method b4EndDrag
  401.      * @private
  402.      */
  403.     b4EndDrag: function(e) { },
  404.     /**
  405.      * Fired when we are done dragging the object
  406.      * @method endDrag
  407.      * @param {Event} e the mouseup event
  408.      */
  409.     endDrag: function(e) { /* override this */ },
  410.     /**
  411.      * Code executed immediately before the onMouseDown event
  412.      * @method b4MouseDown
  413.      * @param {Event} e the mousedown event
  414.      * @private
  415.      */
  416.     b4MouseDown: function(e) {  },
  417.     /**
  418.      * Event handler that fires when a drag/drop obj gets a mousedown
  419.      * @method onMouseDown
  420.      * @param {Event} e the mousedown event
  421.      */
  422.     onMouseDown: function(e) { /* override this */ },
  423.     /**
  424.      * Event handler that fires when a drag/drop obj gets a mouseup
  425.      * @method onMouseUp
  426.      * @param {Event} e the mouseup event
  427.      */
  428.     onMouseUp: function(e) { /* override this */ },
  429.     /**
  430.      * Override the onAvailable method to do what is needed after the initial
  431.      * position was determined.
  432.      * @method onAvailable
  433.      */
  434.     onAvailable: function () {
  435.     },
  436.     /**
  437.      * Provides default constraint padding to "constrainTo" elements (defaults to {left: 0, right:0, top:0, bottom:0}).
  438.      * @type Object
  439.      */
  440.     defaultPadding : {left:0, right:0, top:0, bottom:0},
  441.     /**
  442.      * Initializes the drag drop object's constraints to restrict movement to a certain element.
  443.  *
  444.  * Usage:
  445.  <pre><code>
  446.  var dd = new Ext.dd.DDProxy("dragDiv1", "proxytest",
  447.                 { dragElId: "existingProxyDiv" });
  448.  dd.startDrag = function(){
  449.      this.constrainTo("parent-id");
  450.  };
  451.  </code></pre>
  452.  * Or you can initalize it using the {@link Ext.Element} object:
  453.  <pre><code>
  454.  Ext.get("dragDiv1").initDDProxy("proxytest", {dragElId: "existingProxyDiv"}, {
  455.      startDrag : function(){
  456.          this.constrainTo("parent-id");
  457.      }
  458.  });
  459.  </code></pre>
  460.      * @param {Mixed} constrainTo The element to constrain to.
  461.      * @param {Object/Number} pad (optional) Pad provides a way to specify "padding" of the constraints,
  462.      * and can be either a number for symmetrical padding (4 would be equal to {left:4, right:4, top:4, bottom:4}) or
  463.      * an object containing the sides to pad. For example: {right:10, bottom:10}
  464.      * @param {Boolean} inContent (optional) Constrain the draggable in the content box of the element (inside padding and borders)
  465.      */
  466.     constrainTo : function(constrainTo, pad, inContent){
  467.         if(Ext.isNumber(pad)){
  468.             pad = {left: pad, right:pad, top:pad, bottom:pad};
  469.         }
  470.         pad = pad || this.defaultPadding;
  471.         var b = Ext.get(this.getEl()).getBox(),
  472.             ce = Ext.get(constrainTo),
  473.             s = ce.getScroll(),
  474.             c, 
  475.             cd = ce.dom;
  476.         if(cd == document.body){
  477.             c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};
  478.         }else{
  479.             var xy = ce.getXY();
  480.             c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight};
  481.         }
  482.         var topSpace = b.y - c.y,
  483.             leftSpace = b.x - c.x;
  484.         this.resetConstraints();
  485.         this.setXConstraint(leftSpace - (pad.left||0), // left
  486.                 c.width - leftSpace - b.width - (pad.right||0), //right
  487. this.xTickSize
  488.         );
  489.         this.setYConstraint(topSpace - (pad.top||0), //top
  490.                 c.height - topSpace - b.height - (pad.bottom||0), //bottom
  491. this.yTickSize
  492.         );
  493.     },
  494.     /**
  495.      * Returns a reference to the linked element
  496.      * @method getEl
  497.      * @return {HTMLElement} the html element
  498.      */
  499.     getEl: function() {
  500.         if (!this._domRef) {
  501.             this._domRef = Ext.getDom(this.id);
  502.         }
  503.         return this._domRef;
  504.     },
  505.     /**
  506.      * Returns a reference to the actual element to drag.  By default this is
  507.      * the same as the html element, but it can be assigned to another
  508.      * element. An example of this can be found in Ext.dd.DDProxy
  509.      * @method getDragEl
  510.      * @return {HTMLElement} the html element
  511.      */
  512.     getDragEl: function() {
  513.         return Ext.getDom(this.dragElId);
  514.     },
  515.     /**
  516.      * Sets up the DragDrop object.  Must be called in the constructor of any
  517.      * Ext.dd.DragDrop subclass
  518.      * @method init
  519.      * @param id the id of the linked element
  520.      * @param {String} sGroup the group of related items
  521.      * @param {object} config configuration attributes
  522.      */
  523.     init: function(id, sGroup, config) {
  524.         this.initTarget(id, sGroup, config);
  525.         Event.on(this.id, "mousedown", this.handleMouseDown, this);
  526.         // Event.on(this.id, "selectstart", Event.preventDefault);
  527.     },
  528.     /**
  529.      * Initializes Targeting functionality only... the object does not
  530.      * get a mousedown handler.
  531.      * @method initTarget
  532.      * @param id the id of the linked element
  533.      * @param {String} sGroup the group of related items
  534.      * @param {object} config configuration attributes
  535.      */
  536.     initTarget: function(id, sGroup, config) {
  537.         // configuration attributes
  538.         this.config = config || {};
  539.         // create a local reference to the drag and drop manager
  540.         this.DDM = Ext.dd.DDM;
  541.         // initialize the groups array
  542.         this.groups = {};
  543.         // assume that we have an element reference instead of an id if the
  544.         // parameter is not a string
  545.         if (typeof id !== "string") {
  546.             id = Ext.id(id);
  547.         }
  548.         // set the id
  549.         this.id = id;
  550.         // add to an interaction group
  551.         this.addToGroup((sGroup) ? sGroup : "default");
  552.         // We don't want to register this as the handle with the manager
  553.         // so we just set the id rather than calling the setter.
  554.         this.handleElId = id;
  555.         // the linked element is the element that gets dragged by default
  556.         this.setDragElId(id);
  557.         // by default, clicked anchors will not start drag operations.
  558.         this.invalidHandleTypes = { A: "A" };
  559.         this.invalidHandleIds = {};
  560.         this.invalidHandleClasses = [];
  561.         this.applyConfig();
  562.         this.handleOnAvailable();
  563.     },
  564.     /**
  565.      * Applies the configuration parameters that were passed into the constructor.
  566.      * This is supposed to happen at each level through the inheritance chain.  So
  567.      * a DDProxy implentation will execute apply config on DDProxy, DD, and
  568.      * DragDrop in order to get all of the parameters that are available in
  569.      * each object.
  570.      * @method applyConfig
  571.      */
  572.     applyConfig: function() {
  573.         // configurable properties:
  574.         //    padding, isTarget, maintainOffset, primaryButtonOnly
  575.         this.padding           = this.config.padding || [0, 0, 0, 0];
  576.         this.isTarget          = (this.config.isTarget !== false);
  577.         this.maintainOffset    = (this.config.maintainOffset);
  578.         this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
  579.     },
  580.     /**
  581.      * Executed when the linked element is available
  582.      * @method handleOnAvailable
  583.      * @private
  584.      */
  585.     handleOnAvailable: function() {
  586.         this.available = true;
  587.         this.resetConstraints();
  588.         this.onAvailable();
  589.     },
  590.      /**
  591.      * Configures the padding for the target zone in px.  Effectively expands
  592.      * (or reduces) the virtual object size for targeting calculations.
  593.      * Supports css-style shorthand; if only one parameter is passed, all sides
  594.      * will have that padding, and if only two are passed, the top and bottom
  595.      * will have the first param, the left and right the second.
  596.      * @method setPadding
  597.      * @param {int} iTop    Top pad
  598.      * @param {int} iRight  Right pad
  599.      * @param {int} iBot    Bot pad
  600.      * @param {int} iLeft   Left pad
  601.      */
  602.     setPadding: function(iTop, iRight, iBot, iLeft) {
  603.         // this.padding = [iLeft, iRight, iTop, iBot];
  604.         if (!iRight && 0 !== iRight) {
  605.             this.padding = [iTop, iTop, iTop, iTop];
  606.         } else if (!iBot && 0 !== iBot) {
  607.             this.padding = [iTop, iRight, iTop, iRight];
  608.         } else {
  609.             this.padding = [iTop, iRight, iBot, iLeft];
  610.         }
  611.     },
  612.     /**
  613.      * Stores the initial placement of the linked element.
  614.      * @method setInitPosition
  615.      * @param {int} diffX   the X offset, default 0
  616.      * @param {int} diffY   the Y offset, default 0
  617.      */
  618.     setInitPosition: function(diffX, diffY) {
  619.         var el = this.getEl();
  620.         if (!this.DDM.verifyEl(el)) {
  621.             return;
  622.         }
  623.         var dx = diffX || 0;
  624.         var dy = diffY || 0;
  625.         var p = Dom.getXY( el );
  626.         this.initPageX = p[0] - dx;
  627.         this.initPageY = p[1] - dy;
  628.         this.lastPageX = p[0];
  629.         this.lastPageY = p[1];
  630.         this.setStartPosition(p);
  631.     },
  632.     /**
  633.      * Sets the start position of the element.  This is set when the obj
  634.      * is initialized, the reset when a drag is started.
  635.      * @method setStartPosition
  636.      * @param pos current position (from previous lookup)
  637.      * @private
  638.      */
  639.     setStartPosition: function(pos) {
  640.         var p = pos || Dom.getXY( this.getEl() );
  641.         this.deltaSetXY = null;
  642.         this.startPageX = p[0];
  643.         this.startPageY = p[1];
  644.     },
  645.     /**
  646.      * Add this instance to a group of related drag/drop objects.  All
  647.      * instances belong to at least one group, and can belong to as many
  648.      * groups as needed.
  649.      * @method addToGroup
  650.      * @param sGroup {string} the name of the group
  651.      */
  652.     addToGroup: function(sGroup) {
  653.         this.groups[sGroup] = true;
  654.         this.DDM.regDragDrop(this, sGroup);
  655.     },
  656.     /**
  657.      * Remove's this instance from the supplied interaction group
  658.      * @method removeFromGroup
  659.      * @param {string}  sGroup  The group to drop
  660.      */
  661.     removeFromGroup: function(sGroup) {
  662.         if (this.groups[sGroup]) {
  663.             delete this.groups[sGroup];
  664.         }
  665.         this.DDM.removeDDFromGroup(this, sGroup);
  666.     },
  667.     /**
  668.      * Allows you to specify that an element other than the linked element
  669.      * will be moved with the cursor during a drag
  670.      * @method setDragElId
  671.      * @param id {string} the id of the element that will be used to initiate the drag
  672.      */
  673.     setDragElId: function(id) {
  674.         this.dragElId = id;
  675.     },
  676.     /**
  677.      * Allows you to specify a child of the linked element that should be
  678.      * used to initiate the drag operation.  An example of this would be if
  679.      * you have a content div with text and links.  Clicking anywhere in the
  680.      * content area would normally start the drag operation.  Use this method
  681.      * to specify that an element inside of the content div is the element
  682.      * that starts the drag operation.
  683.      * @method setHandleElId
  684.      * @param id {string} the id of the element that will be used to
  685.      * initiate the drag.
  686.      */
  687.     setHandleElId: function(id) {
  688.         if (typeof id !== "string") {
  689.             id = Ext.id(id);
  690.         }
  691.         this.handleElId = id;
  692.         this.DDM.regHandle(this.id, id);
  693.     },
  694.     /**
  695.      * Allows you to set an element outside of the linked element as a drag
  696.      * handle
  697.      * @method setOuterHandleElId
  698.      * @param id the id of the element that will be used to initiate the drag
  699.      */
  700.     setOuterHandleElId: function(id) {
  701.         if (typeof id !== "string") {
  702.             id = Ext.id(id);
  703.         }
  704.         Event.on(id, "mousedown",
  705.                 this.handleMouseDown, this);
  706.         this.setHandleElId(id);
  707.         this.hasOuterHandles = true;
  708.     },
  709.     /**
  710.      * Remove all drag and drop hooks for this element
  711.      * @method unreg
  712.      */
  713.     unreg: function() {
  714.         Event.un(this.id, "mousedown",
  715.                 this.handleMouseDown);
  716.         this._domRef = null;
  717.         this.DDM._remove(this);
  718.     },
  719.     destroy : function(){
  720.         this.unreg();
  721.     },
  722.     /**
  723.      * Returns true if this instance is locked, or the drag drop mgr is locked
  724.      * (meaning that all drag/drop is disabled on the page.)
  725.      * @method isLocked
  726.      * @return {boolean} true if this obj or all drag/drop is locked, else
  727.      * false
  728.      */
  729.     isLocked: function() {
  730.         return (this.DDM.isLocked() || this.locked);
  731.     },
  732.     /**
  733.      * Fired when this object is clicked
  734.      * @method handleMouseDown
  735.      * @param {Event} e
  736.      * @param {Ext.dd.DragDrop} oDD the clicked dd object (this dd obj)
  737.      * @private
  738.      */
  739.     handleMouseDown: function(e, oDD){
  740.         if (this.primaryButtonOnly && e.button != 0) {
  741.             return;
  742.         }
  743.         if (this.isLocked()) {
  744.             return;
  745.         }
  746.         this.DDM.refreshCache(this.groups);
  747.         var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));
  748.         if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) )  {
  749.         } else {
  750.             if (this.clickValidator(e)) {
  751.                 // set the initial element position
  752.                 this.setStartPosition();
  753.                 this.b4MouseDown(e);
  754.                 this.onMouseDown(e);
  755.                 this.DDM.handleMouseDown(e, this);
  756.                 this.DDM.stopEvent(e);
  757.             } else {
  758.             }
  759.         }
  760.     },
  761.     clickValidator: function(e) {
  762.         var target = e.getTarget();
  763.         return ( this.isValidHandleChild(target) &&
  764.                     (this.id == this.handleElId ||
  765.                         this.DDM.handleWasClicked(target, this.id)) );
  766.     },
  767.     /**
  768.      * Allows you to specify a tag name that should not start a drag operation
  769.      * when clicked.  This is designed to facilitate embedding links within a
  770.      * drag handle that do something other than start the drag.
  771.      * @method addInvalidHandleType
  772.      * @param {string} tagName the type of element to exclude
  773.      */
  774.     addInvalidHandleType: function(tagName) {
  775.         var type = tagName.toUpperCase();
  776.         this.invalidHandleTypes[type] = type;
  777.     },
  778.     /**
  779.      * Lets you to specify an element id for a child of a drag handle
  780.      * that should not initiate a drag
  781.      * @method addInvalidHandleId
  782.      * @param {string} id the element id of the element you wish to ignore
  783.      */
  784.     addInvalidHandleId: function(id) {
  785.         if (typeof id !== "string") {
  786.             id = Ext.id(id);
  787.         }
  788.         this.invalidHandleIds[id] = id;
  789.     },
  790.     /**
  791.      * Lets you specify a css class of elements that will not initiate a drag
  792.      * @method addInvalidHandleClass
  793.      * @param {string} cssClass the class of the elements you wish to ignore
  794.      */
  795.     addInvalidHandleClass: function(cssClass) {
  796.         this.invalidHandleClasses.push(cssClass);
  797.     },
  798.     /**
  799.      * Unsets an excluded tag name set by addInvalidHandleType
  800.      * @method removeInvalidHandleType
  801.      * @param {string} tagName the type of element to unexclude
  802.      */
  803.     removeInvalidHandleType: function(tagName) {
  804.         var type = tagName.toUpperCase();
  805.         // this.invalidHandleTypes[type] = null;
  806.         delete this.invalidHandleTypes[type];
  807.     },
  808.     /**
  809.      * Unsets an invalid handle id
  810.      * @method removeInvalidHandleId
  811.      * @param {string} id the id of the element to re-enable
  812.      */
  813.     removeInvalidHandleId: function(id) {
  814.         if (typeof id !== "string") {
  815.             id = Ext.id(id);
  816.         }
  817.         delete this.invalidHandleIds[id];
  818.     },
  819.     /**
  820.      * Unsets an invalid css class
  821.      * @method removeInvalidHandleClass
  822.      * @param {string} cssClass the class of the element(s) you wish to
  823.      * re-enable
  824.      */
  825.     removeInvalidHandleClass: function(cssClass) {
  826.         for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
  827.             if (this.invalidHandleClasses[i] == cssClass) {
  828.                 delete this.invalidHandleClasses[i];
  829.             }
  830.         }
  831.     },
  832.     /**
  833.      * Checks the tag exclusion list to see if this click should be ignored
  834.      * @method isValidHandleChild
  835.      * @param {HTMLElement} node the HTMLElement to evaluate
  836.      * @return {boolean} true if this is a valid tag type, false if not
  837.      */
  838.     isValidHandleChild: function(node) {
  839.         var valid = true;
  840.         // var n = (node.nodeName == "#text") ? node.parentNode : node;
  841.         var nodeName;
  842.         try {
  843.             nodeName = node.nodeName.toUpperCase();
  844.         } catch(e) {
  845.             nodeName = node.nodeName;
  846.         }
  847.         valid = valid && !this.invalidHandleTypes[nodeName];
  848.         valid = valid && !this.invalidHandleIds[node.id];
  849.         for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
  850.             valid = !Ext.fly(node).hasClass(this.invalidHandleClasses[i]);
  851.         }
  852.         return valid;
  853.     },
  854.     /**
  855.      * Create the array of horizontal tick marks if an interval was specified
  856.      * in setXConstraint().
  857.      * @method setXTicks
  858.      * @private
  859.      */
  860.     setXTicks: function(iStartX, iTickSize) {
  861.         this.xTicks = [];
  862.         this.xTickSize = iTickSize;
  863.         var tickMap = {};
  864.         for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
  865.             if (!tickMap[i]) {
  866.                 this.xTicks[this.xTicks.length] = i;
  867.                 tickMap[i] = true;
  868.             }
  869.         }
  870.         for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
  871.             if (!tickMap[i]) {
  872.                 this.xTicks[this.xTicks.length] = i;
  873.                 tickMap[i] = true;
  874.             }
  875.         }
  876.         this.xTicks.sort(this.DDM.numericSort) ;
  877.     },
  878.     /**
  879.      * Create the array of vertical tick marks if an interval was specified in
  880.      * setYConstraint().
  881.      * @method setYTicks
  882.      * @private
  883.      */
  884.     setYTicks: function(iStartY, iTickSize) {
  885.         this.yTicks = [];
  886.         this.yTickSize = iTickSize;
  887.         var tickMap = {};
  888.         for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
  889.             if (!tickMap[i]) {
  890.                 this.yTicks[this.yTicks.length] = i;
  891.                 tickMap[i] = true;
  892.             }
  893.         }
  894.         for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
  895.             if (!tickMap[i]) {
  896.                 this.yTicks[this.yTicks.length] = i;
  897.                 tickMap[i] = true;
  898.             }
  899.         }
  900.         this.yTicks.sort(this.DDM.numericSort) ;
  901.     },
  902.     /**
  903.      * By default, the element can be dragged any place on the screen.  Use
  904.      * this method to limit the horizontal travel of the element.  Pass in
  905.      * 0,0 for the parameters if you want to lock the drag to the y axis.
  906.      * @method setXConstraint
  907.      * @param {int} iLeft the number of pixels the element can move to the left
  908.      * @param {int} iRight the number of pixels the element can move to the
  909.      * right
  910.      * @param {int} iTickSize optional parameter for specifying that the
  911.      * element
  912.      * should move iTickSize pixels at a time.
  913.      */
  914.     setXConstraint: function(iLeft, iRight, iTickSize) {
  915.         this.leftConstraint = iLeft;
  916.         this.rightConstraint = iRight;
  917.         this.minX = this.initPageX - iLeft;
  918.         this.maxX = this.initPageX + iRight;
  919.         if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
  920.         this.constrainX = true;
  921.     },
  922.     /**
  923.      * Clears any constraints applied to this instance.  Also clears ticks
  924.      * since they can't exist independent of a constraint at this time.
  925.      * @method clearConstraints
  926.      */
  927.     clearConstraints: function() {
  928.         this.constrainX = false;
  929.         this.constrainY = false;
  930.         this.clearTicks();
  931.     },
  932.     /**
  933.      * Clears any tick interval defined for this instance
  934.      * @method clearTicks
  935.      */
  936.     clearTicks: function() {
  937.         this.xTicks = null;
  938.         this.yTicks = null;
  939.         this.xTickSize = 0;
  940.         this.yTickSize = 0;
  941.     },
  942.     /**
  943.      * By default, the element can be dragged any place on the screen.  Set
  944.      * this to limit the vertical travel of the element.  Pass in 0,0 for the
  945.      * parameters if you want to lock the drag to the x axis.
  946.      * @method setYConstraint
  947.      * @param {int} iUp the number of pixels the element can move up
  948.      * @param {int} iDown the number of pixels the element can move down
  949.      * @param {int} iTickSize optional parameter for specifying that the
  950.      * element should move iTickSize pixels at a time.
  951.      */
  952.     setYConstraint: function(iUp, iDown, iTickSize) {
  953.         this.topConstraint = iUp;
  954.         this.bottomConstraint = iDown;
  955.         this.minY = this.initPageY - iUp;
  956.         this.maxY = this.initPageY + iDown;
  957.         if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
  958.         this.constrainY = true;
  959.     },
  960.     /**
  961.      * resetConstraints must be called if you manually reposition a dd element.
  962.      * @method resetConstraints
  963.      * @param {boolean} maintainOffset
  964.      */
  965.     resetConstraints: function() {
  966.         // Maintain offsets if necessary
  967.         if (this.initPageX || this.initPageX === 0) {
  968.             // figure out how much this thing has moved
  969.             var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
  970.             var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
  971.             this.setInitPosition(dx, dy);
  972.         // This is the first time we have detected the element's position
  973.         } else {
  974.             this.setInitPosition();
  975.         }
  976.         if (this.constrainX) {
  977.             this.setXConstraint( this.leftConstraint,
  978.                                  this.rightConstraint,
  979.                                  this.xTickSize        );
  980.         }
  981.         if (this.constrainY) {
  982.             this.setYConstraint( this.topConstraint,
  983.                                  this.bottomConstraint,
  984.                                  this.yTickSize         );
  985.         }
  986.     },
  987.     /**
  988.      * Normally the drag element is moved pixel by pixel, but we can specify
  989.      * that it move a number of pixels at a time.  This method resolves the
  990.      * location when we have it set up like this.
  991.      * @method getTick
  992.      * @param {int} val where we want to place the object
  993.      * @param {int[]} tickArray sorted array of valid points
  994.      * @return {int} the closest tick
  995.      * @private
  996.      */
  997.     getTick: function(val, tickArray) {
  998.         if (!tickArray) {
  999.             // If tick interval is not defined, it is effectively 1 pixel,
  1000.             // so we return the value passed to us.
  1001.             return val;
  1002.         } else if (tickArray[0] >= val) {
  1003.             // The value is lower than the first tick, so we return the first
  1004.             // tick.
  1005.             return tickArray[0];
  1006.         } else {
  1007.             for (var i=0, len=tickArray.length; i<len; ++i) {
  1008.                 var next = i + 1;
  1009.                 if (tickArray[next] && tickArray[next] >= val) {
  1010.                     var diff1 = val - tickArray[i];
  1011.                     var diff2 = tickArray[next] - val;
  1012.                     return (diff2 > diff1) ? tickArray[i] : tickArray[next];
  1013.                 }
  1014.             }
  1015.             // The value is larger than the last tick, so we return the last
  1016.             // tick.
  1017.             return tickArray[tickArray.length - 1];
  1018.         }
  1019.     },
  1020.     /**
  1021.      * toString method
  1022.      * @method toString
  1023.      * @return {string} string representation of the dd obj
  1024.      */
  1025.     toString: function() {
  1026.         return ("DragDrop " + this.id);
  1027.     }
  1028. };
  1029. })();
  1030. /**
  1031.  * The drag and drop utility provides a framework for building drag and drop
  1032.  * applications.  In addition to enabling drag and drop for specific elements,
  1033.  * the drag and drop elements are tracked by the manager class, and the
  1034.  * interactions between the various elements are tracked during the drag and
  1035.  * the implementing code is notified about these important moments.
  1036.  */
  1037. // Only load the library once.  Rewriting the manager class would orphan
  1038. // existing drag and drop instances.
  1039. if (!Ext.dd.DragDropMgr) {
  1040. /**
  1041.  * @class Ext.dd.DragDropMgr
  1042.  * DragDropMgr is a singleton that tracks the element interaction for
  1043.  * all DragDrop items in the window.  Generally, you will not call
  1044.  * this class directly, but it does have helper methods that could
  1045.  * be useful in your DragDrop implementations.
  1046.  * @singleton
  1047.  */
  1048. Ext.dd.DragDropMgr = function() {
  1049.     var Event = Ext.EventManager;
  1050.     return {
  1051.         /**
  1052.          * Two dimensional Array of registered DragDrop objects.  The first
  1053.          * dimension is the DragDrop item group, the second the DragDrop
  1054.          * object.
  1055.          * @property ids
  1056.          * @type {string: string}
  1057.          * @private
  1058.          * @static
  1059.          */
  1060.         ids: {},
  1061.         /**
  1062.          * Array of element ids defined as drag handles.  Used to determine
  1063.          * if the element that generated the mousedown event is actually the
  1064.          * handle and not the html element itself.
  1065.          * @property handleIds
  1066.          * @type {string: string}
  1067.          * @private
  1068.          * @static
  1069.          */
  1070.         handleIds: {},
  1071.         /**
  1072.          * the DragDrop object that is currently being dragged
  1073.          * @property dragCurrent
  1074.          * @type DragDrop
  1075.          * @private
  1076.          * @static
  1077.          **/
  1078.         dragCurrent: null,
  1079.         /**
  1080.          * the DragDrop object(s) that are being hovered over
  1081.          * @property dragOvers
  1082.          * @type Array
  1083.          * @private
  1084.          * @static
  1085.          */
  1086.         dragOvers: {},
  1087.         /**
  1088.          * the X distance between the cursor and the object being dragged
  1089.          * @property deltaX
  1090.          * @type int
  1091.          * @private
  1092.          * @static
  1093.          */
  1094.         deltaX: 0,
  1095.         /**
  1096.          * the Y distance between the cursor and the object being dragged
  1097.          * @property deltaY
  1098.          * @type int
  1099.          * @private
  1100.          * @static
  1101.          */
  1102.         deltaY: 0,
  1103.         /**
  1104.          * Flag to determine if we should prevent the default behavior of the
  1105.          * events we define. By default this is true, but this can be set to
  1106.          * false if you need the default behavior (not recommended)
  1107.          * @property preventDefault
  1108.          * @type boolean
  1109.          * @static
  1110.          */
  1111.         preventDefault: true,
  1112.         /**
  1113.          * Flag to determine if we should stop the propagation of the events
  1114.          * we generate. This is true by default but you may want to set it to
  1115.          * false if the html element contains other features that require the
  1116.          * mouse click.
  1117.          * @property stopPropagation
  1118.          * @type boolean
  1119.          * @static
  1120.          */
  1121.         stopPropagation: true,
  1122.         /**
  1123.          * Internal flag that is set to true when drag and drop has been
  1124.          * intialized
  1125.          * @property initialized
  1126.          * @private
  1127.          * @static
  1128.          */
  1129.         initialized: false,
  1130.         /**
  1131.          * All drag and drop can be disabled.
  1132.          * @property locked
  1133.          * @private
  1134.          * @static
  1135.          */
  1136.         locked: false,
  1137.         /**
  1138.          * Called the first time an element is registered.
  1139.          * @method init
  1140.          * @private
  1141.          * @static
  1142.          */
  1143.         init: function() {
  1144.             this.initialized = true;
  1145.         },
  1146.         /**
  1147.          * In point mode, drag and drop interaction is defined by the
  1148.          * location of the cursor during the drag/drop
  1149.          * @property POINT
  1150.          * @type int
  1151.          * @static
  1152.          */
  1153.         POINT: 0,
  1154.         /**
  1155.          * In intersect mode, drag and drop interaction is defined by the
  1156.          * overlap of two or more drag and drop objects.
  1157.          * @property INTERSECT
  1158.          * @type int
  1159.          * @static
  1160.          */
  1161.         INTERSECT: 1,
  1162.         /**
  1163.          * The current drag and drop mode.  Default: POINT
  1164.          * @property mode
  1165.          * @type int
  1166.          * @static
  1167.          */
  1168.         mode: 0,
  1169.         /**
  1170.          * Runs method on all drag and drop objects
  1171.          * @method _execOnAll
  1172.          * @private
  1173.          * @static
  1174.          */
  1175.         _execOnAll: function(sMethod, args) {
  1176.             for (var i in this.ids) {
  1177.                 for (var j in this.ids[i]) {
  1178.                     var oDD = this.ids[i][j];
  1179.                     if (! this.isTypeOfDD(oDD)) {
  1180.                         continue;
  1181.                     }
  1182.                     oDD[sMethod].apply(oDD, args);
  1183.                 }
  1184.             }
  1185.         },
  1186.         /**
  1187.          * Drag and drop initialization.  Sets up the global event handlers
  1188.          * @method _onLoad
  1189.          * @private
  1190.          * @static
  1191.          */
  1192.         _onLoad: function() {
  1193.             this.init();
  1194.             Event.on(document, "mouseup",   this.handleMouseUp, this, true);
  1195.             Event.on(document, "mousemove", this.handleMouseMove, this, true);
  1196.             Event.on(window,   "unload",    this._onUnload, this, true);
  1197.             Event.on(window,   "resize",    this._onResize, this, true);
  1198.             // Event.on(window,   "mouseout",    this._test);
  1199.         },
  1200.         /**
  1201.          * Reset constraints on all drag and drop objs
  1202.          * @method _onResize
  1203.          * @private
  1204.          * @static
  1205.          */
  1206.         _onResize: function(e) {
  1207.             this._execOnAll("resetConstraints", []);
  1208.         },
  1209.         /**
  1210.          * Lock all drag and drop functionality
  1211.          * @method lock
  1212.          * @static
  1213.          */
  1214.         lock: function() { this.locked = true; },
  1215.         /**
  1216.          * Unlock all drag and drop functionality
  1217.          * @method unlock
  1218.          * @static
  1219.          */
  1220.         unlock: function() { this.locked = false; },
  1221.         /**
  1222.          * Is drag and drop locked?
  1223.          * @method isLocked
  1224.          * @return {boolean} True if drag and drop is locked, false otherwise.
  1225.          * @static
  1226.          */
  1227.         isLocked: function() { return this.locked; },
  1228.         /**
  1229.          * Location cache that is set for all drag drop objects when a drag is
  1230.          * initiated, cleared when the drag is finished.
  1231.          * @property locationCache
  1232.          * @private
  1233.          * @static
  1234.          */
  1235.         locationCache: {},
  1236.         /**
  1237.          * Set useCache to false if you want to force object the lookup of each
  1238.          * drag and drop linked element constantly during a drag.
  1239.          * @property useCache
  1240.          * @type boolean
  1241.          * @static
  1242.          */
  1243.         useCache: true,
  1244.         /**
  1245.          * The number of pixels that the mouse needs to move after the
  1246.          * mousedown before the drag is initiated.  Default=3;
  1247.          * @property clickPixelThresh
  1248.          * @type int
  1249.          * @static
  1250.          */
  1251.         clickPixelThresh: 3,
  1252.         /**
  1253.          * The number of milliseconds after the mousedown event to initiate the
  1254.          * drag if we don't get a mouseup event. Default=350
  1255.          * @property clickTimeThresh
  1256.          * @type int
  1257.          * @static
  1258.          */
  1259.         clickTimeThresh: 350,
  1260.         /**
  1261.          * Flag that indicates that either the drag pixel threshold or the
  1262.          * mousdown time threshold has been met
  1263.          * @property dragThreshMet
  1264.          * @type boolean
  1265.          * @private
  1266.          * @static
  1267.          */
  1268.         dragThreshMet: false,
  1269.         /**
  1270.          * Timeout used for the click time threshold
  1271.          * @property clickTimeout
  1272.          * @type Object
  1273.          * @private
  1274.          * @static
  1275.          */
  1276.         clickTimeout: null,
  1277.         /**
  1278.          * The X position of the mousedown event stored for later use when a
  1279.          * drag threshold is met.
  1280.          * @property startX
  1281.          * @type int
  1282.          * @private
  1283.          * @static
  1284.          */
  1285.         startX: 0,
  1286.         /**
  1287.          * The Y position of the mousedown event stored for later use when a
  1288.          * drag threshold is met.
  1289.          * @property startY
  1290.          * @type int
  1291.          * @private
  1292.          * @static
  1293.          */
  1294.         startY: 0,
  1295.         /**
  1296.          * Each DragDrop instance must be registered with the DragDropMgr.
  1297.          * This is executed in DragDrop.init()
  1298.          * @method regDragDrop
  1299.          * @param {DragDrop} oDD the DragDrop object to register
  1300.          * @param {String} sGroup the name of the group this element belongs to
  1301.          * @static
  1302.          */
  1303.         regDragDrop: function(oDD, sGroup) {
  1304.             if (!this.initialized) { this.init(); }
  1305.             if (!this.ids[sGroup]) {
  1306.                 this.ids[sGroup] = {};
  1307.             }
  1308.             this.ids[sGroup][oDD.id] = oDD;
  1309.         },
  1310.         /**
  1311.          * Removes the supplied dd instance from the supplied group. Executed
  1312.          * by DragDrop.removeFromGroup, so don't call this function directly.
  1313.          * @method removeDDFromGroup
  1314.          * @private
  1315.          * @static
  1316.          */
  1317.         removeDDFromGroup: function(oDD, sGroup) {
  1318.             if (!this.ids[sGroup]) {
  1319.                 this.ids[sGroup] = {};
  1320.             }
  1321.             var obj = this.ids[sGroup];
  1322.             if (obj && obj[oDD.id]) {
  1323.                 delete obj[oDD.id];
  1324.             }
  1325.         },
  1326.         /**
  1327.          * Unregisters a drag and drop item.  This is executed in
  1328.          * DragDrop.unreg, use that method instead of calling this directly.
  1329.          * @method _remove
  1330.          * @private
  1331.          * @static
  1332.          */
  1333.         _remove: function(oDD) {
  1334.             for (var g in oDD.groups) {
  1335.                 if (g && this.ids[g] && this.ids[g][oDD.id]) {
  1336.                     delete this.ids[g][oDD.id];
  1337.                 }
  1338.             }
  1339.             delete this.handleIds[oDD.id];
  1340.         },
  1341.         /**
  1342.          * Each DragDrop handle element must be registered.  This is done
  1343.          * automatically when executing DragDrop.setHandleElId()
  1344.          * @method regHandle
  1345.          * @param {String} sDDId the DragDrop id this element is a handle for
  1346.          * @param {String} sHandleId the id of the element that is the drag
  1347.          * handle
  1348.          * @static
  1349.          */
  1350.         regHandle: function(sDDId, sHandleId) {
  1351.             if (!this.handleIds[sDDId]) {
  1352.                 this.handleIds[sDDId] = {};
  1353.             }
  1354.             this.handleIds[sDDId][sHandleId] = sHandleId;
  1355.         },
  1356.         /**
  1357.          * Utility function to determine if a given element has been
  1358.          * registered as a drag drop item.
  1359.          * @method isDragDrop
  1360.          * @param {String} id the element id to check
  1361.          * @return {boolean} true if this element is a DragDrop item,
  1362.          * false otherwise
  1363.          * @static
  1364.          */
  1365.         isDragDrop: function(id) {
  1366.             return ( this.getDDById(id) ) ? true : false;
  1367.         },
  1368.         /**
  1369.          * Returns the drag and drop instances that are in all groups the
  1370.          * passed in instance belongs to.
  1371.          * @method getRelated
  1372.          * @param {DragDrop} p_oDD the obj to get related data for
  1373.          * @param {boolean} bTargetsOnly if true, only return targetable objs
  1374.          * @return {DragDrop[]} the related instances
  1375.          * @static
  1376.          */
  1377.         getRelated: function(p_oDD, bTargetsOnly) {
  1378.             var oDDs = [];
  1379.             for (var i in p_oDD.groups) {
  1380.                 for (var j in this.ids[i]) {
  1381.                     var dd = this.ids[i][j];
  1382.                     if (! this.isTypeOfDD(dd)) {
  1383.                         continue;
  1384.                     }
  1385.                     if (!bTargetsOnly || dd.isTarget) {
  1386.                         oDDs[oDDs.length] = dd;
  1387.                     }
  1388.                 }
  1389.             }
  1390.             return oDDs;
  1391.         },
  1392.         /**
  1393.          * Returns true if the specified dd target is a legal target for
  1394.          * the specifice drag obj
  1395.          * @method isLegalTarget
  1396.          * @param {DragDrop} the drag obj
  1397.          * @param {DragDrop} the target
  1398.          * @return {boolean} true if the target is a legal target for the
  1399.          * dd obj
  1400.          * @static
  1401.          */
  1402.         isLegalTarget: function (oDD, oTargetDD) {
  1403.             var targets = this.getRelated(oDD, true);
  1404.             for (var i=0, len=targets.length;i<len;++i) {
  1405.                 if (targets[i].id == oTargetDD.id) {
  1406.                     return true;
  1407.                 }
  1408.             }
  1409.             return false;
  1410.         },
  1411.         /**
  1412.          * My goal is to be able to transparently determine if an object is
  1413.          * typeof DragDrop, and the exact subclass of DragDrop.  typeof
  1414.          * returns "object", oDD.constructor.toString() always returns
  1415.          * "DragDrop" and not the name of the subclass.  So for now it just
  1416.          * evaluates a well-known variable in DragDrop.
  1417.          * @method isTypeOfDD
  1418.          * @param {Object} the object to evaluate
  1419.          * @return {boolean} true if typeof oDD = DragDrop
  1420.          * @static
  1421.          */
  1422.         isTypeOfDD: function (oDD) {
  1423.             return (oDD && oDD.__ygDragDrop);
  1424.         },
  1425.         /**
  1426.          * Utility function to determine if a given element has been
  1427.          * registered as a drag drop handle for the given Drag Drop object.
  1428.          * @method isHandle
  1429.          * @param {String} id the element id to check
  1430.          * @return {boolean} true if this element is a DragDrop handle, false
  1431.          * otherwise
  1432.          * @static
  1433.          */
  1434.         isHandle: function(sDDId, sHandleId) {
  1435.             return ( this.handleIds[sDDId] &&
  1436.                             this.handleIds[sDDId][sHandleId] );
  1437.         },
  1438.         /**
  1439.          * Returns the DragDrop instance for a given id
  1440.          * @method getDDById
  1441.          * @param {String} id the id of the DragDrop object
  1442.          * @return {DragDrop} the drag drop object, null if it is not found
  1443.          * @static
  1444.          */
  1445.         getDDById: function(id) {
  1446.             for (var i in this.ids) {
  1447.                 if (this.ids[i][id]) {
  1448.                     return this.ids[i][id];
  1449.                 }
  1450.             }
  1451.             return null;
  1452.         },
  1453.         /**
  1454.          * Fired after a registered DragDrop object gets the mousedown event.
  1455.          * Sets up the events required to track the object being dragged
  1456.          * @method handleMouseDown
  1457.          * @param {Event} e the event
  1458.          * @param oDD the DragDrop object being dragged
  1459.          * @private
  1460.          * @static
  1461.          */
  1462.         handleMouseDown: function(e, oDD) {
  1463.             if(Ext.QuickTips){
  1464.                 Ext.QuickTips.disable();
  1465.             }
  1466.             if(this.dragCurrent){
  1467.                 // the original browser mouseup wasn't handled (e.g. outside FF browser window)
  1468.                 // so clean up first to avoid breaking the next drag
  1469.                 this.handleMouseUp(e);
  1470.             }
  1471.             
  1472.             this.currentTarget = e.getTarget();
  1473.             this.dragCurrent = oDD;
  1474.             var el = oDD.getEl();
  1475.             // track start position
  1476.             this.startX = e.getPageX();
  1477.             this.startY = e.getPageY();
  1478.             this.deltaX = this.startX - el.offsetLeft;
  1479.             this.deltaY = this.startY - el.offsetTop;
  1480.             this.dragThreshMet = false;
  1481.             this.clickTimeout = setTimeout(
  1482.                     function() {
  1483.                         var DDM = Ext.dd.DDM;
  1484.                         DDM.startDrag(DDM.startX, DDM.startY);
  1485.                     },
  1486.                     this.clickTimeThresh );
  1487.         },
  1488.         /**
  1489.          * Fired when either the drag pixel threshol or the mousedown hold
  1490.          * time threshold has been met.
  1491.          * @method startDrag
  1492.          * @param x {int} the X position of the original mousedown
  1493.          * @param y {int} the Y position of the original mousedown
  1494.          * @static
  1495.          */
  1496.         startDrag: function(x, y) {
  1497.             clearTimeout(this.clickTimeout);
  1498.             if (this.dragCurrent) {
  1499.                 this.dragCurrent.b4StartDrag(x, y);
  1500.                 this.dragCurrent.startDrag(x, y);
  1501.             }
  1502.             this.dragThreshMet = true;
  1503.         },
  1504.         /**
  1505.          * Internal function to handle the mouseup event.  Will be invoked
  1506.          * from the context of the document.
  1507.          * @method handleMouseUp
  1508.          * @param {Event} e the event
  1509.          * @private
  1510.          * @static
  1511.          */
  1512.         handleMouseUp: function(e) {
  1513.             if(Ext.QuickTips){
  1514.                 Ext.QuickTips.enable();
  1515.             }
  1516.             if (! this.dragCurrent) {
  1517.                 return;
  1518.             }
  1519.             clearTimeout(this.clickTimeout);
  1520.             if (this.dragThreshMet) {
  1521.                 this.fireEvents(e, true);
  1522.             } else {
  1523.             }
  1524.             this.stopDrag(e);
  1525.             this.stopEvent(e);
  1526.         },
  1527.         /**
  1528.          * Utility to stop event propagation and event default, if these
  1529.          * features are turned on.
  1530.          * @method stopEvent
  1531.          * @param {Event} e the event as returned by this.getEvent()
  1532.          * @static
  1533.          */
  1534.         stopEvent: function(e){
  1535.             if(this.stopPropagation) {
  1536.                 e.stopPropagation();
  1537.             }
  1538.             if (this.preventDefault) {
  1539.                 e.preventDefault();
  1540.             }
  1541.         },
  1542.         /**
  1543.          * Internal function to clean up event handlers after the drag
  1544.          * operation is complete
  1545.          * @method stopDrag
  1546.          * @param {Event} e the event
  1547.          * @private
  1548.          * @static
  1549.          */
  1550.         stopDrag: function(e) {
  1551.             // Fire the drag end event for the item that was dragged
  1552.             if (this.dragCurrent) {
  1553.                 if (this.dragThreshMet) {
  1554.                     this.dragCurrent.b4EndDrag(e);
  1555.                     this.dragCurrent.endDrag(e);
  1556.                 }
  1557.                 this.dragCurrent.onMouseUp(e);
  1558.             }
  1559.             this.dragCurrent = null;
  1560.             this.dragOvers = {};
  1561.         },
  1562.         /**
  1563.          * Internal function to handle the mousemove event.  Will be invoked
  1564.          * from the context of the html element.
  1565.          *
  1566.          * @TODO figure out what we can do about mouse events lost when the
  1567.          * user drags objects beyond the window boundary.  Currently we can
  1568.          * detect this in internet explorer by verifying that the mouse is
  1569.          * down during the mousemove event.  Firefox doesn't give us the
  1570.          * button state on the mousemove event.
  1571.          * @method handleMouseMove
  1572.          * @param {Event} e the event
  1573.          * @private
  1574.          * @static
  1575.          */
  1576.         handleMouseMove: function(e) {
  1577.             if (! this.dragCurrent) {
  1578.                 return true;
  1579.             }
  1580.             // var button = e.which || e.button;
  1581.             // check for IE mouseup outside of page boundary
  1582.             if (Ext.isIE && (e.button !== 0 && e.button !== 1 && e.button !== 2)) {
  1583.                 this.stopEvent(e);
  1584.                 return this.handleMouseUp(e);
  1585.             }
  1586.             if (!this.dragThreshMet) {
  1587.                 var diffX = Math.abs(this.startX - e.getPageX());
  1588.                 var diffY = Math.abs(this.startY - e.getPageY());
  1589.                 if (diffX > this.clickPixelThresh ||
  1590.                             diffY > this.clickPixelThresh) {
  1591.                     this.startDrag(this.startX, this.startY);
  1592.                 }
  1593.             }
  1594.             if (this.dragThreshMet) {
  1595.                 this.dragCurrent.b4Drag(e);
  1596.                 this.dragCurrent.onDrag(e);
  1597.                 if(!this.dragCurrent.moveOnly){
  1598.                     this.fireEvents(e, false);
  1599.                 }
  1600.             }
  1601.             this.stopEvent(e);
  1602.             return true;
  1603.         },
  1604.         /**
  1605.          * Iterates over all of the DragDrop elements to find ones we are
  1606.          * hovering over or dropping on
  1607.          * @method fireEvents
  1608.          * @param {Event} e the event
  1609.          * @param {boolean} isDrop is this a drop op or a mouseover op?
  1610.          * @private
  1611.          * @static
  1612.          */
  1613.         fireEvents: function(e, isDrop) {
  1614.             var dc = this.dragCurrent;
  1615.             // If the user did the mouse up outside of the window, we could
  1616.             // get here even though we have ended the drag.
  1617.             if (!dc || dc.isLocked()) {
  1618.                 return;
  1619.             }
  1620.             var pt = e.getPoint();
  1621.             // cache the previous dragOver array
  1622.             var oldOvers = [];
  1623.             var outEvts   = [];
  1624.             var overEvts  = [];
  1625.             var dropEvts  = [];
  1626.             var enterEvts = [];
  1627.             // Check to see if the object(s) we were hovering over is no longer
  1628.             // being hovered over so we can fire the onDragOut event
  1629.             for (var i in this.dragOvers) {
  1630.                 var ddo = this.dragOvers[i];
  1631.                 if (! this.isTypeOfDD(ddo)) {
  1632.                     continue;
  1633.                 }
  1634.                 if (! this.isOverTarget(pt, ddo, this.mode)) {
  1635.                     outEvts.push( ddo );
  1636.                 }
  1637.                 oldOvers[i] = true;
  1638.                 delete this.dragOvers[i];
  1639.             }
  1640.             for (var sGroup in dc.groups) {
  1641.                 if ("string" != typeof sGroup) {
  1642.                     continue;
  1643.                 }
  1644.                 for (i in this.ids[sGroup]) {
  1645.                     var oDD = this.ids[sGroup][i];
  1646.                     if (! this.isTypeOfDD(oDD)) {
  1647.                         continue;
  1648.                     }
  1649.                     if (oDD.isTarget && !oDD.isLocked() && ((oDD != dc) || (dc.ignoreSelf === false))) {
  1650.                         if (this.isOverTarget(pt, oDD, this.mode)) {
  1651.                             // look for drop interactions
  1652.                             if (isDrop) {
  1653.                                 dropEvts.push( oDD );
  1654.                             // look for drag enter and drag over interactions
  1655.                             } else {
  1656.                                 // initial drag over: dragEnter fires
  1657.                                 if (!oldOvers[oDD.id]) {
  1658.                                     enterEvts.push( oDD );
  1659.                                 // subsequent drag overs: dragOver fires
  1660.                                 } else {
  1661.                                     overEvts.push( oDD );
  1662.                                 }
  1663.                                 this.dragOvers[oDD.id] = oDD;
  1664.                             }
  1665.                         }
  1666.                     }
  1667.                 }
  1668.             }
  1669.             if (this.mode) {
  1670.                 if (outEvts.length) {
  1671.                     dc.b4DragOut(e, outEvts);
  1672.                     dc.onDragOut(e, outEvts);
  1673.                 }
  1674.                 if (enterEvts.length) {
  1675.                     dc.onDragEnter(e, enterEvts);
  1676.                 }
  1677.                 if (overEvts.length) {
  1678.                     dc.b4DragOver(e, overEvts);
  1679.                     dc.onDragOver(e, overEvts);
  1680.                 }
  1681.                 if (dropEvts.length) {
  1682.                     dc.b4DragDrop(e, dropEvts);
  1683.                     dc.onDragDrop(e, dropEvts);
  1684.                 }
  1685.             } else {
  1686.                 // fire dragout events
  1687.                 var len = 0;
  1688.                 for (i=0, len=outEvts.length; i<len; ++i) {
  1689.                     dc.b4DragOut(e, outEvts[i].id);
  1690.                     dc.onDragOut(e, outEvts[i].id);
  1691.                 }
  1692.                 // fire enter events
  1693.                 for (i=0,len=enterEvts.length; i<len; ++i) {
  1694.                     // dc.b4DragEnter(e, oDD.id);
  1695.                     dc.onDragEnter(e, enterEvts[i].id);
  1696.                 }
  1697.                 // fire over events
  1698.                 for (i=0,len=overEvts.length; i<len; ++i) {
  1699.                     dc.b4DragOver(e, overEvts[i].id);
  1700.                     dc.onDragOver(e, overEvts[i].id);
  1701.                 }
  1702.                 // fire drop events
  1703.                 for (i=0, len=dropEvts.length; i<len; ++i) {
  1704.                     dc.b4DragDrop(e, dropEvts[i].id);
  1705.                     dc.onDragDrop(e, dropEvts[i].id);
  1706.                 }
  1707.             }
  1708.             // notify about a drop that did not find a target
  1709.             if (isDrop && !dropEvts.length) {
  1710.                 dc.onInvalidDrop(e);
  1711.             }
  1712.         },
  1713.         /**
  1714.          * Helper function for getting the best match from the list of drag
  1715.          * and drop objects returned by the drag and drop events when we are
  1716.          * in INTERSECT mode.  It returns either the first object that the
  1717.          * cursor is over, or the object that has the greatest overlap with
  1718.          * the dragged element.
  1719.          * @method getBestMatch
  1720.          * @param  {DragDrop[]} dds The array of drag and drop objects
  1721.          * targeted
  1722.          * @return {DragDrop}       The best single match
  1723.          * @static
  1724.          */
  1725.         getBestMatch: function(dds) {
  1726.             var winner = null;
  1727.             // Return null if the input is not what we expect
  1728.             //if (!dds || !dds.length || dds.length == 0) {
  1729.                // winner = null;
  1730.             // If there is only one item, it wins
  1731.             //} else if (dds.length == 1) {
  1732.             var len = dds.length;
  1733.             if (len == 1) {
  1734.                 winner = dds[0];
  1735.             } else {
  1736.                 // Loop through the targeted items
  1737.                 for (var i=0; i<len; ++i) {
  1738.                     var dd = dds[i];
  1739.                     // If the cursor is over the object, it wins.  If the
  1740.                     // cursor is over multiple matches, the first one we come
  1741.                     // to wins.
  1742.                     if (dd.cursorIsOver) {
  1743.                         winner = dd;
  1744.                         break;
  1745.                     // Otherwise the object with the most overlap wins
  1746.                     } else {
  1747.                         if (!winner ||
  1748.                             winner.overlap.getArea() < dd.overlap.getArea()) {
  1749.                             winner = dd;
  1750.                         }
  1751.                     }
  1752.                 }
  1753.             }
  1754.             return winner;
  1755.         },
  1756.         /**
  1757.          * Refreshes the cache of the top-left and bottom-right points of the
  1758.          * drag and drop objects in the specified group(s).  This is in the
  1759.          * format that is stored in the drag and drop instance, so typical
  1760.          * usage is:
  1761.          * <code>
  1762.          * Ext.dd.DragDropMgr.refreshCache(ddinstance.groups);
  1763.          * </code>
  1764.          * Alternatively:
  1765.          * <code>
  1766.          * Ext.dd.DragDropMgr.refreshCache({group1:true, group2:true});
  1767.          * </code>
  1768.          * @TODO this really should be an indexed array.  Alternatively this
  1769.          * method could accept both.
  1770.          * @method refreshCache
  1771.          * @param {Object} groups an associative array of groups to refresh
  1772.          * @static
  1773.          */
  1774.         refreshCache: function(groups) {
  1775.             for (var sGroup in groups) {
  1776.                 if ("string" != typeof sGroup) {
  1777.                     continue;
  1778.                 }
  1779.                 for (var i in this.ids[sGroup]) {
  1780.                     var oDD = this.ids[sGroup][i];
  1781.                     if (this.isTypeOfDD(oDD)) {
  1782.                     // if (this.isTypeOfDD(oDD) && oDD.isTarget) {
  1783.                         var loc = this.getLocation(oDD);
  1784.                         if (loc) {
  1785.                             this.locationCache[oDD.id] = loc;
  1786.                         } else {
  1787.                             delete this.locationCache[oDD.id];
  1788.                             // this will unregister the drag and drop object if
  1789.                             // the element is not in a usable state
  1790.                             // oDD.unreg();
  1791.                         }
  1792.                     }
  1793.                 }
  1794.             }
  1795.         },
  1796.         /**
  1797.          * This checks to make sure an element exists and is in the DOM.  The
  1798.          * main purpose is to handle cases where innerHTML is used to remove
  1799.          * drag and drop objects from the DOM.  IE provides an 'unspecified
  1800.          * error' when trying to access the offsetParent of such an element
  1801.          * @method verifyEl
  1802.          * @param {HTMLElement} el the element to check
  1803.          * @return {boolean} true if the element looks usable
  1804.          * @static
  1805.          */
  1806.         verifyEl: function(el) {
  1807.             if (el) {
  1808.                 var parent;
  1809.                 if(Ext.isIE){
  1810.                     try{
  1811.                         parent = el.offsetParent;
  1812.                     }catch(e){}
  1813.                 }else{
  1814.                     parent = el.offsetParent;
  1815.                 }
  1816.                 if (parent) {
  1817.                     return true;
  1818.                 }
  1819.             }
  1820.             return false;
  1821.         },
  1822.         /**
  1823.          * Returns a Region object containing the drag and drop element's position
  1824.          * and size, including the padding configured for it
  1825.          * @method getLocation
  1826.          * @param {DragDrop} oDD the drag and drop object to get the
  1827.          *                       location for
  1828.          * @return {Ext.lib.Region} a Region object representing the total area
  1829.          *                             the element occupies, including any padding
  1830.          *                             the instance is configured for.
  1831.          * @static
  1832.          */
  1833.         getLocation: function(oDD) {
  1834.             if (! this.isTypeOfDD(oDD)) {
  1835.                 return null;
  1836.             }
  1837.             var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;
  1838.             try {
  1839.                 pos= Ext.lib.Dom.getXY(el);
  1840.             } catch (e) { }
  1841.             if (!pos) {
  1842.                 return null;
  1843.             }
  1844.             x1 = pos[0];
  1845.             x2 = x1 + el.offsetWidth;
  1846.             y1 = pos[1];
  1847.             y2 = y1 + el.offsetHeight;
  1848.             t = y1 - oDD.padding[0];
  1849.             r = x2 + oDD.padding[1];
  1850.             b = y2 + oDD.padding[2];
  1851.             l = x1 - oDD.padding[3];
  1852.             return new Ext.lib.Region( t, r, b, l );
  1853.         },
  1854.         /**
  1855.          * Checks the cursor location to see if it over the target
  1856.          * @method isOverTarget
  1857.          * @param {Ext.lib.Point} pt The point to evaluate
  1858.          * @param {DragDrop} oTarget the DragDrop object we are inspecting
  1859.          * @return {boolean} true if the mouse is over the target
  1860.          * @private
  1861.          * @static
  1862.          */
  1863.         isOverTarget: function(pt, oTarget, intersect) {
  1864.             // use cache if available
  1865.             var loc = this.locationCache[oTarget.id];
  1866.             if (!loc || !this.useCache) {
  1867.                 loc = this.getLocation(oTarget);
  1868.                 this.locationCache[oTarget.id] = loc;
  1869.             }
  1870.             if (!loc) {
  1871.                 return false;
  1872.             }
  1873.             oTarget.cursorIsOver = loc.contains( pt );
  1874.             // DragDrop is using this as a sanity check for the initial mousedown
  1875.             // in this case we are done.  In POINT mode, if the drag obj has no
  1876.             // contraints, we are also done. Otherwise we need to evaluate the
  1877.             // location of the target as related to the actual location of the
  1878.             // dragged element.
  1879.             var dc = this.dragCurrent;
  1880.             if (!dc || !dc.getTargetCoord ||
  1881.                     (!intersect && !dc.constrainX && !dc.constrainY)) {
  1882.                 return oTarget.cursorIsOver;
  1883.             }
  1884.             oTarget.overlap = null;
  1885.             // Get the current location of the drag element, this is the
  1886.             // location of the mouse event less the delta that represents
  1887.             // where the original mousedown happened on the element.  We
  1888.             // need to consider constraints and ticks as well.
  1889.             var pos = dc.getTargetCoord(pt.x, pt.y);
  1890.             var el = dc.getDragEl();
  1891.             var curRegion = new Ext.lib.Region( pos.y,
  1892.                                                    pos.x + el.offsetWidth,
  1893.                                                    pos.y + el.offsetHeight,
  1894.                                                    pos.x );
  1895.             var overlap = curRegion.intersect(loc);
  1896.             if (overlap) {
  1897.                 oTarget.overlap = overlap;
  1898.                 return (intersect) ? true : oTarget.cursorIsOver;
  1899.             } else {
  1900.                 return false;
  1901.             }
  1902.         },
  1903.         /**
  1904.          * unload event handler
  1905.          * @method _onUnload
  1906.          * @private
  1907.          * @static
  1908.          */
  1909.         _onUnload: function(e, me) {
  1910.             Ext.dd.DragDropMgr.unregAll();
  1911.         },
  1912.         /**
  1913.          * Cleans up the drag and drop events and objects.
  1914.          * @method unregAll
  1915.          * @private
  1916.          * @static
  1917.          */
  1918.         unregAll: function() {
  1919.             if (this.dragCurrent) {
  1920.                 this.stopDrag();
  1921.                 this.dragCurrent = null;
  1922.             }
  1923.             this._execOnAll("unreg", []);
  1924.             for (var i in this.elementCache) {
  1925.                 delete this.elementCache[i];
  1926.             }
  1927.             this.elementCache = {};
  1928.             this.ids = {};
  1929.         },
  1930.         /**
  1931.          * A cache of DOM elements
  1932.          * @property elementCache
  1933.          * @private
  1934.          * @static
  1935.          */
  1936.         elementCache: {},
  1937.         /**
  1938.          * Get the wrapper for the DOM element specified
  1939.          * @method getElWrapper
  1940.          * @param {String} id the id of the element to get
  1941.          * @return {Ext.dd.DDM.ElementWrapper} the wrapped element
  1942.          * @private
  1943.          * @deprecated This wrapper isn't that useful
  1944.          * @static
  1945.          */
  1946.         getElWrapper: function(id) {
  1947.             var oWrapper = this.elementCache[id];
  1948.             if (!oWrapper || !oWrapper.el) {
  1949.                 oWrapper = this.elementCache[id] =
  1950.                     new this.ElementWrapper(Ext.getDom(id));
  1951.             }
  1952.             return oWrapper;
  1953.         },
  1954.         /**
  1955.          * Returns the actual DOM element
  1956.          * @method getElement
  1957.          * @param {String} id the id of the elment to get
  1958.          * @return {Object} The element
  1959.          * @deprecated use Ext.lib.Ext.getDom instead
  1960.          * @static
  1961.          */
  1962.         getElement: function(id) {
  1963.             return Ext.getDom(id);
  1964.         },
  1965.         /**
  1966.          * Returns the style property for the DOM element (i.e.,
  1967.          * document.getElById(id).style)
  1968.          * @method getCss
  1969.          * @param {String} id the id of the elment to get
  1970.          * @return {Object} The style property of the element
  1971.          * @deprecated use Ext.lib.Dom instead
  1972.          * @static
  1973.          */
  1974.         getCss: function(id) {
  1975.             var el = Ext.getDom(id);
  1976.             return (el) ? el.style : null;
  1977.         },
  1978.         /**
  1979.          * Inner class for cached elements
  1980.          * @class DragDropMgr.ElementWrapper
  1981.          * @for DragDropMgr
  1982.          * @private
  1983.          * @deprecated
  1984.          */
  1985.         ElementWrapper: function(el) {
  1986.                 /**
  1987.                  * The element
  1988.                  * @property el
  1989.                  */
  1990.                 this.el = el || null;
  1991.                 /**
  1992.                  * The element id
  1993.                  * @property id
  1994.                  */
  1995.                 this.id = this.el && el.id;
  1996.                 /**
  1997.                  * A reference to the style property
  1998.                  * @property css
  1999.                  */
  2000.                 this.css = this.el && el.style;
  2001.             },
  2002.         /**
  2003.          * Returns the X position of an html element
  2004.          * @method getPosX
  2005.          * @param el the element for which to get the position
  2006.          * @return {int} the X coordinate
  2007.          * @for DragDropMgr
  2008.          * @deprecated use Ext.lib.Dom.getX instead
  2009.          * @static
  2010.          */
  2011.         getPosX: function(el) {
  2012.             return Ext.lib.Dom.getX(el);
  2013.         },
  2014.         /**
  2015.          * Returns the Y position of an html element
  2016.          * @method getPosY
  2017.          * @param el the element for which to get the position
  2018.          * @return {int} the Y coordinate
  2019.          * @deprecated use Ext.lib.Dom.getY instead
  2020.          * @static
  2021.          */
  2022.         getPosY: function(el) {
  2023.             return Ext.lib.Dom.getY(el);
  2024.         },
  2025.         /**
  2026.          * Swap two nodes.  In IE, we use the native method, for others we
  2027.          * emulate the IE behavior
  2028.          * @method swapNode
  2029.          * @param n1 the first node to swap
  2030.          * @param n2 the other node to swap
  2031.          * @static
  2032.          */
  2033.         swapNode: function(n1, n2) {
  2034.             if (n1.swapNode) {
  2035.                 n1.swapNode(n2);
  2036.             } else {
  2037.                 var p = n2.parentNode;
  2038.                 var s = n2.nextSibling;
  2039.                 if (s == n1) {
  2040.                     p.insertBefore(n1, n2);
  2041.                 } else if (n2 == n1.nextSibling) {
  2042.                     p.insertBefore(n2, n1);
  2043.                 } else {
  2044.                     n1.parentNode.replaceChild(n2, n1);
  2045.                     p.insertBefore(n1, s);
  2046.                 }
  2047.             }
  2048.         },
  2049.         /**
  2050.          * Returns the current scroll position
  2051.          * @method getScroll
  2052.          * @private
  2053.          * @static
  2054.          */
  2055.         getScroll: function () {
  2056.             var t, l, dde=document.documentElement, db=document.body;
  2057.             if (dde && (dde.scrollTop || dde.scrollLeft)) {
  2058.                 t = dde.scrollTop;
  2059.                 l = dde.scrollLeft;
  2060.             } else if (db) {
  2061.                 t = db.scrollTop;
  2062.                 l = db.scrollLeft;
  2063.             } else {
  2064.             }
  2065.             return { top: t, left: l };
  2066.         },
  2067.         /**
  2068.          * Returns the specified element style property
  2069.          * @method getStyle
  2070.          * @param {HTMLElement} el          the element
  2071.          * @param {string}      styleProp   the style property
  2072.          * @return {string} The value of the style property
  2073.          * @deprecated use Ext.lib.Dom.getStyle
  2074.          * @static
  2075.          */
  2076.         getStyle: function(el, styleProp) {
  2077.             return Ext.fly(el).getStyle(styleProp);
  2078.         },
  2079.         /**
  2080.          * Gets the scrollTop
  2081.          * @method getScrollTop
  2082.          * @return {int} the document's scrollTop
  2083.          * @static
  2084.          */
  2085.         getScrollTop: function () { return this.getScroll().top; },
  2086.         /**
  2087.          * Gets the scrollLeft
  2088.          * @method getScrollLeft
  2089.          * @return {int} the document's scrollTop
  2090.          * @static
  2091.          */
  2092.         getScrollLeft: function () { return this.getScroll().left; },
  2093.         /**
  2094.          * Sets the x/y position of an element to the location of the
  2095.          * target element.
  2096.          * @method moveToEl
  2097.          * @param {HTMLElement} moveEl      The element to move
  2098.          * @param {HTMLElement} targetEl    The position reference element
  2099.          * @static
  2100.          */
  2101.         moveToEl: function (moveEl, targetEl) {
  2102.             var aCoord = Ext.lib.Dom.getXY(targetEl);
  2103.             Ext.lib.Dom.setXY(moveEl, aCoord);
  2104.         },
  2105.         /**
  2106.          * Numeric array sort function
  2107.          * @method numericSort
  2108.          * @static
  2109.          */
  2110.         numericSort: function(a, b) { return (a - b); },
  2111.         /**
  2112.          * Internal counter
  2113.          * @property _timeoutCount
  2114.          * @private
  2115.          * @static
  2116.          */
  2117.         _timeoutCount: 0,
  2118.         /**
  2119.          * Trying to make the load order less important.  Without this we get
  2120.          * an error if this file is loaded before the Event Utility.
  2121.          * @method _addListeners
  2122.          * @private
  2123.          * @static
  2124.          */
  2125.         _addListeners: function() {
  2126.             var DDM = Ext.dd.DDM;
  2127.             if ( Ext.lib.Event && document ) {
  2128.                 DDM._onLoad();
  2129.             } else {
  2130.                 if (DDM._timeoutCount > 2000) {
  2131.                 } else {
  2132.                     setTimeout(DDM._addListeners, 10);
  2133.                     if (document && document.body) {
  2134.                         DDM._timeoutCount += 1;
  2135.                     }
  2136.                 }
  2137.             }
  2138.         },
  2139.         /**
  2140.          * Recursively searches the immediate parent and all child nodes for
  2141.          * the handle element in order to determine wheter or not it was
  2142.          * clicked.
  2143.          * @method handleWasClicked
  2144.          * @param node the html element to inspect
  2145.          * @static
  2146.          */
  2147.         handleWasClicked: function(node, id) {
  2148.             if (this.isHandle(id, node.id)) {
  2149.                 return true;
  2150.             } else {
  2151.                 // check to see if this is a text node child of the one we want
  2152.                 var p = node.parentNode;
  2153.                 while (p) {
  2154.                     if (this.isHandle(id, p.id)) {
  2155.                         return true;
  2156.                     } else {
  2157.                         p = p.parentNode;
  2158.                     }
  2159.                 }
  2160.             }
  2161.             return false;
  2162.         }
  2163.     };
  2164. }();
  2165. // shorter alias, save a few bytes
  2166. Ext.dd.DDM = Ext.dd.DragDropMgr;
  2167. Ext.dd.DDM._addListeners();
  2168. }
  2169. /**
  2170.  * @class Ext.dd.DD
  2171.  * A DragDrop implementation where the linked element follows the
  2172.  * mouse cursor during a drag.
  2173.  * @extends Ext.dd.DragDrop
  2174.  * @constructor
  2175.  * @param {String} id the id of the linked element
  2176.  * @param {String} sGroup the group of related DragDrop items
  2177.  * @param {object} config an object containing configurable attributes
  2178.  *                Valid properties for DD:
  2179.  *                    scroll
  2180.  */
  2181. Ext.dd.DD = function(id, sGroup, config) {
  2182.     if (id) {
  2183.         this.init(id, sGroup, config);
  2184.     }
  2185. };
  2186. Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {
  2187.     /**
  2188.      * When set to true, the utility automatically tries to scroll the browser
  2189.      * window when a drag and drop element is dragged near the viewport boundary.
  2190.      * Defaults to true.
  2191.      * @property scroll
  2192.      * @type boolean
  2193.      */
  2194.     scroll: true,
  2195.     /**
  2196.      * Sets the pointer offset to the distance between the linked element's top
  2197.      * left corner and the location the element was clicked
  2198.      * @method autoOffset
  2199.      * @param {int} iPageX the X coordinate of the click
  2200.      * @param {int} iPageY the Y coordinate of the click
  2201.      */
  2202.     autoOffset: function(iPageX, iPageY) {
  2203.         var x = iPageX - this.startPageX;
  2204.         var y = iPageY - this.startPageY;
  2205.         this.setDelta(x, y);
  2206.     },
  2207.     /**
  2208.      * Sets the pointer offset.  You can call this directly to force the
  2209.      * offset to be in a particular location (e.g., pass in 0,0 to set it
  2210.      * to the center of the object)
  2211.      * @method setDelta
  2212.      * @param {int} iDeltaX the distance from the left
  2213.      * @param {int} iDeltaY the distance from the top
  2214.      */
  2215.     setDelta: function(iDeltaX, iDeltaY) {
  2216.         this.deltaX = iDeltaX;
  2217.         this.deltaY = iDeltaY;
  2218.     },
  2219.     /**
  2220.      * Sets the drag element to the location of the mousedown or click event,
  2221.      * maintaining the cursor location relative to the location on the element
  2222.      * that was clicked.  Override this if you want to place the element in a
  2223.      * location other than where the cursor is.
  2224.      * @method setDragElPos
  2225.      * @param {int} iPageX the X coordinate of the mousedown or drag event
  2226.      * @param {int} iPageY the Y coordinate of the mousedown or drag event
  2227.      */
  2228.     setDragElPos: function(iPageX, iPageY) {
  2229.         // the first time we do this, we are going to check to make sure
  2230.         // the element has css positioning
  2231.         var el = this.getDragEl();
  2232.         this.alignElWithMouse(el, iPageX, iPageY);
  2233.     },
  2234.     /**
  2235.      * Sets the element to the location of the mousedown or click event,
  2236.      * maintaining the cursor location relative to the location on the element
  2237.      * that was clicked.  Override this if you want to place the element in a
  2238.      * location other than where the cursor is.
  2239.      * @method alignElWithMouse
  2240.      * @param {HTMLElement} el the element to move
  2241.      * @param {int} iPageX the X coordinate of the mousedown or drag event
  2242.      * @param {int} iPageY the Y coordinate of the mousedown or drag event
  2243.      */
  2244.     alignElWithMouse: function(el, iPageX, iPageY) {
  2245.         var oCoord = this.getTargetCoord(iPageX, iPageY);
  2246.         var fly = el.dom ? el : Ext.fly(el, '_dd');
  2247.         if (!this.deltaSetXY) {
  2248.             var aCoord = [oCoord.x, oCoord.y];
  2249.             fly.setXY(aCoord);
  2250.             var newLeft = fly.getLeft(true);
  2251.             var newTop  = fly.getTop(true);
  2252.             this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
  2253.         } else {
  2254.             fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);
  2255.         }
  2256.         this.cachePosition(oCoord.x, oCoord.y);
  2257.         this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
  2258.         return oCoord;
  2259.     },
  2260.     /**
  2261.      * Saves the most recent position so that we can reset the constraints and
  2262.      * tick marks on-demand.  We need to know this so that we can calculate the
  2263.      * number of pixels the element is offset from its original position.
  2264.      * @method cachePosition
  2265.      * @param iPageX the current x position (optional, this just makes it so we
  2266.      * don't have to look it up again)
  2267.      * @param iPageY the current y position (optional, this just makes it so we
  2268.      * don't have to look it up again)
  2269.      */
  2270.     cachePosition: function(iPageX, iPageY) {
  2271.         if (iPageX) {
  2272.             this.lastPageX = iPageX;
  2273.             this.lastPageY = iPageY;
  2274.         } else {
  2275.             var aCoord = Ext.lib.Dom.getXY(this.getEl());
  2276.             this.lastPageX = aCoord[0];
  2277.             this.lastPageY = aCoord[1];
  2278.         }
  2279.     },
  2280.     /**
  2281.      * Auto-scroll the window if the dragged object has been moved beyond the
  2282.      * visible window boundary.
  2283.      * @method autoScroll
  2284.      * @param {int} x the drag element's x position
  2285.      * @param {int} y the drag element's y position
  2286.      * @param {int} h the height of the drag element
  2287.      * @param {int} w the width of the drag element
  2288.      * @private
  2289.      */
  2290.     autoScroll: function(x, y, h, w) {
  2291.         if (this.scroll) {
  2292.             // The client height
  2293.             var clientH = Ext.lib.Dom.getViewHeight();
  2294.             // The client width
  2295.             var clientW = Ext.lib.Dom.getViewWidth();
  2296.             // The amt scrolled down
  2297.             var st = this.DDM.getScrollTop();
  2298.             // The amt scrolled right
  2299.             var sl = this.DDM.getScrollLeft();
  2300.             // Location of the bottom of the element
  2301.             var bot = h + y;
  2302.             // Location of the right of the element
  2303.             var right = w + x;
  2304.             // The distance from the cursor to the bottom of the visible area,
  2305.             // adjusted so that we don't scroll if the cursor is beyond the
  2306.             // element drag constraints
  2307.             var toBot = (clientH + st - y - this.deltaY);
  2308.             // The distance from the cursor to the right of the visible area
  2309.             var toRight = (clientW + sl - x - this.deltaX);
  2310.             // How close to the edge the cursor must be before we scroll
  2311.             // var thresh = (document.all) ? 100 : 40;
  2312.             var thresh = 40;
  2313.             // How many pixels to scroll per autoscroll op.  This helps to reduce
  2314.             // clunky scrolling. IE is more sensitive about this ... it needs this
  2315.             // value to be higher.
  2316.             var scrAmt = (document.all) ? 80 : 30;
  2317.             // Scroll down if we are near the bottom of the visible page and the
  2318.             // obj extends below the crease
  2319.             if ( bot > clientH && toBot < thresh ) {
  2320.                 window.scrollTo(sl, st + scrAmt);
  2321.             }
  2322.             // Scroll up if the window is scrolled down and the top of the object
  2323.             // goes above the top border
  2324.             if ( y < st && st > 0 && y - st < thresh ) {
  2325.                 window.scrollTo(sl, st - scrAmt);
  2326.             }
  2327.             // Scroll right if the obj is beyond the right border and the cursor is
  2328.             // near the border.
  2329.             if ( right > clientW && toRight < thresh ) {
  2330.                 window.scrollTo(sl + scrAmt, st);
  2331.             }
  2332.             // Scroll left if the window has been scrolled to the right and the obj
  2333.             // extends past the left border
  2334.             if ( x < sl && sl > 0 && x - sl < thresh ) {
  2335.                 window.scrollTo(sl - scrAmt, st);
  2336.             }
  2337.         }
  2338.     },
  2339.     /**
  2340.      * Finds the location the element should be placed if we want to move
  2341.      * it to where the mouse location less the click offset would place us.
  2342.      * @method getTargetCoord
  2343.      * @param {int} iPageX the X coordinate of the click
  2344.      * @param {int} iPageY the Y coordinate of the click
  2345.      * @return an object that contains the coordinates (Object.x and Object.y)
  2346.      * @private
  2347.      */
  2348.     getTargetCoord: function(iPageX, iPageY) {
  2349.         var x = iPageX - this.deltaX;
  2350.         var y = iPageY - this.deltaY;
  2351.         if (this.constrainX) {
  2352.             if (x < this.minX) { x = this.minX; }
  2353.             if (x > this.maxX) { x = this.maxX; }
  2354.         }
  2355.         if (this.constrainY) {
  2356.             if (y < this.minY) { y = this.minY; }
  2357.             if (y > this.maxY) { y = this.maxY; }
  2358.         }
  2359.         x = this.getTick(x, this.xTicks);
  2360.         y = this.getTick(y, this.yTicks);
  2361.         return {x:x, y:y};
  2362.     },
  2363.     /**
  2364.      * Sets up config options specific to this class. Overrides
  2365.      * Ext.dd.DragDrop, but all versions of this method through the
  2366.      * inheritance chain are called
  2367.      */
  2368.     applyConfig: function() {
  2369.         Ext.dd.DD.superclass.applyConfig.call(this);
  2370.         this.scroll = (this.config.scroll !== false);
  2371.     },
  2372.     /**
  2373.      * Event that fires prior to the onMouseDown event.  Overrides
  2374.      * Ext.dd.DragDrop.
  2375.      */
  2376.     b4MouseDown: function(e) {
  2377.         // this.resetConstraints();
  2378.         this.autoOffset(e.getPageX(),
  2379.                             e.getPageY());
  2380.     },
  2381.     /**
  2382.      * Event that fires prior to the onDrag event.  Overrides
  2383.      * Ext.dd.DragDrop.
  2384.      */
  2385.     b4Drag: function(e) {
  2386.         this.setDragElPos(e.getPageX(),
  2387.                             e.getPageY());
  2388.     },
  2389.     toString: function() {
  2390.         return ("DD " + this.id);
  2391.     }
  2392.     //////////////////////////////////////////////////////////////////////////
  2393.     // Debugging ygDragDrop events that can be overridden
  2394.     //////////////////////////////////////////////////////////////////////////
  2395.     /*
  2396.     startDrag: function(x, y) {
  2397.     },
  2398.     onDrag: function(e) {
  2399.     },
  2400.     onDragEnter: function(e, id) {
  2401.     },
  2402.     onDragOver: function(e, id) {
  2403.     },
  2404.     onDragOut: function(e, id) {
  2405.     },
  2406.     onDragDrop: function(e, id) {
  2407.     },
  2408.     endDrag: function(e) {
  2409.     }
  2410.     */
  2411. });
  2412. /**
  2413.  * @class Ext.dd.DDProxy
  2414.  * A DragDrop implementation that inserts an empty, bordered div into
  2415.  * the document that follows the cursor during drag operations.  At the time of
  2416.  * the click, the frame div is resized to the dimensions of the linked html
  2417.  * element, and moved to the exact location of the linked element.
  2418.  *
  2419.  * References to the "frame" element refer to the single proxy element that
  2420.  * was created to be dragged in place of all DDProxy elements on the
  2421.  * page.
  2422.  *
  2423.  * @extends Ext.dd.DD
  2424.  * @constructor
  2425.  * @param {String} id the id of the linked html element
  2426.  * @param {String} sGroup the group of related DragDrop objects
  2427.  * @param {object} config an object containing configurable attributes
  2428.  *                Valid properties for DDProxy in addition to those in DragDrop:
  2429.  *                   resizeFrame, centerFrame, dragElId
  2430.  */
  2431. Ext.dd.DDProxy = function(id, sGroup, config) {
  2432.     if (id) {
  2433.         this.init(id, sGroup, config);
  2434.         this.initFrame();
  2435.     }
  2436. };
  2437. /**
  2438.  * The default drag frame div id
  2439.  * @property Ext.dd.DDProxy.dragElId
  2440.  * @type String
  2441.  * @static
  2442.  */
  2443. Ext.dd.DDProxy.dragElId = "ygddfdiv";
  2444. Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, {
  2445.     /**
  2446.      * By default we resize the drag frame to be the same size as the element
  2447.      * we want to drag (this is to get the frame effect).  We can turn it off
  2448.      * if we want a different behavior.
  2449.      * @property resizeFrame
  2450.      * @type boolean
  2451.      */
  2452.     resizeFrame: true,
  2453.     /**
  2454.      * By default the frame is positioned exactly where the drag element is, so
  2455.      * we use the cursor offset provided by Ext.dd.DD.  Another option that works only if
  2456.      * you do not have constraints on the obj is to have the drag frame centered
  2457.      * around the cursor.  Set centerFrame to true for this effect.
  2458.      * @property centerFrame
  2459.      * @type boolean
  2460.      */
  2461.     centerFrame: false,
  2462.     /**
  2463.      * Creates the proxy element if it does not yet exist
  2464.      * @method createFrame
  2465.      */
  2466.     createFrame: function() {
  2467.         var self = this;
  2468.         var body = document.body;
  2469.         if (!body || !body.firstChild) {
  2470.             setTimeout( function() { self.createFrame(); }, 50 );
  2471.             return;
  2472.         }
  2473.         var div = this.getDragEl();
  2474.         if (!div) {
  2475.             div    = document.createElement("div");
  2476.             div.id = this.dragElId;
  2477.             var s  = div.style;
  2478.             s.position   = "absolute";
  2479.             s.visibility = "hidden";
  2480.             s.cursor     = "move";
  2481.             s.border     = "2px solid #aaa";
  2482.             s.zIndex     = 999;
  2483.             // appendChild can blow up IE if invoked prior to the window load event
  2484.             // while rendering a table.  It is possible there are other scenarios
  2485.             // that would cause this to happen as well.
  2486.             body.insertBefore(div, body.firstChild);
  2487.         }
  2488.     },
  2489.     /**
  2490.      * Initialization for the drag frame element.  Must be called in the
  2491.      * constructor of all subclasses
  2492.      * @method initFrame
  2493.      */
  2494.     initFrame: function() {
  2495.         this.createFrame();
  2496.     },
  2497.     applyConfig: function() {
  2498.         Ext.dd.DDProxy.superclass.applyConfig.call(this);
  2499.         this.resizeFrame = (this.config.resizeFrame !== false);
  2500.         this.centerFrame = (this.config.centerFrame);
  2501.         this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);
  2502.     },
  2503.     /**
  2504.      * Resizes the drag frame to the dimensions of the clicked object, positions
  2505.      * it over the object, and finally displays it
  2506.      * @method showFrame
  2507.      * @param {int} iPageX X click position
  2508.      * @param {int} iPageY Y click position
  2509.      * @private
  2510.      */
  2511.     showFrame: function(iPageX, iPageY) {
  2512.         var el = this.getEl();
  2513.         var dragEl = this.getDragEl();
  2514.         var s = dragEl.style;
  2515.         this._resizeProxy();
  2516.         if (this.centerFrame) {
  2517.             this.setDelta( Math.round(parseInt(s.width,  10)/2),
  2518.                            Math.round(parseInt(s.height, 10)/2) );
  2519.         }
  2520.         this.setDragElPos(iPageX, iPageY);
  2521.         Ext.fly(dragEl).show();
  2522.     },
  2523.     /**
  2524.      * The proxy is automatically resized to the dimensions of the linked
  2525.      * element when a drag is initiated, unless resizeFrame is set to false
  2526.      * @method _resizeProxy
  2527.      * @private
  2528.      */
  2529.     _resizeProxy: function() {
  2530.         if (this.resizeFrame) {
  2531.             var el = this.getEl();
  2532.             Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
  2533.         }
  2534.     },
  2535.     // overrides Ext.dd.DragDrop
  2536.     b4MouseDown: function(e) {
  2537.         var x = e.getPageX();
  2538.         var y = e.getPageY();
  2539.         this.autoOffset(x, y);
  2540.         this.setDragElPos(x, y);
  2541.     },
  2542.     // overrides Ext.dd.DragDrop
  2543.     b4StartDrag: function(x, y) {
  2544.         // show the drag frame
  2545.         this.showFrame(x, y);
  2546.     },
  2547.     // overrides Ext.dd.DragDrop
  2548.     b4EndDrag: function(e) {
  2549.         Ext.fly(this.getDragEl()).hide();
  2550.     },
  2551.     // overrides Ext.dd.DragDrop
  2552.     // By default we try to move the element to the last location of the frame.
  2553.     // This is so that the default behavior mirrors that of Ext.dd.DD.
  2554.     endDrag: function(e) {
  2555.         var lel = this.getEl();
  2556.         var del = this.getDragEl();
  2557.         // Show the drag frame briefly so we can get its position
  2558.         del.style.visibility = "";
  2559.         this.beforeMove();
  2560.         // Hide the linked element before the move to get around a Safari
  2561.         // rendering bug.
  2562.         lel.style.visibility = "hidden";
  2563.         Ext.dd.DDM.moveToEl(lel, del);
  2564.         del.style.visibility = "hidden";
  2565.         lel.style.visibility = "";
  2566.         this.afterDrag();
  2567.     },
  2568.     beforeMove : function(){
  2569.     },
  2570.     afterDrag : function(){
  2571.     },
  2572.     toString: function() {
  2573.         return ("DDProxy " + this.id);
  2574.     }
  2575. });
  2576. /**
  2577.  * @class Ext.dd.DDTarget
  2578.  * A DragDrop implementation that does not move, but can be a drop
  2579.  * target.  You would get the same result by simply omitting implementation
  2580.  * for the event callbacks, but this way we reduce the processing cost of the
  2581.  * event listener and the callbacks.
  2582.  * @extends Ext.dd.DragDrop
  2583.  * @constructor
  2584.  * @param {String} id the id of the element that is a drop target
  2585.  * @param {String} sGroup the group of related DragDrop objects
  2586.  * @param {object} config an object containing configurable attributes
  2587.  *                 Valid properties for DDTarget in addition to those in
  2588.  *                 DragDrop:
  2589.  *                    none
  2590.  */
  2591. Ext.dd.DDTarget = function(id, sGroup, config) {
  2592.     if (id) {
  2593.         this.initTarget(id, sGroup, config);
  2594.     }
  2595. };
  2596. // Ext.dd.DDTarget.prototype = new Ext.dd.DragDrop();
  2597. Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {
  2598.     /**
  2599.      * @hide
  2600.      * Overridden and disabled. A DDTarget does not support being dragged.
  2601.      * @method
  2602.      */
  2603.     getDragEl: Ext.emptyFn,
  2604.     /**
  2605.      * @hide
  2606.      * Overridden and disabled. A DDTarget does not support being dragged.
  2607.      * @method
  2608.      */
  2609.     isValidHandleChild: Ext.emptyFn,
  2610.     /**
  2611.      * @hide
  2612.      * Overridden and disabled. A DDTarget does not support being dragged.
  2613.      * @method
  2614.      */
  2615.     startDrag: Ext.emptyFn,
  2616.     /**
  2617.      * @hide
  2618.      * Overridden and disabled. A DDTarget does not support being dragged.
  2619.      * @method
  2620.      */
  2621.     endDrag: Ext.emptyFn,
  2622.     /**
  2623.      * @hide
  2624.      * Overridden and disabled. A DDTarget does not support being dragged.
  2625.      * @method
  2626.      */
  2627.     onDrag: Ext.emptyFn,
  2628.     /**
  2629.      * @hide
  2630.      * Overridden and disabled. A DDTarget does not support being dragged.
  2631.      * @method
  2632.      */
  2633.     onDragDrop: Ext.emptyFn,
  2634.     /**
  2635.      * @hide
  2636.      * Overridden and disabled. A DDTarget does not support being dragged.
  2637.      * @method
  2638.      */
  2639.     onDragEnter: Ext.emptyFn,
  2640.     /**
  2641.      * @hide
  2642.      * Overridden and disabled. A DDTarget does not support being dragged.
  2643.      * @method
  2644.      */
  2645.     onDragOut: Ext.emptyFn,
  2646.     /**
  2647.      * @hide
  2648.      * Overridden and disabled. A DDTarget does not support being dragged.
  2649.      * @method
  2650.      */
  2651.     onDragOver: Ext.emptyFn,
  2652.     /**
  2653.      * @hide
  2654.      * Overridden and disabled. A DDTarget does not support being dragged.
  2655.      * @method
  2656.      */
  2657.     onInvalidDrop: Ext.emptyFn,
  2658.     /**
  2659.      * @hide
  2660.      * Overridden and disabled. A DDTarget does not support being dragged.
  2661.      * @method
  2662.      */
  2663.     onMouseDown: Ext.emptyFn,
  2664.     /**
  2665.      * @hide
  2666.      * Overridden and disabled. A DDTarget does not support being dragged.
  2667.      * @method
  2668.      */
  2669.     onMouseUp: Ext.emptyFn,
  2670.     /**
  2671.      * @hide
  2672.      * Overridden and disabled. A DDTarget does not support being dragged.
  2673.      * @method
  2674.      */
  2675.     setXConstraint: Ext.emptyFn,
  2676.     /**
  2677.      * @hide
  2678.      * Overridden and disabled. A DDTarget does not support being dragged.
  2679.      * @method
  2680.      */
  2681.     setYConstraint: Ext.emptyFn,
  2682.     /**
  2683.      * @hide
  2684.      * Overridden and disabled. A DDTarget does not support being dragged.
  2685.      * @method
  2686.      */
  2687.     resetConstraints: Ext.emptyFn,
  2688.     /**
  2689.      * @hide
  2690.      * Overridden and disabled. A DDTarget does not support being dragged.
  2691.      * @method
  2692.      */
  2693.     clearConstraints: Ext.emptyFn,
  2694.     /**
  2695.      * @hide
  2696.      * Overridden and disabled. A DDTarget does not support being dragged.
  2697.      * @method
  2698.      */
  2699.     clearTicks: Ext.emptyFn,
  2700.     /**
  2701.      * @hide
  2702.      * Overridden and disabled. A DDTarget does not support being dragged.
  2703.      * @method
  2704.      */
  2705.     setInitPosition: Ext.emptyFn,
  2706.     /**
  2707.      * @hide
  2708.      * Overridden and disabled. A DDTarget does not support being dragged.
  2709.      * @method
  2710.      */
  2711.     setDragElId: Ext.emptyFn,
  2712.     /**
  2713.      * @hide
  2714.      * Overridden and disabled. A DDTarget does not support being dragged.
  2715.      * @method
  2716.      */
  2717.     setHandleElId: Ext.emptyFn,
  2718.     /**
  2719.      * @hide
  2720.      * Overridden and disabled. A DDTarget does not support being dragged.
  2721.      * @method
  2722.      */
  2723.     setOuterHandleElId: Ext.emptyFn,
  2724.     /**
  2725.      * @hide
  2726.      * Overridden and disabled. A DDTarget does not support being dragged.
  2727.      * @method
  2728.      */
  2729.     addInvalidHandleClass: Ext.emptyFn,
  2730.     /**
  2731.      * @hide
  2732.      * Overridden and disabled. A DDTarget does not support being dragged.
  2733.      * @method
  2734.      */
  2735.     addInvalidHandleId: Ext.emptyFn,
  2736.     /**
  2737.      * @hide
  2738.      * Overridden and disabled. A DDTarget does not support being dragged.
  2739.      * @method
  2740.      */
  2741.     addInvalidHandleType: Ext.emptyFn,
  2742.     /**
  2743.      * @hide
  2744.      * Overridden and disabled. A DDTarget does not support being dragged.
  2745.      * @method
  2746.      */
  2747.     removeInvalidHandleClass: Ext.emptyFn,
  2748.     /**
  2749.      * @hide
  2750.      * Overridden and disabled. A DDTarget does not support being dragged.
  2751.      * @method
  2752.      */
  2753.     removeInvalidHandleId: Ext.emptyFn,
  2754.     /**
  2755.      * @hide
  2756.      * Overridden and disabled. A DDTarget does not support being dragged.
  2757.      * @method
  2758.      */
  2759.     removeInvalidHandleType: Ext.emptyFn,
  2760.     toString: function() {
  2761.         return ("DDTarget " + this.id);
  2762.     }
  2763. });