1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 2005, 2006, 2007, 2009, 2010, 2012, 2013, 2014, 2016 Synacor, Inc. 5 * 6 * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: https://www.zimbra.com/license 9 * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15 10 * have been added to cover use of software over a computer network and provide for limited attribution 11 * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B. 12 * 13 * Software distributed under the License is distributed on an "AS IS" basis, 14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. 15 * See the License for the specific language governing rights and limitations under the License. 16 * The Original Code is Zimbra Open Source Web Client. 17 * The Initial Developer of the Original Code is Zimbra, Inc. All rights to the Original Code were 18 * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015. 19 * 20 * All portions of the code are Copyright (C) 2005, 2006, 2007, 2009, 2010, 2012, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 24 25 /** 26 * @class 27 * This static class enables entities (for example, {@link DwtDialog}s) to be dragged around within 28 * an application window. The code is basically the same as in dom-drag.js from www.youngpup.net 29 * 30 * @author Ross Dargahi 31 * 32 * @private 33 */ 34 DwtDraggable = function() { 35 } 36 37 DwtDraggable.dragEl = null; 38 39 /** 40 * Initializes dragging for <code>dragEl</code> 41 * 42 * @param {HTMLElement} dragEl the element being dragged, can also be a handle e.g. the 43 * title bar in a dialog 44 * @param {HTMLElement} [rootEl] the actual element that will be moved. This will be a 45 * parent element of <i>dragEl</i> 46 * @param {number} [minX] the minimum x coord to which we can drag 47 * @param {number} [maxX] the maximum x coord to which we can drag 48 * @param {number} [minY] the minimum y coord to which we can drag 49 * @param {number} [maxY] the maximum x coord to which we can drag 50 * @param {AjxCallback} dragStartCB the callback that is called when dragging is started 51 * @param {AjxCallback}dragCB the callback that is called when dragging 52 * @param {AjxCallback}dragEndCB the callback that is called when dragging is ended 53 * @param {boolean} [swapHorizRef] if <code>true</code>, then mouse motion to the right will move element left 54 * @param {boolean} [swapVertRef] if <code>true</code>, then mouse motion to the bottom will move element up 55 * @param {function} [fXMapper] the function that overrides this classes x coordinate transformations 56 * @param {function} [fYMapper] the function that overrides this classes y coordinate transformations 57 * 58 */ 59 DwtDraggable.init = 60 function(dragEl, rootEl, minX, maxX, minY, maxY, dragStartCB, dragCB, dragEndCB, 61 swapHorizRef, swapVertRef, fXMapper, fYMapper) { 62 dragEl.onmousedown = DwtDraggable.__start; 63 64 dragEl.__hMode = swapHorizRef ? false : true; 65 dragEl.__vMode = swapVertRef ? false : true; 66 67 dragEl.__root = (rootEl && rootEl != null) ? rootEl : dragEl ; 68 69 if (dragEl.__hMode && isNaN(parseInt(dragEl.__root.style.left))) 70 dragEl.__root.style.left = "0px"; 71 if (dragEl.__vMode && isNaN(parseInt(dragEl.__root.style.top))) 72 dragEl.__root.style.top = "0px"; 73 74 if (!dragEl.__hMode && isNaN(parseInt(dragEl.__root.style.right))) 75 dragEl.__root.style.right = "0px"; 76 if (!dragEl.__vMode && isNaN(parseInt(dragEl.__root.style.bottom))) 77 dragEl.__root.style.bottom = "0px"; 78 79 dragEl.__minX = (typeof minX != 'undefined') ? minX : null; 80 dragEl.__minY = (typeof minY != 'undefined') ? minY : null; 81 dragEl.__maxX = (typeof maxX != 'undefined') ? maxX : null; 82 dragEl.__maxY = (typeof maxY != 'undefined') ? maxY : null; 83 84 dragEl.__xMapper = fXMapper ? fXMapper : null; 85 dragEl.__yMapper = fYMapper ? fYMapper : null; 86 87 dragEl.__root.onDragStart = dragStartCB 88 dragEl.__root.onDragEnd = dragEndCB 89 dragEl.__root.onDrag = dragCB; 90 }; 91 92 /** 93 * Sets the minimum and maximum drag boundries 94 * 95 * @param {HTMLElement} dragEl Element being dragged, can also be a handle e.g. the 96 * title bar in a dialog 97 * @param {number} minX the minimum x coordinate 98 * @param {number} maxX the maximum x coordinate 99 * @param {number} minY the minimum y coordinate 100 * @param {number} maxY the maximum y coordinate 101 */ 102 DwtDraggable.setDragBoundaries = 103 function (dragEl ,minX, maxX, minY, maxY) { 104 if (dragEl != null) { 105 if (minX != null) dragEl.__minX = minX; 106 if (maxX != null) dragEl.__maxX = maxX; 107 if (minY != null) dragEl.__minY = minY; 108 if (maxY != null) dragEl.__maxY = maxY; 109 } 110 }; 111 112 /** @private */ 113 DwtDraggable.__start = 114 function(e) { 115 var dragEl = DwtDraggable.dragEl = this; 116 e = DwtDraggable.__fixE(e); 117 var x = parseInt(dragEl.__hMode ? dragEl.__root.style.left : dragEl.__root.style.right ); 118 var y = parseInt(dragEl.__vMode ? dragEl.__root.style.top : dragEl.__root.style.bottom); 119 if (dragEl.__root.onDragStart) 120 dragEl.__root.onDragStart.run([x, y]); 121 122 dragEl.__lastMouseX = e.clientX; 123 dragEl.__lastMouseY = e.clientY; 124 125 if (dragEl.__hMode) { 126 if (dragEl.__minX != null) 127 dragEl.__minMouseX = e.clientX - x + dragEl.__minX; 128 if (dragEl.__maxX != null) 129 dragEl.__maxMouseX = dragEl.__minMouseX + dragEl.__maxX - dragEl.__minX; 130 } else { 131 if (dragEl.__minX != null) 132 dragEl.__maxMouseX = -dragEl.__minX + e.clientX + x; 133 if (dragEl.__maxX != null) 134 dragEl.__minMouseX = -dragEl.__maxX + e.clientX + x; 135 } 136 137 if (dragEl.__vMode) { 138 if (dragEl.__minY != null) 139 dragEl.__minMouseY = e.clientY - y + dragEl.__minY; 140 if (dragEl.__maxY != null) 141 dragEl.__maxMouseY = dragEl.__minMouseY + dragEl.__maxY - dragEl.__minY; 142 } else { 143 if (dragEl.__minY != null) 144 dragEl.__maxMouseY = -dragEl.__minY + e.clientY + y; 145 if (dragEl.__maxY != null) 146 dragEl.__minMouseY = -dragEl.__maxY + e.clientY + y; 147 } 148 149 document.onmousemove = DwtDraggable.__drag; 150 document.onmouseup = DwtDraggable.__end; 151 152 return false; 153 }; 154 155 /** @private */ 156 DwtDraggable.__drag = 157 function(e) { 158 e = DwtDraggable.__fixE(e); 159 var dragEl = DwtDraggable.dragEl; 160 161 var ey = e.clientY; 162 var ex = e.clientX; 163 var x = parseInt(dragEl.__hMode ? dragEl.__root.style.left : dragEl.__root.style.right ); 164 var y = parseInt(dragEl.__vMode ? dragEl.__root.style.top : dragEl.__root.style.bottom); 165 var nx, ny; 166 167 if (!dragEl.__xMapper) { 168 if (dragEl.__minX != null) 169 ex = dragEl.__hMode ? Math.max(ex, dragEl.__minMouseX) : Math.min(ex, dragEl.__maxMouseX); 170 if (dragEl.__maxX != null) 171 ex = dragEl.__hMode ? Math.min(ex, dragEl.__maxMouseX) : Math.max(ex, dragEl.__minMouseX); 172 nx = x + ((ex - dragEl.__lastMouseX) * (dragEl.__hMode ? 1 : -1)); 173 } else { 174 nx = dragEl.__xMapper(x, ex); 175 } 176 177 if (!dragEl.__yMapper) { 178 if (dragEl.__minY != null) 179 ey = dragEl.__vMode ? Math.max(ey, dragEl.__minMouseY) : Math.min(ey, dragEl.__maxMouseY); 180 if (dragEl.__maxY != null) 181 ey = dragEl.__vMode ? Math.min(ey, dragEl.__maxMouseY) : Math.max(ey, dragEl.__minMouseY); 182 ny = y + ((ey - dragEl.__lastMouseY) * (dragEl.__vMode ? 1 : -1)); 183 } else { 184 ny = dragEl.__yMapper(y, ey); 185 } 186 187 DwtDraggable.dragEl.__root.style[dragEl.__hMode ? "left" : "right"] = nx + "px"; 188 DwtDraggable.dragEl.__root.style[dragEl.__vMode ? "top" : "bottom"] = ny + "px"; 189 DwtDraggable.dragEl.__lastMouseX = ex; 190 DwtDraggable.dragEl.__lastMouseY = ey; 191 192 if (DwtDraggable.dragEl.__root.onDrag) 193 DwtDraggable.dragEl.__root.onDrag.run([nx, ny]); 194 195 return false; 196 }; 197 198 /** @private */ 199 DwtDraggable.__end = 200 function() { 201 document.onmousemove = null; 202 document.onmouseup = null; 203 if (DwtDraggable.dragEl.__root.onDragEnd) 204 DwtDraggable.dragEl.__root.onDragEnd.run([parseInt(DwtDraggable.dragEl.__root.style[DwtDraggable.dragEl.__hMode ? "left" : "right"]), 205 parseInt(DwtDraggable.dragEl.__root.style[DwtDraggable.dragEl.__vMode ? "top" : "bottom"])]); 206 DwtDraggable.dragEl = null; 207 }; 208 209 /** @private */ 210 DwtDraggable.__fixE = 211 function(e) { 212 if (typeof e == 'undefined') 213 e = window.event; 214 if (!AjxEnv.isWebKitBased) { 215 if (typeof e.layerX == 'undefined') 216 e.layerX = e.offsetX; 217 if (typeof e.layerY == 'undefined') 218 e.layerY = e.offsetY; 219 } 220 return e; 221 }; 222