+++ /dev/null
-/*\r
- * Ext JS Library 2.2.1\r
- * Copyright(c) 2006-2009, Ext JS, LLC.\r
- * licensing@extjs.com\r
- * \r
- * http://extjs.com/license\r
- */\r
-\r
-/*\r
- * These classes are derivatives of the similarly named classes in the YUI Library.\r
- * The original license:\r
- * Copyright (c) 2006, Yahoo! Inc. All rights reserved.\r
- * Code licensed under the BSD License:\r
- * http://developer.yahoo.net/yui/license.txt\r
- */\r
-\r
-(function() {\r
-\r
-var Event=Ext.EventManager;\r
-var Dom=Ext.lib.Dom;\r
-\r
-/**\r
- * @class Ext.dd.DragDrop\r
- * Defines the interface and base operation of items that that can be\r
- * dragged or can be drop targets. It was designed to be extended, overriding\r
- * the event handlers for startDrag, onDrag, onDragOver and onDragOut.\r
- * Up to three html elements can be associated with a DragDrop instance:\r
- * <ul>\r
- * <li>linked element: the element that is passed into the constructor.\r
- * This is the element which defines the boundaries for interaction with\r
- * other DragDrop objects.</li>\r
- * <li>handle element(s): The drag operation only occurs if the element that\r
- * was clicked matches a handle element. By default this is the linked\r
- * element, but there are times that you will want only a portion of the\r
- * linked element to initiate the drag operation, and the setHandleElId()\r
- * method provides a way to define this.</li>\r
- * <li>drag element: this represents the element that would be moved along\r
- * with the cursor during a drag operation. By default, this is the linked\r
- * element itself as in {@link Ext.dd.DD}. setDragElId() lets you define\r
- * a separate element that would be moved, as in {@link Ext.dd.DDProxy}.\r
- * </li>\r
- * </ul>\r
- * This class should not be instantiated until the onload event to ensure that\r
- * the associated elements are available.\r
- * The following would define a DragDrop obj that would interact with any\r
- * other DragDrop obj in the "group1" group:\r
- * <pre>\r
- * dd = new Ext.dd.DragDrop("div1", "group1");\r
- * </pre>\r
- * Since none of the event handlers have been implemented, nothing would\r
- * actually happen if you were to run the code above. Normally you would\r
- * override this class or one of the default implementations, but you can\r
- * also override the methods you want on an instance of the class...\r
- * <pre>\r
- * dd.onDragDrop = function(e, id) {\r
- * alert("dd was dropped on " + id);\r
- * }\r
- * </pre>\r
- * @constructor\r
- * @param {String} id of the element that is linked to this instance\r
- * @param {String} sGroup the group of related DragDrop objects\r
- * @param {object} config an object containing configurable attributes\r
- * Valid properties for DragDrop:\r
- * padding, isTarget, maintainOffset, primaryButtonOnly\r
- */\r
-Ext.dd.DragDrop = function(id, sGroup, config) {\r
- if(id) {\r
- this.init(id, sGroup, config);\r
- }\r
-};\r
-\r
-Ext.dd.DragDrop.prototype = {\r
-\r
- /**\r
- * The id of the element associated with this object. This is what we\r
- * refer to as the "linked element" because the size and position of\r
- * this element is used to determine when the drag and drop objects have\r
- * interacted.\r
- * @property id\r
- * @type String\r
- */\r
- id: null,\r
-\r
- /**\r
- * Configuration attributes passed into the constructor\r
- * @property config\r
- * @type object\r
- */\r
- config: null,\r
-\r
- /**\r
- * The id of the element that will be dragged. By default this is same\r
- * as the linked element , but could be changed to another element. Ex:\r
- * Ext.dd.DDProxy\r
- * @property dragElId\r
- * @type String\r
- * @private\r
- */\r
- dragElId: null,\r
-\r
- /**\r
- * The ID of the element that initiates the drag operation. By default\r
- * this is the linked element, but could be changed to be a child of this\r
- * element. This lets us do things like only starting the drag when the\r
- * header element within the linked html element is clicked.\r
- * @property handleElId\r
- * @type String\r
- * @private\r
- */\r
- handleElId: null,\r
-\r
- /**\r
- * An object who's property names identify HTML tags to be considered invalid as drag handles.\r
- * A non-null property value identifies the tag as invalid. Defaults to the \r
- * following value which prevents drag operations from being initiated by <a> elements:<pre><code>\r
-{\r
- A: "A"\r
-}</code></pre>\r
- * @property invalidHandleTypes\r
- * @type Object\r
- */\r
- invalidHandleTypes: null,\r
-\r
- /**\r
- * An object who's property names identify the IDs of elements to be considered invalid as drag handles.\r
- * A non-null property value identifies the ID as invalid. For example, to prevent\r
- * dragging from being initiated on element ID "foo", use:<pre><code>\r
-{\r
- foo: true\r
-}</code></pre>\r
- * @property invalidHandleIds\r
- * @type Object\r
- */\r
- invalidHandleIds: null,\r
-\r
- /**\r
- * An Array of CSS class names for elements to be considered in valid as drag handles.\r
- * @property invalidHandleClasses\r
- * @type Array\r
- */\r
- invalidHandleClasses: null,\r
-\r
- /**\r
- * The linked element's absolute X position at the time the drag was\r
- * started\r
- * @property startPageX\r
- * @type int\r
- * @private\r
- */\r
- startPageX: 0,\r
-\r
- /**\r
- * The linked element's absolute X position at the time the drag was\r
- * started\r
- * @property startPageY\r
- * @type int\r
- * @private\r
- */\r
- startPageY: 0,\r
-\r
- /**\r
- * The group defines a logical collection of DragDrop objects that are\r
- * related. Instances only get events when interacting with other\r
- * DragDrop object in the same group. This lets us define multiple\r
- * groups using a single DragDrop subclass if we want.\r
- * @property groups\r
- * @type object An object in the format {'group1':true, 'group2':true}\r
- */\r
- groups: null,\r
-\r
- /**\r
- * Individual drag/drop instances can be locked. This will prevent\r
- * onmousedown start drag.\r
- * @property locked\r
- * @type boolean\r
- * @private\r
- */\r
- locked: false,\r
-\r
- /**\r
- * Lock this instance\r
- * @method lock\r
- */\r
- lock: function() { this.locked = true; },\r
-\r
- /**\r
- * When set to true, other DD objects in cooperating DDGroups do not receive\r
- * notification events when this DD object is dragged over them. Defaults to false.\r
- * @property moveOnly\r
- * @type boolean\r
- */\r
- moveOnly: false,\r
-\r
- /**\r
- * Unlock this instace\r
- * @method unlock\r
- */\r
- unlock: function() { this.locked = false; },\r
-\r
- /**\r
- * By default, all instances can be a drop target. This can be disabled by\r
- * setting isTarget to false.\r
- * @property isTarget\r
- * @type boolean\r
- */\r
- isTarget: true,\r
-\r
- /**\r
- * The padding configured for this drag and drop object for calculating\r
- * the drop zone intersection with this object.\r
- * @property padding\r
- * @type int[] An array containing the 4 padding values: [top, right, bottom, left]\r
- */\r
- padding: null,\r
-\r
- /**\r
- * Cached reference to the linked element\r
- * @property _domRef\r
- * @private\r
- */\r
- _domRef: null,\r
-\r
- /**\r
- * Internal typeof flag\r
- * @property __ygDragDrop\r
- * @private\r
- */\r
- __ygDragDrop: true,\r
-\r
- /**\r
- * Set to true when horizontal contraints are applied\r
- * @property constrainX\r
- * @type boolean\r
- * @private\r
- */\r
- constrainX: false,\r
-\r
- /**\r
- * Set to true when vertical contraints are applied\r
- * @property constrainY\r
- * @type boolean\r
- * @private\r
- */\r
- constrainY: false,\r
-\r
- /**\r
- * The left constraint\r
- * @property minX\r
- * @type int\r
- * @private\r
- */\r
- minX: 0,\r
-\r
- /**\r
- * The right constraint\r
- * @property maxX\r
- * @type int\r
- * @private\r
- */\r
- maxX: 0,\r
-\r
- /**\r
- * The up constraint\r
- * @property minY\r
- * @type int\r
- * @type int\r
- * @private\r
- */\r
- minY: 0,\r
-\r
- /**\r
- * The down constraint\r
- * @property maxY\r
- * @type int\r
- * @private\r
- */\r
- maxY: 0,\r
-\r
- /**\r
- * Maintain offsets when we resetconstraints. Set to true when you want\r
- * the position of the element relative to its parent to stay the same\r
- * when the page changes\r
- *\r
- * @property maintainOffset\r
- * @type boolean\r
- */\r
- maintainOffset: false,\r
-\r
- /**\r
- * Array of pixel locations the element will snap to if we specified a\r
- * horizontal graduation/interval. This array is generated automatically\r
- * when you define a tick interval.\r
- * @property xTicks\r
- * @type int[]\r
- */\r
- xTicks: null,\r
-\r
- /**\r
- * Array of pixel locations the element will snap to if we specified a\r
- * vertical graduation/interval. This array is generated automatically\r
- * when you define a tick interval.\r
- * @property yTicks\r
- * @type int[]\r
- */\r
- yTicks: null,\r
-\r
- /**\r
- * By default the drag and drop instance will only respond to the primary\r
- * button click (left button for a right-handed mouse). Set to true to\r
- * allow drag and drop to start with any mouse click that is propogated\r
- * by the browser\r
- * @property primaryButtonOnly\r
- * @type boolean\r
- */\r
- primaryButtonOnly: true,\r
-\r
- /**\r
- * The availabe property is false until the linked dom element is accessible.\r
- * @property available\r
- * @type boolean\r
- */\r
- available: false,\r
-\r
- /**\r
- * By default, drags can only be initiated if the mousedown occurs in the\r
- * region the linked element is. This is done in part to work around a\r
- * bug in some browsers that mis-report the mousedown if the previous\r
- * mouseup happened outside of the window. This property is set to true\r
- * if outer handles are defined.\r
- *\r
- * @property hasOuterHandles\r
- * @type boolean\r
- * @default false\r
- */\r
- hasOuterHandles: false,\r
-\r
- /**\r
- * Code that executes immediately before the startDrag event\r
- * @method b4StartDrag\r
- * @private\r
- */\r
- b4StartDrag: function(x, y) { },\r
-\r
- /**\r
- * Abstract method called after a drag/drop object is clicked\r
- * and the drag or mousedown time thresholds have beeen met.\r
- * @method startDrag\r
- * @param {int} X click location\r
- * @param {int} Y click location\r
- */\r
- startDrag: function(x, y) { /* override this */ },\r
-\r
- /**\r
- * Code that executes immediately before the onDrag event\r
- * @method b4Drag\r
- * @private\r
- */\r
- b4Drag: function(e) { },\r
-\r
- /**\r
- * Abstract method called during the onMouseMove event while dragging an\r
- * object.\r
- * @method onDrag\r
- * @param {Event} e the mousemove event\r
- */\r
- onDrag: function(e) { /* override this */ },\r
-\r
- /**\r
- * Abstract method called when this element fist begins hovering over\r
- * another DragDrop obj\r
- * @method onDragEnter\r
- * @param {Event} e the mousemove event\r
- * @param {String|DragDrop[]} id In POINT mode, the element\r
- * id this is hovering over. In INTERSECT mode, an array of one or more\r
- * dragdrop items being hovered over.\r
- */\r
- onDragEnter: function(e, id) { /* override this */ },\r
-\r
- /**\r
- * Code that executes immediately before the onDragOver event\r
- * @method b4DragOver\r
- * @private\r
- */\r
- b4DragOver: function(e) { },\r
-\r
- /**\r
- * Abstract method called when this element is hovering over another\r
- * DragDrop obj\r
- * @method onDragOver\r
- * @param {Event} e the mousemove event\r
- * @param {String|DragDrop[]} id In POINT mode, the element\r
- * id this is hovering over. In INTERSECT mode, an array of dd items\r
- * being hovered over.\r
- */\r
- onDragOver: function(e, id) { /* override this */ },\r
-\r
- /**\r
- * Code that executes immediately before the onDragOut event\r
- * @method b4DragOut\r
- * @private\r
- */\r
- b4DragOut: function(e) { },\r
-\r
- /**\r
- * Abstract method called when we are no longer hovering over an element\r
- * @method onDragOut\r
- * @param {Event} e the mousemove event\r
- * @param {String|DragDrop[]} id In POINT mode, the element\r
- * id this was hovering over. In INTERSECT mode, an array of dd items\r
- * that the mouse is no longer over.\r
- */\r
- onDragOut: function(e, id) { /* override this */ },\r
-\r
- /**\r
- * Code that executes immediately before the onDragDrop event\r
- * @method b4DragDrop\r
- * @private\r
- */\r
- b4DragDrop: function(e) { },\r
-\r
- /**\r
- * Abstract method called when this item is dropped on another DragDrop\r
- * obj\r
- * @method onDragDrop\r
- * @param {Event} e the mouseup event\r
- * @param {String|DragDrop[]} id In POINT mode, the element\r
- * id this was dropped on. In INTERSECT mode, an array of dd items this\r
- * was dropped on.\r
- */\r
- onDragDrop: function(e, id) { /* override this */ },\r
-\r
- /**\r
- * Abstract method called when this item is dropped on an area with no\r
- * drop target\r
- * @method onInvalidDrop\r
- * @param {Event} e the mouseup event\r
- */\r
- onInvalidDrop: function(e) { /* override this */ },\r
-\r
- /**\r
- * Code that executes immediately before the endDrag event\r
- * @method b4EndDrag\r
- * @private\r
- */\r
- b4EndDrag: function(e) { },\r
-\r
- /**\r
- * Fired when we are done dragging the object\r
- * @method endDrag\r
- * @param {Event} e the mouseup event\r
- */\r
- endDrag: function(e) { /* override this */ },\r
-\r
- /**\r
- * Code executed immediately before the onMouseDown event\r
- * @method b4MouseDown\r
- * @param {Event} e the mousedown event\r
- * @private\r
- */\r
- b4MouseDown: function(e) { },\r
-\r
- /**\r
- * Event handler that fires when a drag/drop obj gets a mousedown\r
- * @method onMouseDown\r
- * @param {Event} e the mousedown event\r
- */\r
- onMouseDown: function(e) { /* override this */ },\r
-\r
- /**\r
- * Event handler that fires when a drag/drop obj gets a mouseup\r
- * @method onMouseUp\r
- * @param {Event} e the mouseup event\r
- */\r
- onMouseUp: function(e) { /* override this */ },\r
-\r
- /**\r
- * Override the onAvailable method to do what is needed after the initial\r
- * position was determined.\r
- * @method onAvailable\r
- */\r
- onAvailable: function () {\r
- },\r
-\r
- /**\r
- * Provides default constraint padding to "constrainTo" elements (defaults to {left: 0, right:0, top:0, bottom:0}).\r
- * @type Object\r
- */\r
- defaultPadding : {left:0, right:0, top:0, bottom:0},\r
-\r
- /**\r
- * Initializes the drag drop object's constraints to restrict movement to a certain element.\r
- *\r
- * Usage:\r
- <pre><code>\r
- var dd = new Ext.dd.DDProxy("dragDiv1", "proxytest",\r
- { dragElId: "existingProxyDiv" });\r
- dd.startDrag = function(){\r
- this.constrainTo("parent-id");\r
- };\r
- </code></pre>\r
- * Or you can initalize it using the {@link Ext.Element} object:\r
- <pre><code>\r
- Ext.get("dragDiv1").initDDProxy("proxytest", {dragElId: "existingProxyDiv"}, {\r
- startDrag : function(){\r
- this.constrainTo("parent-id");\r
- }\r
- });\r
- </code></pre>\r
- * @param {Mixed} constrainTo The element to constrain to.\r
- * @param {Object/Number} pad (optional) Pad provides a way to specify "padding" of the constraints,\r
- * and can be either a number for symmetrical padding (4 would be equal to {left:4, right:4, top:4, bottom:4}) or\r
- * an object containing the sides to pad. For example: {right:10, bottom:10}\r
- * @param {Boolean} inContent (optional) Constrain the draggable in the content box of the element (inside padding and borders)\r
- */\r
- constrainTo : function(constrainTo, pad, inContent){\r
- if(typeof pad == "number"){\r
- pad = {left: pad, right:pad, top:pad, bottom:pad};\r
- }\r
- pad = pad || this.defaultPadding;\r
- var b = Ext.get(this.getEl()).getBox();\r
- var ce = Ext.get(constrainTo);\r
- var s = ce.getScroll();\r
- var c, cd = ce.dom;\r
- if(cd == document.body){\r
- c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};\r
- }else{\r
- var xy = ce.getXY();\r
- c = {x : xy[0]+s.left, y: xy[1]+s.top, width: cd.clientWidth, height: cd.clientHeight};\r
- }\r
-\r
-\r
- var topSpace = b.y - c.y;\r
- var leftSpace = b.x - c.x;\r
-\r
- this.resetConstraints();\r
- this.setXConstraint(leftSpace - (pad.left||0), // left\r
- c.width - leftSpace - b.width - (pad.right||0), //right\r
- this.xTickSize\r
- );\r
- this.setYConstraint(topSpace - (pad.top||0), //top\r
- c.height - topSpace - b.height - (pad.bottom||0), //bottom\r
- this.yTickSize\r
- );\r
- },\r
-\r
- /**\r
- * Returns a reference to the linked element\r
- * @method getEl\r
- * @return {HTMLElement} the html element\r
- */\r
- getEl: function() {\r
- if (!this._domRef) {\r
- this._domRef = Ext.getDom(this.id);\r
- }\r
-\r
- return this._domRef;\r
- },\r
-\r
- /**\r
- * Returns a reference to the actual element to drag. By default this is\r
- * the same as the html element, but it can be assigned to another\r
- * element. An example of this can be found in Ext.dd.DDProxy\r
- * @method getDragEl\r
- * @return {HTMLElement} the html element\r
- */\r
- getDragEl: function() {\r
- return Ext.getDom(this.dragElId);\r
- },\r
-\r
- /**\r
- * Sets up the DragDrop object. Must be called in the constructor of any\r
- * Ext.dd.DragDrop subclass\r
- * @method init\r
- * @param id the id of the linked element\r
- * @param {String} sGroup the group of related items\r
- * @param {object} config configuration attributes\r
- */\r
- init: function(id, sGroup, config) {\r
- this.initTarget(id, sGroup, config);\r
- Event.on(this.id, "mousedown", this.handleMouseDown, this);\r
- // Event.on(this.id, "selectstart", Event.preventDefault);\r
- },\r
-\r
- /**\r
- * Initializes Targeting functionality only... the object does not\r
- * get a mousedown handler.\r
- * @method initTarget\r
- * @param id the id of the linked element\r
- * @param {String} sGroup the group of related items\r
- * @param {object} config configuration attributes\r
- */\r
- initTarget: function(id, sGroup, config) {\r
-\r
- // configuration attributes\r
- this.config = config || {};\r
-\r
- // create a local reference to the drag and drop manager\r
- this.DDM = Ext.dd.DDM;\r
- // initialize the groups array\r
- this.groups = {};\r
-\r
- // assume that we have an element reference instead of an id if the\r
- // parameter is not a string\r
- if (typeof id !== "string") {\r
- id = Ext.id(id);\r
- }\r
-\r
- // set the id\r
- this.id = id;\r
-\r
- // add to an interaction group\r
- this.addToGroup((sGroup) ? sGroup : "default");\r
-\r
- // We don't want to register this as the handle with the manager\r
- // so we just set the id rather than calling the setter.\r
- this.handleElId = id;\r
-\r
- // the linked element is the element that gets dragged by default\r
- this.setDragElId(id);\r
-\r
- // by default, clicked anchors will not start drag operations.\r
- this.invalidHandleTypes = { A: "A" };\r
- this.invalidHandleIds = {};\r
- this.invalidHandleClasses = [];\r
-\r
- this.applyConfig();\r
-\r
- this.handleOnAvailable();\r
- },\r
-\r
- /**\r
- * Applies the configuration parameters that were passed into the constructor.\r
- * This is supposed to happen at each level through the inheritance chain. So\r
- * a DDProxy implentation will execute apply config on DDProxy, DD, and\r
- * DragDrop in order to get all of the parameters that are available in\r
- * each object.\r
- * @method applyConfig\r
- */\r
- applyConfig: function() {\r
-\r
- // configurable properties:\r
- // padding, isTarget, maintainOffset, primaryButtonOnly\r
- this.padding = this.config.padding || [0, 0, 0, 0];\r
- this.isTarget = (this.config.isTarget !== false);\r
- this.maintainOffset = (this.config.maintainOffset);\r
- this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);\r
-\r
- },\r
-\r
- /**\r
- * Executed when the linked element is available\r
- * @method handleOnAvailable\r
- * @private\r
- */\r
- handleOnAvailable: function() {\r
- this.available = true;\r
- this.resetConstraints();\r
- this.onAvailable();\r
- },\r
-\r
- /**\r
- * Configures the padding for the target zone in px. Effectively expands\r
- * (or reduces) the virtual object size for targeting calculations.\r
- * Supports css-style shorthand; if only one parameter is passed, all sides\r
- * will have that padding, and if only two are passed, the top and bottom\r
- * will have the first param, the left and right the second.\r
- * @method setPadding\r
- * @param {int} iTop Top pad\r
- * @param {int} iRight Right pad\r
- * @param {int} iBot Bot pad\r
- * @param {int} iLeft Left pad\r
- */\r
- setPadding: function(iTop, iRight, iBot, iLeft) {\r
- // this.padding = [iLeft, iRight, iTop, iBot];\r
- if (!iRight && 0 !== iRight) {\r
- this.padding = [iTop, iTop, iTop, iTop];\r
- } else if (!iBot && 0 !== iBot) {\r
- this.padding = [iTop, iRight, iTop, iRight];\r
- } else {\r
- this.padding = [iTop, iRight, iBot, iLeft];\r
- }\r
- },\r
-\r
- /**\r
- * Stores the initial placement of the linked element.\r
- * @method setInitialPosition\r
- * @param {int} diffX the X offset, default 0\r
- * @param {int} diffY the Y offset, default 0\r
- */\r
- setInitPosition: function(diffX, diffY) {\r
- var el = this.getEl();\r
-\r
- if (!this.DDM.verifyEl(el)) {\r
- return;\r
- }\r
-\r
- var dx = diffX || 0;\r
- var dy = diffY || 0;\r
-\r
- var p = Dom.getXY( el );\r
-\r
- this.initPageX = p[0] - dx;\r
- this.initPageY = p[1] - dy;\r
-\r
- this.lastPageX = p[0];\r
- this.lastPageY = p[1];\r
-\r
-\r
- this.setStartPosition(p);\r
- },\r
-\r
- /**\r
- * Sets the start position of the element. This is set when the obj\r
- * is initialized, the reset when a drag is started.\r
- * @method setStartPosition\r
- * @param pos current position (from previous lookup)\r
- * @private\r
- */\r
- setStartPosition: function(pos) {\r
- var p = pos || Dom.getXY( this.getEl() );\r
- this.deltaSetXY = null;\r
-\r
- this.startPageX = p[0];\r
- this.startPageY = p[1];\r
- },\r
-\r
- /**\r
- * Add this instance to a group of related drag/drop objects. All\r
- * instances belong to at least one group, and can belong to as many\r
- * groups as needed.\r
- * @method addToGroup\r
- * @param sGroup {string} the name of the group\r
- */\r
- addToGroup: function(sGroup) {\r
- this.groups[sGroup] = true;\r
- this.DDM.regDragDrop(this, sGroup);\r
- },\r
-\r
- /**\r
- * Remove's this instance from the supplied interaction group\r
- * @method removeFromGroup\r
- * @param {string} sGroup The group to drop\r
- */\r
- removeFromGroup: function(sGroup) {\r
- if (this.groups[sGroup]) {\r
- delete this.groups[sGroup];\r
- }\r
-\r
- this.DDM.removeDDFromGroup(this, sGroup);\r
- },\r
-\r
- /**\r
- * Allows you to specify that an element other than the linked element\r
- * will be moved with the cursor during a drag\r
- * @method setDragElId\r
- * @param id {string} the id of the element that will be used to initiate the drag\r
- */\r
- setDragElId: function(id) {\r
- this.dragElId = id;\r
- },\r
-\r
- /**\r
- * Allows you to specify a child of the linked element that should be\r
- * used to initiate the drag operation. An example of this would be if\r
- * you have a content div with text and links. Clicking anywhere in the\r
- * content area would normally start the drag operation. Use this method\r
- * to specify that an element inside of the content div is the element\r
- * that starts the drag operation.\r
- * @method setHandleElId\r
- * @param id {string} the id of the element that will be used to\r
- * initiate the drag.\r
- */\r
- setHandleElId: function(id) {\r
- if (typeof id !== "string") {\r
- id = Ext.id(id);\r
- }\r
- this.handleElId = id;\r
- this.DDM.regHandle(this.id, id);\r
- },\r
-\r
- /**\r
- * Allows you to set an element outside of the linked element as a drag\r
- * handle\r
- * @method setOuterHandleElId\r
- * @param id the id of the element that will be used to initiate the drag\r
- */\r
- setOuterHandleElId: function(id) {\r
- if (typeof id !== "string") {\r
- id = Ext.id(id);\r
- }\r
- Event.on(id, "mousedown",\r
- this.handleMouseDown, this);\r
- this.setHandleElId(id);\r
-\r
- this.hasOuterHandles = true;\r
- },\r
-\r
- /**\r
- * Remove all drag and drop hooks for this element\r
- * @method unreg\r
- */\r
- unreg: function() {\r
- Event.un(this.id, "mousedown",\r
- this.handleMouseDown);\r
- this._domRef = null;\r
- this.DDM._remove(this);\r
- },\r
-\r
- destroy : function(){\r
- this.unreg();\r
- },\r
-\r
- /**\r
- * Returns true if this instance is locked, or the drag drop mgr is locked\r
- * (meaning that all drag/drop is disabled on the page.)\r
- * @method isLocked\r
- * @return {boolean} true if this obj or all drag/drop is locked, else\r
- * false\r
- */\r
- isLocked: function() {\r
- return (this.DDM.isLocked() || this.locked);\r
- },\r
-\r
- /**\r
- * Fired when this object is clicked\r
- * @method handleMouseDown\r
- * @param {Event} e\r
- * @param {Ext.dd.DragDrop} oDD the clicked dd object (this dd obj)\r
- * @private\r
- */\r
- handleMouseDown: function(e, oDD){\r
- if (this.primaryButtonOnly && e.button != 0) {\r
- return;\r
- }\r
-\r
- if (this.isLocked()) {\r
- return;\r
- }\r
-\r
- this.DDM.refreshCache(this.groups);\r
-\r
- var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));\r
- if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) ) {\r
- } else {\r
- if (this.clickValidator(e)) {\r
-\r
- // set the initial element position\r
- this.setStartPosition();\r
-\r
-\r
- this.b4MouseDown(e);\r
- this.onMouseDown(e);\r
-\r
- this.DDM.handleMouseDown(e, this);\r
-\r
- this.DDM.stopEvent(e);\r
- } else {\r
-\r
-\r
- }\r
- }\r
- },\r
-\r
- clickValidator: function(e) {\r
- var target = e.getTarget();\r
- return ( this.isValidHandleChild(target) &&\r
- (this.id == this.handleElId ||\r
- this.DDM.handleWasClicked(target, this.id)) );\r
- },\r
-\r
- /**\r
- * Allows you to specify a tag name that should not start a drag operation\r
- * when clicked. This is designed to facilitate embedding links within a\r
- * drag handle that do something other than start the drag.\r
- * @method addInvalidHandleType\r
- * @param {string} tagName the type of element to exclude\r
- */\r
- addInvalidHandleType: function(tagName) {\r
- var type = tagName.toUpperCase();\r
- this.invalidHandleTypes[type] = type;\r
- },\r
-\r
- /**\r
- * Lets you to specify an element id for a child of a drag handle\r
- * that should not initiate a drag\r
- * @method addInvalidHandleId\r
- * @param {string} id the element id of the element you wish to ignore\r
- */\r
- addInvalidHandleId: function(id) {\r
- if (typeof id !== "string") {\r
- id = Ext.id(id);\r
- }\r
- this.invalidHandleIds[id] = id;\r
- },\r
-\r
- /**\r
- * Lets you specify a css class of elements that will not initiate a drag\r
- * @method addInvalidHandleClass\r
- * @param {string} cssClass the class of the elements you wish to ignore\r
- */\r
- addInvalidHandleClass: function(cssClass) {\r
- this.invalidHandleClasses.push(cssClass);\r
- },\r
-\r
- /**\r
- * Unsets an excluded tag name set by addInvalidHandleType\r
- * @method removeInvalidHandleType\r
- * @param {string} tagName the type of element to unexclude\r
- */\r
- removeInvalidHandleType: function(tagName) {\r
- var type = tagName.toUpperCase();\r
- // this.invalidHandleTypes[type] = null;\r
- delete this.invalidHandleTypes[type];\r
- },\r
-\r
- /**\r
- * Unsets an invalid handle id\r
- * @method removeInvalidHandleId\r
- * @param {string} id the id of the element to re-enable\r
- */\r
- removeInvalidHandleId: function(id) {\r
- if (typeof id !== "string") {\r
- id = Ext.id(id);\r
- }\r
- delete this.invalidHandleIds[id];\r
- },\r
-\r
- /**\r
- * Unsets an invalid css class\r
- * @method removeInvalidHandleClass\r
- * @param {string} cssClass the class of the element(s) you wish to\r
- * re-enable\r
- */\r
- removeInvalidHandleClass: function(cssClass) {\r
- for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {\r
- if (this.invalidHandleClasses[i] == cssClass) {\r
- delete this.invalidHandleClasses[i];\r
- }\r
- }\r
- },\r
-\r
- /**\r
- * Checks the tag exclusion list to see if this click should be ignored\r
- * @method isValidHandleChild\r
- * @param {HTMLElement} node the HTMLElement to evaluate\r
- * @return {boolean} true if this is a valid tag type, false if not\r
- */\r
- isValidHandleChild: function(node) {\r
-\r
- var valid = true;\r
- // var n = (node.nodeName == "#text") ? node.parentNode : node;\r
- var nodeName;\r
- try {\r
- nodeName = node.nodeName.toUpperCase();\r
- } catch(e) {\r
- nodeName = node.nodeName;\r
- }\r
- valid = valid && !this.invalidHandleTypes[nodeName];\r
- valid = valid && !this.invalidHandleIds[node.id];\r
-\r
- for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {\r
- valid = !Ext.fly(node).hasClass(this.invalidHandleClasses[i]);\r
- }\r
-\r
-\r
- return valid;\r
-\r
- },\r
-\r
- /**\r
- * Create the array of horizontal tick marks if an interval was specified\r
- * in setXConstraint().\r
- * @method setXTicks\r
- * @private\r
- */\r
- setXTicks: function(iStartX, iTickSize) {\r
- this.xTicks = [];\r
- this.xTickSize = iTickSize;\r
-\r
- var tickMap = {};\r
-\r
- for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {\r
- if (!tickMap[i]) {\r
- this.xTicks[this.xTicks.length] = i;\r
- tickMap[i] = true;\r
- }\r
- }\r
-\r
- for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {\r
- if (!tickMap[i]) {\r
- this.xTicks[this.xTicks.length] = i;\r
- tickMap[i] = true;\r
- }\r
- }\r
-\r
- this.xTicks.sort(this.DDM.numericSort) ;\r
- },\r
-\r
- /**\r
- * Create the array of vertical tick marks if an interval was specified in\r
- * setYConstraint().\r
- * @method setYTicks\r
- * @private\r
- */\r
- setYTicks: function(iStartY, iTickSize) {\r
- this.yTicks = [];\r
- this.yTickSize = iTickSize;\r
-\r
- var tickMap = {};\r
-\r
- for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {\r
- if (!tickMap[i]) {\r
- this.yTicks[this.yTicks.length] = i;\r
- tickMap[i] = true;\r
- }\r
- }\r
-\r
- for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {\r
- if (!tickMap[i]) {\r
- this.yTicks[this.yTicks.length] = i;\r
- tickMap[i] = true;\r
- }\r
- }\r
-\r
- this.yTicks.sort(this.DDM.numericSort) ;\r
- },\r
-\r
- /**\r
- * By default, the element can be dragged any place on the screen. Use\r
- * this method to limit the horizontal travel of the element. Pass in\r
- * 0,0 for the parameters if you want to lock the drag to the y axis.\r
- * @method setXConstraint\r
- * @param {int} iLeft the number of pixels the element can move to the left\r
- * @param {int} iRight the number of pixels the element can move to the\r
- * right\r
- * @param {int} iTickSize optional parameter for specifying that the\r
- * element\r
- * should move iTickSize pixels at a time.\r
- */\r
- setXConstraint: function(iLeft, iRight, iTickSize) {\r
- this.leftConstraint = iLeft;\r
- this.rightConstraint = iRight;\r
-\r
- this.minX = this.initPageX - iLeft;\r
- this.maxX = this.initPageX + iRight;\r
- if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }\r
-\r
- this.constrainX = true;\r
- },\r
-\r
- /**\r
- * Clears any constraints applied to this instance. Also clears ticks\r
- * since they can't exist independent of a constraint at this time.\r
- * @method clearConstraints\r
- */\r
- clearConstraints: function() {\r
- this.constrainX = false;\r
- this.constrainY = false;\r
- this.clearTicks();\r
- },\r
-\r
- /**\r
- * Clears any tick interval defined for this instance\r
- * @method clearTicks\r
- */\r
- clearTicks: function() {\r
- this.xTicks = null;\r
- this.yTicks = null;\r
- this.xTickSize = 0;\r
- this.yTickSize = 0;\r
- },\r
-\r
- /**\r
- * By default, the element can be dragged any place on the screen. Set\r
- * this to limit the vertical travel of the element. Pass in 0,0 for the\r
- * parameters if you want to lock the drag to the x axis.\r
- * @method setYConstraint\r
- * @param {int} iUp the number of pixels the element can move up\r
- * @param {int} iDown the number of pixels the element can move down\r
- * @param {int} iTickSize optional parameter for specifying that the\r
- * element should move iTickSize pixels at a time.\r
- */\r
- setYConstraint: function(iUp, iDown, iTickSize) {\r
- this.topConstraint = iUp;\r
- this.bottomConstraint = iDown;\r
-\r
- this.minY = this.initPageY - iUp;\r
- this.maxY = this.initPageY + iDown;\r
- if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }\r
-\r
- this.constrainY = true;\r
-\r
- },\r
-\r
- /**\r
- * resetConstraints must be called if you manually reposition a dd element.\r
- * @method resetConstraints\r
- * @param {boolean} maintainOffset\r
- */\r
- resetConstraints: function() {\r
-\r
-\r
- // Maintain offsets if necessary\r
- if (this.initPageX || this.initPageX === 0) {\r
- // figure out how much this thing has moved\r
- var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;\r
- var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;\r
-\r
- this.setInitPosition(dx, dy);\r
-\r
- // This is the first time we have detected the element's position\r
- } else {\r
- this.setInitPosition();\r
- }\r
-\r
- if (this.constrainX) {\r
- this.setXConstraint( this.leftConstraint,\r
- this.rightConstraint,\r
- this.xTickSize );\r
- }\r
-\r
- if (this.constrainY) {\r
- this.setYConstraint( this.topConstraint,\r
- this.bottomConstraint,\r
- this.yTickSize );\r
- }\r
- },\r
-\r
- /**\r
- * Normally the drag element is moved pixel by pixel, but we can specify\r
- * that it move a number of pixels at a time. This method resolves the\r
- * location when we have it set up like this.\r
- * @method getTick\r
- * @param {int} val where we want to place the object\r
- * @param {int[]} tickArray sorted array of valid points\r
- * @return {int} the closest tick\r
- * @private\r
- */\r
- getTick: function(val, tickArray) {\r
-\r
- if (!tickArray) {\r
- // If tick interval is not defined, it is effectively 1 pixel,\r
- // so we return the value passed to us.\r
- return val;\r
- } else if (tickArray[0] >= val) {\r
- // The value is lower than the first tick, so we return the first\r
- // tick.\r
- return tickArray[0];\r
- } else {\r
- for (var i=0, len=tickArray.length; i<len; ++i) {\r
- var next = i + 1;\r
- if (tickArray[next] && tickArray[next] >= val) {\r
- var diff1 = val - tickArray[i];\r
- var diff2 = tickArray[next] - val;\r
- return (diff2 > diff1) ? tickArray[i] : tickArray[next];\r
- }\r
- }\r
-\r
- // The value is larger than the last tick, so we return the last\r
- // tick.\r
- return tickArray[tickArray.length - 1];\r
- }\r
- },\r
-\r
- /**\r
- * toString method\r
- * @method toString\r
- * @return {string} string representation of the dd obj\r
- */\r
- toString: function() {\r
- return ("DragDrop " + this.id);\r
- }\r
-\r
-};\r
-\r
-})();\r
-/**\r
- * The drag and drop utility provides a framework for building drag and drop\r
- * applications. In addition to enabling drag and drop for specific elements,\r
- * the drag and drop elements are tracked by the manager class, and the\r
- * interactions between the various elements are tracked during the drag and\r
- * the implementing code is notified about these important moments.\r
- */\r
-\r
-// Only load the library once. Rewriting the manager class would orphan\r
-// existing drag and drop instances.\r
-if (!Ext.dd.DragDropMgr) {\r
-\r
-/**\r
- * @class Ext.dd.DragDropMgr\r
- * DragDropMgr is a singleton that tracks the element interaction for\r
- * all DragDrop items in the window. Generally, you will not call\r
- * this class directly, but it does have helper methods that could\r
- * be useful in your DragDrop implementations.\r
- * @singleton\r
- */\r
-Ext.dd.DragDropMgr = function() {\r
-\r
- var Event = Ext.EventManager;\r
-\r
- return {\r
-\r
- /**\r
- * Two dimensional Array of registered DragDrop objects. The first\r
- * dimension is the DragDrop item group, the second the DragDrop\r
- * object.\r
- * @property ids\r
- * @type {string: string}\r
- * @private\r
- * @static\r
- */\r
- ids: {},\r
-\r
- /**\r
- * Array of element ids defined as drag handles. Used to determine\r
- * if the element that generated the mousedown event is actually the\r
- * handle and not the html element itself.\r
- * @property handleIds\r
- * @type {string: string}\r
- * @private\r
- * @static\r
- */\r
- handleIds: {},\r
-\r
- /**\r
- * the DragDrop object that is currently being dragged\r
- * @property dragCurrent\r
- * @type DragDrop\r
- * @private\r
- * @static\r
- **/\r
- dragCurrent: null,\r
-\r
- /**\r
- * the DragDrop object(s) that are being hovered over\r
- * @property dragOvers\r
- * @type Array\r
- * @private\r
- * @static\r
- */\r
- dragOvers: {},\r
-\r
- /**\r
- * the X distance between the cursor and the object being dragged\r
- * @property deltaX\r
- * @type int\r
- * @private\r
- * @static\r
- */\r
- deltaX: 0,\r
-\r
- /**\r
- * the Y distance between the cursor and the object being dragged\r
- * @property deltaY\r
- * @type int\r
- * @private\r
- * @static\r
- */\r
- deltaY: 0,\r
-\r
- /**\r
- * Flag to determine if we should prevent the default behavior of the\r
- * events we define. By default this is true, but this can be set to\r
- * false if you need the default behavior (not recommended)\r
- * @property preventDefault\r
- * @type boolean\r
- * @static\r
- */\r
- preventDefault: true,\r
-\r
- /**\r
- * Flag to determine if we should stop the propagation of the events\r
- * we generate. This is true by default but you may want to set it to\r
- * false if the html element contains other features that require the\r
- * mouse click.\r
- * @property stopPropagation\r
- * @type boolean\r
- * @static\r
- */\r
- stopPropagation: true,\r
-\r
- /**\r
- * Internal flag that is set to true when drag and drop has been\r
- * intialized\r
- * @property initialized\r
- * @private\r
- * @static\r
- */\r
- initialized: false,\r
-\r
- /**\r
- * All drag and drop can be disabled.\r
- * @property locked\r
- * @private\r
- * @static\r
- */\r
- locked: false,\r
-\r
- /**\r
- * Called the first time an element is registered.\r
- * @method init\r
- * @private\r
- * @static\r
- */\r
- init: function() {\r
- this.initialized = true;\r
- },\r
-\r
- /**\r
- * In point mode, drag and drop interaction is defined by the\r
- * location of the cursor during the drag/drop\r
- * @property POINT\r
- * @type int\r
- * @static\r
- */\r
- POINT: 0,\r
-\r
- /**\r
- * In intersect mode, drag and drop interaction is defined by the\r
- * overlap of two or more drag and drop objects.\r
- * @property INTERSECT\r
- * @type int\r
- * @static\r
- */\r
- INTERSECT: 1,\r
-\r
- /**\r
- * The current drag and drop mode. Default: POINT\r
- * @property mode\r
- * @type int\r
- * @static\r
- */\r
- mode: 0,\r
-\r
- /**\r
- * Runs method on all drag and drop objects\r
- * @method _execOnAll\r
- * @private\r
- * @static\r
- */\r
- _execOnAll: function(sMethod, args) {\r
- for (var i in this.ids) {\r
- for (var j in this.ids[i]) {\r
- var oDD = this.ids[i][j];\r
- if (! this.isTypeOfDD(oDD)) {\r
- continue;\r
- }\r
- oDD[sMethod].apply(oDD, args);\r
- }\r
- }\r
- },\r
-\r
- /**\r
- * Drag and drop initialization. Sets up the global event handlers\r
- * @method _onLoad\r
- * @private\r
- * @static\r
- */\r
- _onLoad: function() {\r
-\r
- this.init();\r
-\r
-\r
- Event.on(document, "mouseup", this.handleMouseUp, this, true);\r
- Event.on(document, "mousemove", this.handleMouseMove, this, true);\r
- Event.on(window, "unload", this._onUnload, this, true);\r
- Event.on(window, "resize", this._onResize, this, true);\r
- // Event.on(window, "mouseout", this._test);\r
-\r
- },\r
-\r
- /**\r
- * Reset constraints on all drag and drop objs\r
- * @method _onResize\r
- * @private\r
- * @static\r
- */\r
- _onResize: function(e) {\r
- this._execOnAll("resetConstraints", []);\r
- },\r
-\r
- /**\r
- * Lock all drag and drop functionality\r
- * @method lock\r
- * @static\r
- */\r
- lock: function() { this.locked = true; },\r
-\r
- /**\r
- * Unlock all drag and drop functionality\r
- * @method unlock\r
- * @static\r
- */\r
- unlock: function() { this.locked = false; },\r
-\r
- /**\r
- * Is drag and drop locked?\r
- * @method isLocked\r
- * @return {boolean} True if drag and drop is locked, false otherwise.\r
- * @static\r
- */\r
- isLocked: function() { return this.locked; },\r
-\r
- /**\r
- * Location cache that is set for all drag drop objects when a drag is\r
- * initiated, cleared when the drag is finished.\r
- * @property locationCache\r
- * @private\r
- * @static\r
- */\r
- locationCache: {},\r
-\r
- /**\r
- * Set useCache to false if you want to force object the lookup of each\r
- * drag and drop linked element constantly during a drag.\r
- * @property useCache\r
- * @type boolean\r
- * @static\r
- */\r
- useCache: true,\r
-\r
- /**\r
- * The number of pixels that the mouse needs to move after the\r
- * mousedown before the drag is initiated. Default=3;\r
- * @property clickPixelThresh\r
- * @type int\r
- * @static\r
- */\r
- clickPixelThresh: 3,\r
-\r
- /**\r
- * The number of milliseconds after the mousedown event to initiate the\r
- * drag if we don't get a mouseup event. Default=1000\r
- * @property clickTimeThresh\r
- * @type int\r
- * @static\r
- */\r
- clickTimeThresh: 350,\r
-\r
- /**\r
- * Flag that indicates that either the drag pixel threshold or the\r
- * mousdown time threshold has been met\r
- * @property dragThreshMet\r
- * @type boolean\r
- * @private\r
- * @static\r
- */\r
- dragThreshMet: false,\r
-\r
- /**\r
- * Timeout used for the click time threshold\r
- * @property clickTimeout\r
- * @type Object\r
- * @private\r
- * @static\r
- */\r
- clickTimeout: null,\r
-\r
- /**\r
- * The X position of the mousedown event stored for later use when a\r
- * drag threshold is met.\r
- * @property startX\r
- * @type int\r
- * @private\r
- * @static\r
- */\r
- startX: 0,\r
-\r
- /**\r
- * The Y position of the mousedown event stored for later use when a\r
- * drag threshold is met.\r
- * @property startY\r
- * @type int\r
- * @private\r
- * @static\r
- */\r
- startY: 0,\r
-\r
- /**\r
- * Each DragDrop instance must be registered with the DragDropMgr.\r
- * This is executed in DragDrop.init()\r
- * @method regDragDrop\r
- * @param {DragDrop} oDD the DragDrop object to register\r
- * @param {String} sGroup the name of the group this element belongs to\r
- * @static\r
- */\r
- regDragDrop: function(oDD, sGroup) {\r
- if (!this.initialized) { this.init(); }\r
-\r
- if (!this.ids[sGroup]) {\r
- this.ids[sGroup] = {};\r
- }\r
- this.ids[sGroup][oDD.id] = oDD;\r
- },\r
-\r
- /**\r
- * Removes the supplied dd instance from the supplied group. Executed\r
- * by DragDrop.removeFromGroup, so don't call this function directly.\r
- * @method removeDDFromGroup\r
- * @private\r
- * @static\r
- */\r
- removeDDFromGroup: function(oDD, sGroup) {\r
- if (!this.ids[sGroup]) {\r
- this.ids[sGroup] = {};\r
- }\r
-\r
- var obj = this.ids[sGroup];\r
- if (obj && obj[oDD.id]) {\r
- delete obj[oDD.id];\r
- }\r
- },\r
-\r
- /**\r
- * Unregisters a drag and drop item. This is executed in\r
- * DragDrop.unreg, use that method instead of calling this directly.\r
- * @method _remove\r
- * @private\r
- * @static\r
- */\r
- _remove: function(oDD) {\r
- for (var g in oDD.groups) {\r
- if (g && this.ids[g] && this.ids[g][oDD.id]) {\r
- delete this.ids[g][oDD.id];\r
- }\r
- }\r
- delete this.handleIds[oDD.id];\r
- },\r
-\r
- /**\r
- * Each DragDrop handle element must be registered. This is done\r
- * automatically when executing DragDrop.setHandleElId()\r
- * @method regHandle\r
- * @param {String} sDDId the DragDrop id this element is a handle for\r
- * @param {String} sHandleId the id of the element that is the drag\r
- * handle\r
- * @static\r
- */\r
- regHandle: function(sDDId, sHandleId) {\r
- if (!this.handleIds[sDDId]) {\r
- this.handleIds[sDDId] = {};\r
- }\r
- this.handleIds[sDDId][sHandleId] = sHandleId;\r
- },\r
-\r
- /**\r
- * Utility function to determine if a given element has been\r
- * registered as a drag drop item.\r
- * @method isDragDrop\r
- * @param {String} id the element id to check\r
- * @return {boolean} true if this element is a DragDrop item,\r
- * false otherwise\r
- * @static\r
- */\r
- isDragDrop: function(id) {\r
- return ( this.getDDById(id) ) ? true : false;\r
- },\r
-\r
- /**\r
- * Returns the drag and drop instances that are in all groups the\r
- * passed in instance belongs to.\r
- * @method getRelated\r
- * @param {DragDrop} p_oDD the obj to get related data for\r
- * @param {boolean} bTargetsOnly if true, only return targetable objs\r
- * @return {DragDrop[]} the related instances\r
- * @static\r
- */\r
- getRelated: function(p_oDD, bTargetsOnly) {\r
- var oDDs = [];\r
- for (var i in p_oDD.groups) {\r
- for (j in this.ids[i]) {\r
- var dd = this.ids[i][j];\r
- if (! this.isTypeOfDD(dd)) {\r
- continue;\r
- }\r
- if (!bTargetsOnly || dd.isTarget) {\r
- oDDs[oDDs.length] = dd;\r
- }\r
- }\r
- }\r
-\r
- return oDDs;\r
- },\r
-\r
- /**\r
- * Returns true if the specified dd target is a legal target for\r
- * the specifice drag obj\r
- * @method isLegalTarget\r
- * @param {DragDrop} the drag obj\r
- * @param {DragDrop} the target\r
- * @return {boolean} true if the target is a legal target for the\r
- * dd obj\r
- * @static\r
- */\r
- isLegalTarget: function (oDD, oTargetDD) {\r
- var targets = this.getRelated(oDD, true);\r
- for (var i=0, len=targets.length;i<len;++i) {\r
- if (targets[i].id == oTargetDD.id) {\r
- return true;\r
- }\r
- }\r
-\r
- return false;\r
- },\r
-\r
- /**\r
- * My goal is to be able to transparently determine if an object is\r
- * typeof DragDrop, and the exact subclass of DragDrop. typeof\r
- * returns "object", oDD.constructor.toString() always returns\r
- * "DragDrop" and not the name of the subclass. So for now it just\r
- * evaluates a well-known variable in DragDrop.\r
- * @method isTypeOfDD\r
- * @param {Object} the object to evaluate\r
- * @return {boolean} true if typeof oDD = DragDrop\r
- * @static\r
- */\r
- isTypeOfDD: function (oDD) {\r
- return (oDD && oDD.__ygDragDrop);\r
- },\r
-\r
- /**\r
- * Utility function to determine if a given element has been\r
- * registered as a drag drop handle for the given Drag Drop object.\r
- * @method isHandle\r
- * @param {String} id the element id to check\r
- * @return {boolean} true if this element is a DragDrop handle, false\r
- * otherwise\r
- * @static\r
- */\r
- isHandle: function(sDDId, sHandleId) {\r
- return ( this.handleIds[sDDId] &&\r
- this.handleIds[sDDId][sHandleId] );\r
- },\r
-\r
- /**\r
- * Returns the DragDrop instance for a given id\r
- * @method getDDById\r
- * @param {String} id the id of the DragDrop object\r
- * @return {DragDrop} the drag drop object, null if it is not found\r
- * @static\r
- */\r
- getDDById: function(id) {\r
- for (var i in this.ids) {\r
- if (this.ids[i][id]) {\r
- return this.ids[i][id];\r
- }\r
- }\r
- return null;\r
- },\r
-\r
- /**\r
- * Fired after a registered DragDrop object gets the mousedown event.\r
- * Sets up the events required to track the object being dragged\r
- * @method handleMouseDown\r
- * @param {Event} e the event\r
- * @param oDD the DragDrop object being dragged\r
- * @private\r
- * @static\r
- */\r
- handleMouseDown: function(e, oDD) {\r
- if(Ext.QuickTips){\r
- Ext.QuickTips.disable();\r
- }\r
- if(this.dragCurrent){\r
- // the original browser mouseup wasn't handled (e.g. outside FF browser window)\r
- // so clean up first to avoid breaking the next drag\r
- this.handleMouseUp(e);\r
- }\r
- \r
- this.currentTarget = e.getTarget();\r
- this.dragCurrent = oDD;\r
-\r
- var el = oDD.getEl();\r
-\r
- // track start position\r
- this.startX = e.getPageX();\r
- this.startY = e.getPageY();\r
-\r
- this.deltaX = this.startX - el.offsetLeft;\r
- this.deltaY = this.startY - el.offsetTop;\r
-\r
- this.dragThreshMet = false;\r
-\r
- this.clickTimeout = setTimeout(\r
- function() {\r
- var DDM = Ext.dd.DDM;\r
- DDM.startDrag(DDM.startX, DDM.startY);\r
- },\r
- this.clickTimeThresh );\r
- },\r
-\r
- /**\r
- * Fired when either the drag pixel threshol or the mousedown hold\r
- * time threshold has been met.\r
- * @method startDrag\r
- * @param x {int} the X position of the original mousedown\r
- * @param y {int} the Y position of the original mousedown\r
- * @static\r
- */\r
- startDrag: function(x, y) {\r
- clearTimeout(this.clickTimeout);\r
- if (this.dragCurrent) {\r
- this.dragCurrent.b4StartDrag(x, y);\r
- this.dragCurrent.startDrag(x, y);\r
- }\r
- this.dragThreshMet = true;\r
- },\r
-\r
- /**\r
- * Internal function to handle the mouseup event. Will be invoked\r
- * from the context of the document.\r
- * @method handleMouseUp\r
- * @param {Event} e the event\r
- * @private\r
- * @static\r
- */\r
- handleMouseUp: function(e) {\r
-\r
- if(Ext.QuickTips){\r
- Ext.QuickTips.enable();\r
- }\r
- if (! this.dragCurrent) {\r
- return;\r
- }\r
-\r
- clearTimeout(this.clickTimeout);\r
-\r
- if (this.dragThreshMet) {\r
- this.fireEvents(e, true);\r
- } else {\r
- }\r
-\r
- this.stopDrag(e);\r
-\r
- this.stopEvent(e);\r
- },\r
-\r
- /**\r
- * Utility to stop event propagation and event default, if these\r
- * features are turned on.\r
- * @method stopEvent\r
- * @param {Event} e the event as returned by this.getEvent()\r
- * @static\r
- */\r
- stopEvent: function(e){\r
- if(this.stopPropagation) {\r
- e.stopPropagation();\r
- }\r
-\r
- if (this.preventDefault) {\r
- e.preventDefault();\r
- }\r
- },\r
-\r
- /**\r
- * Internal function to clean up event handlers after the drag\r
- * operation is complete\r
- * @method stopDrag\r
- * @param {Event} e the event\r
- * @private\r
- * @static\r
- */\r
- stopDrag: function(e) {\r
- // Fire the drag end event for the item that was dragged\r
- if (this.dragCurrent) {\r
- if (this.dragThreshMet) {\r
- this.dragCurrent.b4EndDrag(e);\r
- this.dragCurrent.endDrag(e);\r
- }\r
-\r
- this.dragCurrent.onMouseUp(e);\r
- }\r
-\r
- this.dragCurrent = null;\r
- this.dragOvers = {};\r
- },\r
-\r
- /**\r
- * Internal function to handle the mousemove event. Will be invoked\r
- * from the context of the html element.\r
- *\r
- * @TODO figure out what we can do about mouse events lost when the\r
- * user drags objects beyond the window boundary. Currently we can\r
- * detect this in internet explorer by verifying that the mouse is\r
- * down during the mousemove event. Firefox doesn't give us the\r
- * button state on the mousemove event.\r
- * @method handleMouseMove\r
- * @param {Event} e the event\r
- * @private\r
- * @static\r
- */\r
- handleMouseMove: function(e) {\r
- if (! this.dragCurrent) {\r
- return true;\r
- }\r
-\r
- // var button = e.which || e.button;\r
-\r
- // check for IE mouseup outside of page boundary\r
- if (Ext.isIE && (e.button !== 0 && e.button !== 1 && e.button !== 2)) {\r
- this.stopEvent(e);\r
- return this.handleMouseUp(e);\r
- }\r
-\r
- if (!this.dragThreshMet) {\r
- var diffX = Math.abs(this.startX - e.getPageX());\r
- var diffY = Math.abs(this.startY - e.getPageY());\r
- if (diffX > this.clickPixelThresh ||\r
- diffY > this.clickPixelThresh) {\r
- this.startDrag(this.startX, this.startY);\r
- }\r
- }\r
-\r
- if (this.dragThreshMet) {\r
- this.dragCurrent.b4Drag(e);\r
- this.dragCurrent.onDrag(e);\r
- if(!this.dragCurrent.moveOnly){\r
- this.fireEvents(e, false);\r
- }\r
- }\r
-\r
- this.stopEvent(e);\r
-\r
- return true;\r
- },\r
-\r
- /**\r
- * Iterates over all of the DragDrop elements to find ones we are\r
- * hovering over or dropping on\r
- * @method fireEvents\r
- * @param {Event} e the event\r
- * @param {boolean} isDrop is this a drop op or a mouseover op?\r
- * @private\r
- * @static\r
- */\r
- fireEvents: function(e, isDrop) {\r
- var dc = this.dragCurrent;\r
-\r
- // If the user did the mouse up outside of the window, we could\r
- // get here even though we have ended the drag.\r
- if (!dc || dc.isLocked()) {\r
- return;\r
- }\r
-\r
- var pt = e.getPoint();\r
-\r
- // cache the previous dragOver array\r
- var oldOvers = [];\r
-\r
- var outEvts = [];\r
- var overEvts = [];\r
- var dropEvts = [];\r
- var enterEvts = [];\r
-\r
- // Check to see if the object(s) we were hovering over is no longer\r
- // being hovered over so we can fire the onDragOut event\r
- for (var i in this.dragOvers) {\r
-\r
- var ddo = this.dragOvers[i];\r
-\r
- if (! this.isTypeOfDD(ddo)) {\r
- continue;\r
- }\r
-\r
- if (! this.isOverTarget(pt, ddo, this.mode)) {\r
- outEvts.push( ddo );\r
- }\r
-\r
- oldOvers[i] = true;\r
- delete this.dragOvers[i];\r
- }\r
-\r
- for (var sGroup in dc.groups) {\r
-\r
- if ("string" != typeof sGroup) {\r
- continue;\r
- }\r
-\r
- for (i in this.ids[sGroup]) {\r
- var oDD = this.ids[sGroup][i];\r
- if (! this.isTypeOfDD(oDD)) {\r
- continue;\r
- }\r
-\r
- if (oDD.isTarget && !oDD.isLocked() && oDD != dc) {\r
- if (this.isOverTarget(pt, oDD, this.mode)) {\r
- // look for drop interactions\r
- if (isDrop) {\r
- dropEvts.push( oDD );\r
- // look for drag enter and drag over interactions\r
- } else {\r
-\r
- // initial drag over: dragEnter fires\r
- if (!oldOvers[oDD.id]) {\r
- enterEvts.push( oDD );\r
- // subsequent drag overs: dragOver fires\r
- } else {\r
- overEvts.push( oDD );\r
- }\r
-\r
- this.dragOvers[oDD.id] = oDD;\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- if (this.mode) {\r
- if (outEvts.length) {\r
- dc.b4DragOut(e, outEvts);\r
- dc.onDragOut(e, outEvts);\r
- }\r
-\r
- if (enterEvts.length) {\r
- dc.onDragEnter(e, enterEvts);\r
- }\r
-\r
- if (overEvts.length) {\r
- dc.b4DragOver(e, overEvts);\r
- dc.onDragOver(e, overEvts);\r
- }\r
-\r
- if (dropEvts.length) {\r
- dc.b4DragDrop(e, dropEvts);\r
- dc.onDragDrop(e, dropEvts);\r
- }\r
-\r
- } else {\r
- // fire dragout events\r
- var len = 0;\r
- for (i=0, len=outEvts.length; i<len; ++i) {\r
- dc.b4DragOut(e, outEvts[i].id);\r
- dc.onDragOut(e, outEvts[i].id);\r
- }\r
-\r
- // fire enter events\r
- for (i=0,len=enterEvts.length; i<len; ++i) {\r
- // dc.b4DragEnter(e, oDD.id);\r
- dc.onDragEnter(e, enterEvts[i].id);\r
- }\r
-\r
- // fire over events\r
- for (i=0,len=overEvts.length; i<len; ++i) {\r
- dc.b4DragOver(e, overEvts[i].id);\r
- dc.onDragOver(e, overEvts[i].id);\r
- }\r
-\r
- // fire drop events\r
- for (i=0, len=dropEvts.length; i<len; ++i) {\r
- dc.b4DragDrop(e, dropEvts[i].id);\r
- dc.onDragDrop(e, dropEvts[i].id);\r
- }\r
-\r
- }\r
-\r
- // notify about a drop that did not find a target\r
- if (isDrop && !dropEvts.length) {\r
- dc.onInvalidDrop(e);\r
- }\r
-\r
- },\r
-\r
- /**\r
- * Helper function for getting the best match from the list of drag\r
- * and drop objects returned by the drag and drop events when we are\r
- * in INTERSECT mode. It returns either the first object that the\r
- * cursor is over, or the object that has the greatest overlap with\r
- * the dragged element.\r
- * @method getBestMatch\r
- * @param {DragDrop[]} dds The array of drag and drop objects\r
- * targeted\r
- * @return {DragDrop} The best single match\r
- * @static\r
- */\r
- getBestMatch: function(dds) {\r
- var winner = null;\r
- // Return null if the input is not what we expect\r
- //if (!dds || !dds.length || dds.length == 0) {\r
- // winner = null;\r
- // If there is only one item, it wins\r
- //} else if (dds.length == 1) {\r
-\r
- var len = dds.length;\r
-\r
- if (len == 1) {\r
- winner = dds[0];\r
- } else {\r
- // Loop through the targeted items\r
- for (var i=0; i<len; ++i) {\r
- var dd = dds[i];\r
- // If the cursor is over the object, it wins. If the\r
- // cursor is over multiple matches, the first one we come\r
- // to wins.\r
- if (dd.cursorIsOver) {\r
- winner = dd;\r
- break;\r
- // Otherwise the object with the most overlap wins\r
- } else {\r
- if (!winner ||\r
- winner.overlap.getArea() < dd.overlap.getArea()) {\r
- winner = dd;\r
- }\r
- }\r
- }\r
- }\r
-\r
- return winner;\r
- },\r
-\r
- /**\r
- * Refreshes the cache of the top-left and bottom-right points of the\r
- * drag and drop objects in the specified group(s). This is in the\r
- * format that is stored in the drag and drop instance, so typical\r
- * usage is:\r
- * <code>\r
- * Ext.dd.DragDropMgr.refreshCache(ddinstance.groups);\r
- * </code>\r
- * Alternatively:\r
- * <code>\r
- * Ext.dd.DragDropMgr.refreshCache({group1:true, group2:true});\r
- * </code>\r
- * @TODO this really should be an indexed array. Alternatively this\r
- * method could accept both.\r
- * @method refreshCache\r
- * @param {Object} groups an associative array of groups to refresh\r
- * @static\r
- */\r
- refreshCache: function(groups) {\r
- for (var sGroup in groups) {\r
- if ("string" != typeof sGroup) {\r
- continue;\r
- }\r
- for (var i in this.ids[sGroup]) {\r
- var oDD = this.ids[sGroup][i];\r
-\r
- if (this.isTypeOfDD(oDD)) {\r
- // if (this.isTypeOfDD(oDD) && oDD.isTarget) {\r
- var loc = this.getLocation(oDD);\r
- if (loc) {\r
- this.locationCache[oDD.id] = loc;\r
- } else {\r
- delete this.locationCache[oDD.id];\r
- // this will unregister the drag and drop object if\r
- // the element is not in a usable state\r
- // oDD.unreg();\r
- }\r
- }\r
- }\r
- }\r
- },\r
-\r
- /**\r
- * This checks to make sure an element exists and is in the DOM. The\r
- * main purpose is to handle cases where innerHTML is used to remove\r
- * drag and drop objects from the DOM. IE provides an 'unspecified\r
- * error' when trying to access the offsetParent of such an element\r
- * @method verifyEl\r
- * @param {HTMLElement} el the element to check\r
- * @return {boolean} true if the element looks usable\r
- * @static\r
- */\r
- verifyEl: function(el) {\r
- if (el) {\r
- var parent;\r
- if(Ext.isIE){\r
- try{\r
- parent = el.offsetParent;\r
- }catch(e){}\r
- }else{\r
- parent = el.offsetParent;\r
- }\r
- if (parent) {\r
- return true;\r
- }\r
- }\r
-\r
- return false;\r
- },\r
-\r
- /**\r
- * Returns a Region object containing the drag and drop element's position\r
- * and size, including the padding configured for it\r
- * @method getLocation\r
- * @param {DragDrop} oDD the drag and drop object to get the\r
- * location for\r
- * @return {Ext.lib.Region} a Region object representing the total area\r
- * the element occupies, including any padding\r
- * the instance is configured for.\r
- * @static\r
- */\r
- getLocation: function(oDD) {\r
- if (! this.isTypeOfDD(oDD)) {\r
- return null;\r
- }\r
-\r
- var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;\r
-\r
- try {\r
- pos= Ext.lib.Dom.getXY(el);\r
- } catch (e) { }\r
-\r
- if (!pos) {\r
- return null;\r
- }\r
-\r
- x1 = pos[0];\r
- x2 = x1 + el.offsetWidth;\r
- y1 = pos[1];\r
- y2 = y1 + el.offsetHeight;\r
-\r
- t = y1 - oDD.padding[0];\r
- r = x2 + oDD.padding[1];\r
- b = y2 + oDD.padding[2];\r
- l = x1 - oDD.padding[3];\r
-\r
- return new Ext.lib.Region( t, r, b, l );\r
- },\r
-\r
- /**\r
- * Checks the cursor location to see if it over the target\r
- * @method isOverTarget\r
- * @param {Ext.lib.Point} pt The point to evaluate\r
- * @param {DragDrop} oTarget the DragDrop object we are inspecting\r
- * @return {boolean} true if the mouse is over the target\r
- * @private\r
- * @static\r
- */\r
- isOverTarget: function(pt, oTarget, intersect) {\r
- // use cache if available\r
- var loc = this.locationCache[oTarget.id];\r
- if (!loc || !this.useCache) {\r
- loc = this.getLocation(oTarget);\r
- this.locationCache[oTarget.id] = loc;\r
-\r
- }\r
-\r
- if (!loc) {\r
- return false;\r
- }\r
-\r
- oTarget.cursorIsOver = loc.contains( pt );\r
-\r
- // DragDrop is using this as a sanity check for the initial mousedown\r
- // in this case we are done. In POINT mode, if the drag obj has no\r
- // contraints, we are also done. Otherwise we need to evaluate the\r
- // location of the target as related to the actual location of the\r
- // dragged element.\r
- var dc = this.dragCurrent;\r
- if (!dc || !dc.getTargetCoord ||\r
- (!intersect && !dc.constrainX && !dc.constrainY)) {\r
- return oTarget.cursorIsOver;\r
- }\r
-\r
- oTarget.overlap = null;\r
-\r
- // Get the current location of the drag element, this is the\r
- // location of the mouse event less the delta that represents\r
- // where the original mousedown happened on the element. We\r
- // need to consider constraints and ticks as well.\r
- var pos = dc.getTargetCoord(pt.x, pt.y);\r
-\r
- var el = dc.getDragEl();\r
- var curRegion = new Ext.lib.Region( pos.y,\r
- pos.x + el.offsetWidth,\r
- pos.y + el.offsetHeight,\r
- pos.x );\r
-\r
- var overlap = curRegion.intersect(loc);\r
-\r
- if (overlap) {\r
- oTarget.overlap = overlap;\r
- return (intersect) ? true : oTarget.cursorIsOver;\r
- } else {\r
- return false;\r
- }\r
- },\r
-\r
- /**\r
- * unload event handler\r
- * @method _onUnload\r
- * @private\r
- * @static\r
- */\r
- _onUnload: function(e, me) {\r
- Ext.dd.DragDropMgr.unregAll();\r
- },\r
-\r
- /**\r
- * Cleans up the drag and drop events and objects.\r
- * @method unregAll\r
- * @private\r
- * @static\r
- */\r
- unregAll: function() {\r
-\r
- if (this.dragCurrent) {\r
- this.stopDrag();\r
- this.dragCurrent = null;\r
- }\r
-\r
- this._execOnAll("unreg", []);\r
-\r
- for (var i in this.elementCache) {\r
- delete this.elementCache[i];\r
- }\r
-\r
- this.elementCache = {};\r
- this.ids = {};\r
- },\r
-\r
- /**\r
- * A cache of DOM elements\r
- * @property elementCache\r
- * @private\r
- * @static\r
- */\r
- elementCache: {},\r
-\r
- /**\r
- * Get the wrapper for the DOM element specified\r
- * @method getElWrapper\r
- * @param {String} id the id of the element to get\r
- * @return {Ext.dd.DDM.ElementWrapper} the wrapped element\r
- * @private\r
- * @deprecated This wrapper isn't that useful\r
- * @static\r
- */\r
- getElWrapper: function(id) {\r
- var oWrapper = this.elementCache[id];\r
- if (!oWrapper || !oWrapper.el) {\r
- oWrapper = this.elementCache[id] =\r
- new this.ElementWrapper(Ext.getDom(id));\r
- }\r
- return oWrapper;\r
- },\r
-\r
- /**\r
- * Returns the actual DOM element\r
- * @method getElement\r
- * @param {String} id the id of the elment to get\r
- * @return {Object} The element\r
- * @deprecated use Ext.lib.Ext.getDom instead\r
- * @static\r
- */\r
- getElement: function(id) {\r
- return Ext.getDom(id);\r
- },\r
-\r
- /**\r
- * Returns the style property for the DOM element (i.e.,\r
- * document.getElById(id).style)\r
- * @method getCss\r
- * @param {String} id the id of the elment to get\r
- * @return {Object} The style property of the element\r
- * @deprecated use Ext.lib.Dom instead\r
- * @static\r
- */\r
- getCss: function(id) {\r
- var el = Ext.getDom(id);\r
- return (el) ? el.style : null;\r
- },\r
-\r
- /**\r
- * Inner class for cached elements\r
- * @class DragDropMgr.ElementWrapper\r
- * @for DragDropMgr\r
- * @private\r
- * @deprecated\r
- */\r
- ElementWrapper: function(el) {\r
- /**\r
- * The element\r
- * @property el\r
- */\r
- this.el = el || null;\r
- /**\r
- * The element id\r
- * @property id\r
- */\r
- this.id = this.el && el.id;\r
- /**\r
- * A reference to the style property\r
- * @property css\r
- */\r
- this.css = this.el && el.style;\r
- },\r
-\r
- /**\r
- * Returns the X position of an html element\r
- * @method getPosX\r
- * @param el the element for which to get the position\r
- * @return {int} the X coordinate\r
- * @for DragDropMgr\r
- * @deprecated use Ext.lib.Dom.getX instead\r
- * @static\r
- */\r
- getPosX: function(el) {\r
- return Ext.lib.Dom.getX(el);\r
- },\r
-\r
- /**\r
- * Returns the Y position of an html element\r
- * @method getPosY\r
- * @param el the element for which to get the position\r
- * @return {int} the Y coordinate\r
- * @deprecated use Ext.lib.Dom.getY instead\r
- * @static\r
- */\r
- getPosY: function(el) {\r
- return Ext.lib.Dom.getY(el);\r
- },\r
-\r
- /**\r
- * Swap two nodes. In IE, we use the native method, for others we\r
- * emulate the IE behavior\r
- * @method swapNode\r
- * @param n1 the first node to swap\r
- * @param n2 the other node to swap\r
- * @static\r
- */\r
- swapNode: function(n1, n2) {\r
- if (n1.swapNode) {\r
- n1.swapNode(n2);\r
- } else {\r
- var p = n2.parentNode;\r
- var s = n2.nextSibling;\r
-\r
- if (s == n1) {\r
- p.insertBefore(n1, n2);\r
- } else if (n2 == n1.nextSibling) {\r
- p.insertBefore(n2, n1);\r
- } else {\r
- n1.parentNode.replaceChild(n2, n1);\r
- p.insertBefore(n1, s);\r
- }\r
- }\r
- },\r
-\r
- /**\r
- * Returns the current scroll position\r
- * @method getScroll\r
- * @private\r
- * @static\r
- */\r
- getScroll: function () {\r
- var t, l, dde=document.documentElement, db=document.body;\r
- if (dde && (dde.scrollTop || dde.scrollLeft)) {\r
- t = dde.scrollTop;\r
- l = dde.scrollLeft;\r
- } else if (db) {\r
- t = db.scrollTop;\r
- l = db.scrollLeft;\r
- } else {\r
-\r
- }\r
- return { top: t, left: l };\r
- },\r
-\r
- /**\r
- * Returns the specified element style property\r
- * @method getStyle\r
- * @param {HTMLElement} el the element\r
- * @param {string} styleProp the style property\r
- * @return {string} The value of the style property\r
- * @deprecated use Ext.lib.Dom.getStyle\r
- * @static\r
- */\r
- getStyle: function(el, styleProp) {\r
- return Ext.fly(el).getStyle(styleProp);\r
- },\r
-\r
- /**\r
- * Gets the scrollTop\r
- * @method getScrollTop\r
- * @return {int} the document's scrollTop\r
- * @static\r
- */\r
- getScrollTop: function () { return this.getScroll().top; },\r
-\r
- /**\r
- * Gets the scrollLeft\r
- * @method getScrollLeft\r
- * @return {int} the document's scrollTop\r
- * @static\r
- */\r
- getScrollLeft: function () { return this.getScroll().left; },\r
-\r
- /**\r
- * Sets the x/y position of an element to the location of the\r
- * target element.\r
- * @method moveToEl\r
- * @param {HTMLElement} moveEl The element to move\r
- * @param {HTMLElement} targetEl The position reference element\r
- * @static\r
- */\r
- moveToEl: function (moveEl, targetEl) {\r
- var aCoord = Ext.lib.Dom.getXY(targetEl);\r
- Ext.lib.Dom.setXY(moveEl, aCoord);\r
- },\r
-\r
- /**\r
- * Numeric array sort function\r
- * @method numericSort\r
- * @static\r
- */\r
- numericSort: function(a, b) { return (a - b); },\r
-\r
- /**\r
- * Internal counter\r
- * @property _timeoutCount\r
- * @private\r
- * @static\r
- */\r
- _timeoutCount: 0,\r
-\r
- /**\r
- * Trying to make the load order less important. Without this we get\r
- * an error if this file is loaded before the Event Utility.\r
- * @method _addListeners\r
- * @private\r
- * @static\r
- */\r
- _addListeners: function() {\r
- var DDM = Ext.dd.DDM;\r
- if ( Ext.lib.Event && document ) {\r
- DDM._onLoad();\r
- } else {\r
- if (DDM._timeoutCount > 2000) {\r
- } else {\r
- setTimeout(DDM._addListeners, 10);\r
- if (document && document.body) {\r
- DDM._timeoutCount += 1;\r
- }\r
- }\r
- }\r
- },\r
-\r
- /**\r
- * Recursively searches the immediate parent and all child nodes for\r
- * the handle element in order to determine wheter or not it was\r
- * clicked.\r
- * @method handleWasClicked\r
- * @param node the html element to inspect\r
- * @static\r
- */\r
- handleWasClicked: function(node, id) {\r
- if (this.isHandle(id, node.id)) {\r
- return true;\r
- } else {\r
- // check to see if this is a text node child of the one we want\r
- var p = node.parentNode;\r
-\r
- while (p) {\r
- if (this.isHandle(id, p.id)) {\r
- return true;\r
- } else {\r
- p = p.parentNode;\r
- }\r
- }\r
- }\r
-\r
- return false;\r
- }\r
-\r
- };\r
-\r
-}();\r
-\r
-// shorter alias, save a few bytes\r
-Ext.dd.DDM = Ext.dd.DragDropMgr;\r
-Ext.dd.DDM._addListeners();\r
-\r
-}\r
-\r
-/**\r
- * @class Ext.dd.DD\r
- * A DragDrop implementation where the linked element follows the\r
- * mouse cursor during a drag.\r
- * @extends Ext.dd.DragDrop\r
- * @constructor\r
- * @param {String} id the id of the linked element\r
- * @param {String} sGroup the group of related DragDrop items\r
- * @param {object} config an object containing configurable attributes\r
- * Valid properties for DD:\r
- * scroll\r
- */\r
-Ext.dd.DD = function(id, sGroup, config) {\r
- if (id) {\r
- this.init(id, sGroup, config);\r
- }\r
-};\r
-\r
-Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {\r
-\r
- /**\r
- * When set to true, the utility automatically tries to scroll the browser\r
- * window when a drag and drop element is dragged near the viewport boundary.\r
- * Defaults to true.\r
- * @property scroll\r
- * @type boolean\r
- */\r
- scroll: true,\r
-\r
- /**\r
- * Sets the pointer offset to the distance between the linked element's top\r
- * left corner and the location the element was clicked\r
- * @method autoOffset\r
- * @param {int} iPageX the X coordinate of the click\r
- * @param {int} iPageY the Y coordinate of the click\r
- */\r
- autoOffset: function(iPageX, iPageY) {\r
- var x = iPageX - this.startPageX;\r
- var y = iPageY - this.startPageY;\r
- this.setDelta(x, y);\r
- },\r
-\r
- /**\r
- * Sets the pointer offset. You can call this directly to force the\r
- * offset to be in a particular location (e.g., pass in 0,0 to set it\r
- * to the center of the object)\r
- * @method setDelta\r
- * @param {int} iDeltaX the distance from the left\r
- * @param {int} iDeltaY the distance from the top\r
- */\r
- setDelta: function(iDeltaX, iDeltaY) {\r
- this.deltaX = iDeltaX;\r
- this.deltaY = iDeltaY;\r
- },\r
-\r
- /**\r
- * Sets the drag element to the location of the mousedown or click event,\r
- * maintaining the cursor location relative to the location on the element\r
- * that was clicked. Override this if you want to place the element in a\r
- * location other than where the cursor is.\r
- * @method setDragElPos\r
- * @param {int} iPageX the X coordinate of the mousedown or drag event\r
- * @param {int} iPageY the Y coordinate of the mousedown or drag event\r
- */\r
- setDragElPos: function(iPageX, iPageY) {\r
- // the first time we do this, we are going to check to make sure\r
- // the element has css positioning\r
-\r
- var el = this.getDragEl();\r
- this.alignElWithMouse(el, iPageX, iPageY);\r
- },\r
-\r
- /**\r
- * Sets the element to the location of the mousedown or click event,\r
- * maintaining the cursor location relative to the location on the element\r
- * that was clicked. Override this if you want to place the element in a\r
- * location other than where the cursor is.\r
- * @method alignElWithMouse\r
- * @param {HTMLElement} el the element to move\r
- * @param {int} iPageX the X coordinate of the mousedown or drag event\r
- * @param {int} iPageY the Y coordinate of the mousedown or drag event\r
- */\r
- alignElWithMouse: function(el, iPageX, iPageY) {\r
- var oCoord = this.getTargetCoord(iPageX, iPageY);\r
- var fly = el.dom ? el : Ext.fly(el, '_dd');\r
- if (!this.deltaSetXY) {\r
- var aCoord = [oCoord.x, oCoord.y];\r
- fly.setXY(aCoord);\r
- var newLeft = fly.getLeft(true);\r
- var newTop = fly.getTop(true);\r
- this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];\r
- } else {\r
- fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);\r
- }\r
-\r
- this.cachePosition(oCoord.x, oCoord.y);\r
- this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);\r
- return oCoord;\r
- },\r
-\r
- /**\r
- * Saves the most recent position so that we can reset the constraints and\r
- * tick marks on-demand. We need to know this so that we can calculate the\r
- * number of pixels the element is offset from its original position.\r
- * @method cachePosition\r
- * @param iPageX the current x position (optional, this just makes it so we\r
- * don't have to look it up again)\r
- * @param iPageY the current y position (optional, this just makes it so we\r
- * don't have to look it up again)\r
- */\r
- cachePosition: function(iPageX, iPageY) {\r
- if (iPageX) {\r
- this.lastPageX = iPageX;\r
- this.lastPageY = iPageY;\r
- } else {\r
- var aCoord = Ext.lib.Dom.getXY(this.getEl());\r
- this.lastPageX = aCoord[0];\r
- this.lastPageY = aCoord[1];\r
- }\r
- },\r
-\r
- /**\r
- * Auto-scroll the window if the dragged object has been moved beyond the\r
- * visible window boundary.\r
- * @method autoScroll\r
- * @param {int} x the drag element's x position\r
- * @param {int} y the drag element's y position\r
- * @param {int} h the height of the drag element\r
- * @param {int} w the width of the drag element\r
- * @private\r
- */\r
- autoScroll: function(x, y, h, w) {\r
-\r
- if (this.scroll) {\r
- // The client height\r
- var clientH = Ext.lib.Dom.getViewHeight();\r
-\r
- // The client width\r
- var clientW = Ext.lib.Dom.getViewWidth();\r
-\r
- // The amt scrolled down\r
- var st = this.DDM.getScrollTop();\r
-\r
- // The amt scrolled right\r
- var sl = this.DDM.getScrollLeft();\r
-\r
- // Location of the bottom of the element\r
- var bot = h + y;\r
-\r
- // Location of the right of the element\r
- var right = w + x;\r
-\r
- // The distance from the cursor to the bottom of the visible area,\r
- // adjusted so that we don't scroll if the cursor is beyond the\r
- // element drag constraints\r
- var toBot = (clientH + st - y - this.deltaY);\r
-\r
- // The distance from the cursor to the right of the visible area\r
- var toRight = (clientW + sl - x - this.deltaX);\r
-\r
-\r
- // How close to the edge the cursor must be before we scroll\r
- // var thresh = (document.all) ? 100 : 40;\r
- var thresh = 40;\r
-\r
- // How many pixels to scroll per autoscroll op. This helps to reduce\r
- // clunky scrolling. IE is more sensitive about this ... it needs this\r
- // value to be higher.\r
- var scrAmt = (document.all) ? 80 : 30;\r
-\r
- // Scroll down if we are near the bottom of the visible page and the\r
- // obj extends below the crease\r
- if ( bot > clientH && toBot < thresh ) {\r
- window.scrollTo(sl, st + scrAmt);\r
- }\r
-\r
- // Scroll up if the window is scrolled down and the top of the object\r
- // goes above the top border\r
- if ( y < st && st > 0 && y - st < thresh ) {\r
- window.scrollTo(sl, st - scrAmt);\r
- }\r
-\r
- // Scroll right if the obj is beyond the right border and the cursor is\r
- // near the border.\r
- if ( right > clientW && toRight < thresh ) {\r
- window.scrollTo(sl + scrAmt, st);\r
- }\r
-\r
- // Scroll left if the window has been scrolled to the right and the obj\r
- // extends past the left border\r
- if ( x < sl && sl > 0 && x - sl < thresh ) {\r
- window.scrollTo(sl - scrAmt, st);\r
- }\r
- }\r
- },\r
-\r
- /**\r
- * Finds the location the element should be placed if we want to move\r
- * it to where the mouse location less the click offset would place us.\r
- * @method getTargetCoord\r
- * @param {int} iPageX the X coordinate of the click\r
- * @param {int} iPageY the Y coordinate of the click\r
- * @return an object that contains the coordinates (Object.x and Object.y)\r
- * @private\r
- */\r
- getTargetCoord: function(iPageX, iPageY) {\r
-\r
-\r
- var x = iPageX - this.deltaX;\r
- var y = iPageY - this.deltaY;\r
-\r
- if (this.constrainX) {\r
- if (x < this.minX) { x = this.minX; }\r
- if (x > this.maxX) { x = this.maxX; }\r
- }\r
-\r
- if (this.constrainY) {\r
- if (y < this.minY) { y = this.minY; }\r
- if (y > this.maxY) { y = this.maxY; }\r
- }\r
-\r
- x = this.getTick(x, this.xTicks);\r
- y = this.getTick(y, this.yTicks);\r
-\r
-\r
- return {x:x, y:y};\r
- },\r
-\r
- /**\r
- * Sets up config options specific to this class. Overrides\r
- * Ext.dd.DragDrop, but all versions of this method through the\r
- * inheritance chain are called\r
- */\r
- applyConfig: function() {\r
- Ext.dd.DD.superclass.applyConfig.call(this);\r
- this.scroll = (this.config.scroll !== false);\r
- },\r
-\r
- /**\r
- * Event that fires prior to the onMouseDown event. Overrides\r
- * Ext.dd.DragDrop.\r
- */\r
- b4MouseDown: function(e) {\r
- // this.resetConstraints();\r
- this.autoOffset(e.getPageX(),\r
- e.getPageY());\r
- },\r
-\r
- /**\r
- * Event that fires prior to the onDrag event. Overrides\r
- * Ext.dd.DragDrop.\r
- */\r
- b4Drag: function(e) {\r
- this.setDragElPos(e.getPageX(),\r
- e.getPageY());\r
- },\r
-\r
- toString: function() {\r
- return ("DD " + this.id);\r
- }\r
-\r
- //////////////////////////////////////////////////////////////////////////\r
- // Debugging ygDragDrop events that can be overridden\r
- //////////////////////////////////////////////////////////////////////////\r
- /*\r
- startDrag: function(x, y) {\r
- },\r
-\r
- onDrag: function(e) {\r
- },\r
-\r
- onDragEnter: function(e, id) {\r
- },\r
-\r
- onDragOver: function(e, id) {\r
- },\r
-\r
- onDragOut: function(e, id) {\r
- },\r
-\r
- onDragDrop: function(e, id) {\r
- },\r
-\r
- endDrag: function(e) {\r
- }\r
-\r
- */\r
-\r
-});\r
-/**\r
- * @class Ext.dd.DDProxy\r
- * A DragDrop implementation that inserts an empty, bordered div into\r
- * the document that follows the cursor during drag operations. At the time of\r
- * the click, the frame div is resized to the dimensions of the linked html\r
- * element, and moved to the exact location of the linked element.\r
- *\r
- * References to the "frame" element refer to the single proxy element that\r
- * was created to be dragged in place of all DDProxy elements on the\r
- * page.\r
- *\r
- * @extends Ext.dd.DD\r
- * @constructor\r
- * @param {String} id the id of the linked html element\r
- * @param {String} sGroup the group of related DragDrop objects\r
- * @param {object} config an object containing configurable attributes\r
- * Valid properties for DDProxy in addition to those in DragDrop:\r
- * resizeFrame, centerFrame, dragElId\r
- */\r
-Ext.dd.DDProxy = function(id, sGroup, config) {\r
- if (id) {\r
- this.init(id, sGroup, config);\r
- this.initFrame();\r
- }\r
-};\r
-\r
-/**\r
- * The default drag frame div id\r
- * @property Ext.dd.DDProxy.dragElId\r
- * @type String\r
- * @static\r
- */\r
-Ext.dd.DDProxy.dragElId = "ygddfdiv";\r
-\r
-Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, {\r
-\r
- /**\r
- * By default we resize the drag frame to be the same size as the element\r
- * we want to drag (this is to get the frame effect). We can turn it off\r
- * if we want a different behavior.\r
- * @property resizeFrame\r
- * @type boolean\r
- */\r
- resizeFrame: true,\r
-\r
- /**\r
- * By default the frame is positioned exactly where the drag element is, so\r
- * we use the cursor offset provided by Ext.dd.DD. Another option that works only if\r
- * you do not have constraints on the obj is to have the drag frame centered\r
- * around the cursor. Set centerFrame to true for this effect.\r
- * @property centerFrame\r
- * @type boolean\r
- */\r
- centerFrame: false,\r
-\r
- /**\r
- * Creates the proxy element if it does not yet exist\r
- * @method createFrame\r
- */\r
- createFrame: function() {\r
- var self = this;\r
- var body = document.body;\r
-\r
- if (!body || !body.firstChild) {\r
- setTimeout( function() { self.createFrame(); }, 50 );\r
- return;\r
- }\r
-\r
- var div = this.getDragEl();\r
-\r
- if (!div) {\r
- div = document.createElement("div");\r
- div.id = this.dragElId;\r
- var s = div.style;\r
-\r
- s.position = "absolute";\r
- s.visibility = "hidden";\r
- s.cursor = "move";\r
- s.border = "2px solid #aaa";\r
- s.zIndex = 999;\r
-\r
- // appendChild can blow up IE if invoked prior to the window load event\r
- // while rendering a table. It is possible there are other scenarios\r
- // that would cause this to happen as well.\r
- body.insertBefore(div, body.firstChild);\r
- }\r
- },\r
-\r
- /**\r
- * Initialization for the drag frame element. Must be called in the\r
- * constructor of all subclasses\r
- * @method initFrame\r
- */\r
- initFrame: function() {\r
- this.createFrame();\r
- },\r
-\r
- applyConfig: function() {\r
- Ext.dd.DDProxy.superclass.applyConfig.call(this);\r
-\r
- this.resizeFrame = (this.config.resizeFrame !== false);\r
- this.centerFrame = (this.config.centerFrame);\r
- this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);\r
- },\r
-\r
- /**\r
- * Resizes the drag frame to the dimensions of the clicked object, positions\r
- * it over the object, and finally displays it\r
- * @method showFrame\r
- * @param {int} iPageX X click position\r
- * @param {int} iPageY Y click position\r
- * @private\r
- */\r
- showFrame: function(iPageX, iPageY) {\r
- var el = this.getEl();\r
- var dragEl = this.getDragEl();\r
- var s = dragEl.style;\r
-\r
- this._resizeProxy();\r
-\r
- if (this.centerFrame) {\r
- this.setDelta( Math.round(parseInt(s.width, 10)/2),\r
- Math.round(parseInt(s.height, 10)/2) );\r
- }\r
-\r
- this.setDragElPos(iPageX, iPageY);\r
-\r
- Ext.fly(dragEl).show();\r
- },\r
-\r
- /**\r
- * The proxy is automatically resized to the dimensions of the linked\r
- * element when a drag is initiated, unless resizeFrame is set to false\r
- * @method _resizeProxy\r
- * @private\r
- */\r
- _resizeProxy: function() {\r
- if (this.resizeFrame) {\r
- var el = this.getEl();\r
- Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);\r
- }\r
- },\r
-\r
- // overrides Ext.dd.DragDrop\r
- b4MouseDown: function(e) {\r
- var x = e.getPageX();\r
- var y = e.getPageY();\r
- this.autoOffset(x, y);\r
- this.setDragElPos(x, y);\r
- },\r
-\r
- // overrides Ext.dd.DragDrop\r
- b4StartDrag: function(x, y) {\r
- // show the drag frame\r
- this.showFrame(x, y);\r
- },\r
-\r
- // overrides Ext.dd.DragDrop\r
- b4EndDrag: function(e) {\r
- Ext.fly(this.getDragEl()).hide();\r
- },\r
-\r
- // overrides Ext.dd.DragDrop\r
- // By default we try to move the element to the last location of the frame.\r
- // This is so that the default behavior mirrors that of Ext.dd.DD.\r
- endDrag: function(e) {\r
-\r
- var lel = this.getEl();\r
- var del = this.getDragEl();\r
-\r
- // Show the drag frame briefly so we can get its position\r
- del.style.visibility = "";\r
-\r
- this.beforeMove();\r
- // Hide the linked element before the move to get around a Safari\r
- // rendering bug.\r
- lel.style.visibility = "hidden";\r
- Ext.dd.DDM.moveToEl(lel, del);\r
- del.style.visibility = "hidden";\r
- lel.style.visibility = "";\r
-\r
- this.afterDrag();\r
- },\r
-\r
- beforeMove : function(){\r
-\r
- },\r
-\r
- afterDrag : function(){\r
-\r
- },\r
-\r
- toString: function() {\r
- return ("DDProxy " + this.id);\r
- }\r
-\r
-});\r
-/**\r
- * @class Ext.dd.DDTarget\r
- * A DragDrop implementation that does not move, but can be a drop\r
- * target. You would get the same result by simply omitting implementation\r
- * for the event callbacks, but this way we reduce the processing cost of the\r
- * event listener and the callbacks.\r
- * @extends Ext.dd.DragDrop\r
- * @constructor\r
- * @param {String} id the id of the element that is a drop target\r
- * @param {String} sGroup the group of related DragDrop objects\r
- * @param {object} config an object containing configurable attributes\r
- * Valid properties for DDTarget in addition to those in\r
- * DragDrop:\r
- * none\r
- */\r
-Ext.dd.DDTarget = function(id, sGroup, config) {\r
- if (id) {\r
- this.initTarget(id, sGroup, config);\r
- }\r
-};\r
-\r
-// Ext.dd.DDTarget.prototype = new Ext.dd.DragDrop();\r
-Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {\r
- toString: function() {\r
- return ("DDTarget " + this.id);\r
- }\r
-});\r