| 29 | | } |
| 30 | | }); |
| 31 | | |
| 32 | | $.ui.draggable = function(element, options) { |
| 33 | | //Initialize needed constants |
| 34 | | var self = this; |
| | 39 | |
| | 40 | //Position the node |
| | 41 | if(o.helper == 'original' && !(/(relative|absolute|fixed)/).test(this.element.css('position'))) |
| | 42 | this.element.css('position', 'relative'); |
| | 43 | |
| | 44 | }, |
| | 45 | start: function(e) { |
| | 46 | |
| | 47 | var o = this.options; |
| | 48 | if($.ui.ddmanager) $.ui.ddmanager.current = this; |
| | 49 | |
| | 50 | //Create and append the visible helper |
| | 51 | this.helper = typeof o.helper == 'function' ? $(o.helper.apply(this.element[0], [e])) : (o.helper == 'clone' ? this.element.clone() : this.element); |
| | 52 | if(!this.helper.parents('body').length) this.helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); |
| | 53 | |
| | 54 | /* |
| | 55 | * - Position generation - |
| | 56 | * This block generates everything position related - it's the core of draggables. |
| | 57 | */ |
| | 58 | |
| | 59 | this.cssPosition = this.helper.css("position"); //Store the helper's css position |
| | 60 | this.offset = this.element.offset(); //The element's absolute position on the page |
| | 61 | this.offset = { //Substract the margins from the element's absolute offset |
| | 62 | top: this.offset.top - parseInt(this.element.css("marginTop") || 0,10), |
| | 63 | left: this.offset.left - parseInt(this.element.css("marginLeft") || 0,10) |
| | 64 | }; |
| | 65 | |
| | 66 | this.offset.click = { //Where the click happened, relative to the element |
| | 67 | left: e.pageX - this.offset.left, |
| | 68 | top: e.pageY - this.offset.top |
| | 69 | }; |
| | 70 | |
| | 71 | var p = this.element.position(); //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helpers |
| | 72 | this.offset.relative = this.cssPosition == "relative" ? { |
| | 73 | top: p.top - parseInt(this.helper.css("top") || 0,10), |
| | 74 | left: p.left - parseInt(this.helper.css("left") || 0,10) |
| | 75 | } : { top: 0, left: 0 }; |
| | 76 | |
| | 77 | this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset(); //Get the offsetParent and cache its position |
| | 78 | this.offset.parent = { //Store its position plus border |
| | 79 | top: po.top + parseInt(this.offsetParent.css("borderTopWidth") || 0,10), |
| | 80 | left: po.left + parseInt(this.offsetParent.css("borderLeftWidth") || 0,10) |
| | 81 | }; |
| | 82 | |
| | 83 | this.originalPosition = this.generatePosition(e); //Generate the original position |
| | 84 | this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() };//Cache the helper size |
| | 85 | |
| | 86 | |
| | 87 | /* |
| | 88 | * - Position constraining - |
| | 89 | * Here we prepare position constraining like grid and containment. |
| | 90 | */ |
| | 91 | |
| | 92 | if(o.containment) { |
| | 93 | if(o.containment == 'parent') o.containment = this.helper[0].parentNode; |
| | 94 | if(o.containment == 'document') this.containment = [0,0,$(document).width(), ($(document).height() || document.body.parentNode.scrollHeight)]; |
| | 95 | if(!(/(document|window|parent)/).test(o.containment)) { |
| | 96 | var ce = $(o.containment)[0]; |
| | 97 | var co = $(o.containment).offset(); |
| | 98 | |
| | 99 | this.containment = [ |
| | 100 | co.left + parseInt($(ce).css("borderLeftWidth"),10) - this.offset.relative.left - this.offset.parent.left, |
| | 101 | co.top + parseInt($(ce).css("borderTopWidth"),10) - this.offset.relative.top - this.offset.parent.top, |
| | 102 | co.left+Math.max(ce.scrollWidth,ce.offsetWidth) - parseInt($(ce).css("borderRightWidth"),10) - this.offset.relative.left - this.offset.parent.left - this.helperProportions.width - parseInt(this.element.css("marginLeft") || 0,10) - parseInt(this.element.css("marginRight") || 0,10), |
| | 103 | co.top+Math.max(ce.scrollHeight,ce.offsetHeight) - parseInt($(ce).css("borderBottomWidth"),10) - this.offset.relative.top - this.offset.parent.top - this.helperProportions.height - parseInt(this.element.css("marginTop") || 0,10) - parseInt(this.element.css("marginTop") || 0,10) |
| | 104 | ]; |
| | 105 | } |
| | 106 | } |
| | 107 | |
| | 108 | |
| | 109 | //Call plugins and callbacks |
| | 110 | this.propagate("start", e); |
| | 111 | |
| | 112 | this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() };//Recache the helper size |
| | 113 | if ($.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, e); |
| | 114 | |
| | 115 | return false; |
| | 116 | |
| | 117 | }, |
| | 118 | generatePosition: function(e) { |
| | 119 | |
| | 120 | var o = this.options; |
| | 121 | var position = { |
| | 122 | top: ( |
| | 123 | e.pageY // The absolute mouse position |
| | 124 | - this.offset.click.top // Click offset (relative to the element) |
| | 125 | - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent |
| | 126 | - this.offset.parent.top // The offsetParent's offset without borders (offset + border) |
| | 127 | + (this.cssPosition == "fixed" ? 0 : this.offsetParent[0].scrollTop) // The offsetParent's scroll position, not if the element is fixed |
| | 128 | ), |
| | 129 | left: ( |
| | 130 | e.pageX // The absolute mouse position |
| | 131 | - this.offset.click.left // Click offset (relative to the element) |
| | 132 | - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent |
| | 133 | - this.offset.parent.left // The offsetParent's offset without borders (offset + border) |
| | 134 | + (this.cssPosition == "fixed" ? 0 : this.offsetParent[0].scrollLeft) // The offsetParent's scroll position, not if the element is fixed |
| | 135 | ) |
| | 136 | }; |
| | 137 | |
| | 138 | if(!this.originalPosition) return position; //If we are not dragging yet, we won't check for options |
| | 139 | |
| | 140 | |
| | 141 | /* |
| | 142 | * - Position constraining - |
| | 143 | * Constrain the position to a mix of grid, containment. |
| | 144 | */ |
| | 145 | if(this.containment) { |
| | 146 | if(position.left < this.containment[0]) position.left = this.containment[0]; |
| | 147 | if(position.top < this.containment[1]) position.top = this.containment[1]; |
| | 148 | if(position.left > this.containment[2]) position.left = this.containment[2]; |
| | 149 | if(position.top > this.containment[3]) position.top = this.containment[3]; |
| | 150 | } |
| | 151 | |
| | 152 | if(o.grid) { |
| | 153 | var top = this.originalPosition.top + Math.round((position.top - this.originalPosition.top) / o.grid[1]) * o.grid[1]; |
| | 154 | position.top = this.containment ? (!(top < this.containment[1] || top > this.containment[3]) ? top : (!(top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; |
| | 155 | |
| | 156 | var left = this.originalPosition.left + Math.round((position.left - this.originalPosition.left) / o.grid[0]) * o.grid[0]; |
| | 157 | position.left = this.containment ? (!(left < this.containment[0] || left > this.containment[2]) ? left : (!(left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; |
| | 158 | } |
| | 159 | |
| | 160 | return position; |
| | 161 | }, |
| | 162 | drag: function(e) { |
| | 163 | |
| | 164 | //Compute the helpers position |
| | 165 | this.position = this.generatePosition(e); |
| | 166 | |
| | 167 | //Call plugins and callbacks and use the resulting position if something is returned |
| | 168 | this.position = this.propagate("drag", e) || this.position; |
| | 169 | |
| | 170 | if(!this.options.axis || this.options.axis == "x") this.helper[0].style.left = this.position.left+'px'; |
| | 171 | if(!this.options.axis || this.options.axis == "y") this.helper[0].style.top = this.position.top+'px'; |
| | 172 | if($.ui.ddmanager) $.ui.ddmanager.drag(this, e); |
| | 173 | return false; |
| | 174 | |
| | 175 | }, |
| | 176 | stop: function(e) { |
| | 177 | |
| | 178 | //If we are using droppables, inform the manager about the drop |
| | 179 | if ($.ui.ddmanager && !this.options.dropBehaviour) |
| | 180 | $.ui.ddmanager.drop(this, e); |
| | 181 | |
| | 182 | if(this.options.revert) { |
| | 183 | var self = this; |
| | 184 | $(this.helper).animate(this.originalPosition, parseInt(this.options.revert, 10) || 500, function() { |
| | 185 | self.propagate("stop", e); |
| | 186 | self.clear(); |
| | 187 | }); |
| | 188 | } else { |
| | 189 | this.propagate("stop", e); |
| | 190 | this.clear(); |
| | 191 | } |
| | 192 | |
| | 193 | return false; |
| | 194 | |
| | 195 | }, |
| | 196 | clear: function() { |
| | 197 | if(this.options.helper != 'original') this.helper.remove(); |
| | 198 | if($.ui.ddmanager) $.ui.ddmanager.current = null; |
| | 199 | this.helper = null; |
| | 200 | }, |
| 36 | | this.element = $(element); |
| 37 | | |
| 38 | | $.data(element, "draggable", this); |
| 39 | | this.element.addClass("ui-draggable"); |
| 40 | | |
| 41 | | //Prepare the passed options |
| 42 | | this.options = $.extend({}, options); |
| 43 | | var o = this.options; |
| 44 | | $.extend(o, { |
| 45 | | helper: o.ghosting == true ? 'clone' : (o.helper || 'original'), |
| 46 | | handle : o.handle ? ($(o.handle, element)[0] ? $(o.handle, element) : this.element) : this.element, |
| 47 | | appendTo: o.appendTo || 'parent' |
| 48 | | }); |
| 49 | | |
| 50 | | $(element).bind("setData.draggable", function(event, key, value){ |
| 51 | | self.options[key] = value; |
| 52 | | }).bind("getData.draggable", function(event, key){ |
| 53 | | return self.options[key]; |
| 54 | | }); |
| 55 | | |
| 56 | | //Initialize mouse events for interaction |
| 57 | | $(o.handle).mouseInteraction({ |
| 58 | | executor: this, |
| 59 | | delay: o.delay, |
| 60 | | distance: o.distance || 1, |
| 61 | | dragPrevention: o.cancel || o.cancel === '' ? o.cancel.toLowerCase().split(',') : ['input','textarea','button','select','option'], |
| 62 | | start: this.start, |
| 63 | | stop: this.stop, |
| 64 | | drag: this.drag, |
| 65 | | condition: function(e) { return !(e.target.className.indexOf("ui-resizable-handle") != -1 || this.options.disabled); } |
| 66 | | }); |
| 67 | | |
| 68 | | //Position the node |
| 69 | | if(o.helper == 'original' && (this.element.css('position') == 'static' || this.element.css('position') == '')) |
| 70 | | this.element.css('position', 'relative'); |
| 71 | | |
| 72 | | //Prepare cursorAt |
| 73 | | if(o.cursorAt && o.cursorAt.constructor == Array) |
| 74 | | o.cursorAt = { left: o.cursorAt[0], top: o.cursorAt[1] }; |
| 75 | | |
| 76 | | }; |
| 77 | | |
| 78 | | $.extend($.ui.draggable.prototype, { |
| | 202 | // From now on bulk stuff - mainly helpers |
| 109 | | }, |
| 110 | | setContrains: function(minLeft,maxLeft,minTop,maxTop) { |
| 111 | | this.minLeft = minLeft; this.maxLeft = maxLeft; |
| 112 | | this.minTop = minTop; this.maxTop = maxTop; |
| 113 | | this.constrainsSet = true; |
| 114 | | }, |
| 115 | | checkConstrains: function() { |
| 116 | | if(!this.constrainsSet) return; |
| 117 | | if(this.position.left < this.minLeft) this.position.left = this.minLeft; |
| 118 | | if(this.position.left > this.maxLeft - this.helperProportions.width) this.position.left = this.maxLeft - this.helperProportions.width; |
| 119 | | if(this.position.top < this.minTop) this.position.top = this.minTop; |
| 120 | | if(this.position.top > this.maxTop - this.helperProportions.height) this.position.top = this.maxTop - this.helperProportions.height; |
| 121 | | }, |
| 122 | | recallOffset: function(e) { |
| 123 | | |
| 124 | | var elementPosition = { left: this.elementOffset.left - this.offsetParentOffset.left, top: this.elementOffset.top - this.offsetParentOffset.top }; |
| 125 | | var r = this.helper.css('position') == 'relative'; var o = this.options; |
| 126 | | |
| 127 | | //Generate the original position |
| 128 | | this.originalPosition = { |
| 129 | | left: (elementPosition.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft)), |
| 130 | | top: (elementPosition.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)) |
| 131 | | }; |
| 132 | | |
| 133 | | //Generate a flexible offset that will later be subtracted from e.pageX/Y |
| 134 | | this.offset = {left: this._pageX - this.originalPosition.left, top: this._pageY - this.originalPosition.top }; |
| 135 | | |
| 136 | | //Substract margins |
| 137 | | if(this.element[0] != this.helper[0]) { |
| 138 | | this.offset.left += parseInt(this.element.css('marginLeft'),10) || 0; |
| 139 | | this.offset.top += parseInt(this.element.css('marginTop'),10) || 0; |
| 140 | | } |
| 141 | | |
| 142 | | }, |
| 143 | | start: function(e) { |
| 144 | | var o = this.options; |
| 145 | | if($.ui.ddmanager) $.ui.ddmanager.current = this; |
| 146 | | |
| 147 | | //Create and append the visible helper |
| 148 | | this.helper = typeof o.helper == 'function' ? $(o.helper.apply(this.element[0], [e])) : (o.helper == 'clone' ? this.element.clone().appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)) : this.element); |
| 149 | | if(this.helper[0] != this.element[0]) this.helper.css('position', 'absolute'); |
| 150 | | if(!this.helper.parents('body').length) this.helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); |
| 151 | | |
| 152 | | |
| 153 | | //Find out the next positioned parent |
| 154 | | this.offsetParent = (function(cp) { |
| 155 | | while(cp) { |
| 156 | | if(cp.style && (/(absolute|relative|fixed)/).test($.css(cp,'position'))) return $(cp); |
| 157 | | cp = cp.parentNode ? cp.parentNode : null; |
| 158 | | }; return $("body"); |
| 159 | | })(this.helper[0].parentNode); |
| 160 | | |
| 161 | | //Prepare variables for position generation |
| 162 | | this.elementOffset = this.element.offset(); |
| 163 | | this.offsetParentOffset = this.offsetParent.offset(); |
| 164 | | var elementPosition = { left: this.elementOffset.left - this.offsetParentOffset.left, top: this.elementOffset.top - this.offsetParentOffset.top }; |
| 165 | | this._pageX = e.pageX; this._pageY = e.pageY; |
| 166 | | this.clickOffset = { left: e.pageX - this.elementOffset.left, top: e.pageY - this.elementOffset.top }; |
| 167 | | var r = this.helper.css('position') == 'relative'; |
| 168 | | |
| 169 | | //Generate the original position |
| 170 | | this.originalPosition = { |
| 171 | | left: (r ? parseInt(this.helper.css('left'),10) || 0 : elementPosition.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft)), |
| 172 | | top: (r ? parseInt(this.helper.css('top'),10) || 0 : elementPosition.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)) |
| 173 | | }; |
| 174 | | |
| 175 | | //If we have a fixed element, we must subtract the scroll offset again |
| 176 | | if(this.element.css('position') == 'fixed') { |
| 177 | | this.originalPosition.top -= this.offsetParent[0] == document.body ? $(document).scrollTop() : this.offsetParent[0].scrollTop; |
| 178 | | this.originalPosition.left -= this.offsetParent[0] == document.body ? $(document).scrollLeft() : this.offsetParent[0].scrollLeft; |
| 179 | | } |
| 180 | | |
| 181 | | //Generate a flexible offset that will later be subtracted from e.pageX/Y |
| 182 | | this.offset = {left: e.pageX - this.originalPosition.left, top: e.pageY - this.originalPosition.top }; |
| 183 | | |
| 184 | | //Substract margins |
| 185 | | if(this.element[0] != this.helper[0]) { |
| 186 | | this.offset.left += parseInt(this.element.css('marginLeft'),10) || 0; |
| 187 | | this.offset.top += parseInt(this.element.css('marginTop'),10) || 0; |
| 188 | | } |
| 189 | | |
| 190 | | //Call plugins and callbacks |
| 191 | | this.propagate("start", e); |
| 192 | | |
| 193 | | this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; |
| 194 | | if ($.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, e); |
| 195 | | |
| 196 | | //If we have something in cursorAt, we'll use it |
| 197 | | if(o.cursorAt) { |
| 198 | | if(o.cursorAt.top != undefined || o.cursorAt.bottom != undefined) { |
| 199 | | this.offset.top -= this.clickOffset.top - (o.cursorAt.top != undefined ? o.cursorAt.top : (this.helperProportions.height - o.cursorAt.bottom)); |
| 200 | | this.clickOffset.top = (o.cursorAt.top != undefined ? o.cursorAt.top : (this.helperProportions.height - o.cursorAt.bottom)); |
| 201 | | } |
| 202 | | if(o.cursorAt.left != undefined || o.cursorAt.right != undefined) { |
| 203 | | this.offset.left -= this.clickOffset.left - (o.cursorAt.left != undefined ? o.cursorAt.left : (this.helperProportions.width - o.cursorAt.right)); |
| 204 | | this.clickOffset.left = (o.cursorAt.left != undefined ? o.cursorAt.left : (this.helperProportions.width - o.cursorAt.right)); |
| 205 | | } |
| 206 | | } |
| 207 | | |
| 208 | | return false; |
| 209 | | |
| 210 | | }, |
| 211 | | clear: function() { |
| 212 | | if($.ui.ddmanager) $.ui.ddmanager.current = null; |
| 213 | | this.helper = null; |
| 214 | | }, |
| 215 | | stop: function(e) { |
| 216 | | |
| 217 | | //If we are using droppables, inform the manager about the drop |
| 218 | | if ($.ui.ddmanager && !this.options.dropBehaviour) |
| 219 | | $.ui.ddmanager.drop(this, e); |
| 220 | | |
| 221 | | //Call plugins and trigger callbacks |
| 222 | | this.propagate("stop", e); |
| 223 | | |
| 224 | | if(this.cancelHelperRemoval) return false; |
| 225 | | if(this.options.helper != 'original') this.helper.remove(); |
| 226 | | this.clear(); |
| 227 | | |
| 228 | | return false; |
| 229 | | }, |
| 230 | | drag: function(e) { |
| 231 | | |
| 232 | | //Compute the helpers position |
| 233 | | this.position = { top: e.pageY - this.offset.top, left: e.pageX - this.offset.left }; |
| 234 | | this.positionAbs = { left: e.pageX - this.clickOffset.left, top: e.pageY - this.clickOffset.top }; |
| 235 | | |
| 236 | | //Call plugins and callbacks |
| 237 | | this.checkConstrains(); |
| 238 | | this.position = this.propagate("drag", e) || this.position; |
| 239 | | this.checkConstrains(); |
| 240 | | |
| 241 | | $(this.helper).css({ left: this.position.left+'px', top: this.position.top+'px' }); // Stick the helper to the cursor |
| 242 | | if($.ui.ddmanager) $.ui.ddmanager.drag(this, e); |
| 243 | | return false; |
| 244 | | |
| 245 | | } |
| 246 | | }); |
| 247 | | |
| 248 | | /* |
| 249 | | * Draggable Extensions |
| 250 | | */ |
| 251 | | |
| | 224 | } |
| | 225 | }); |
| | 226 | |
| | 227 | $.ui.draggable.defaults = { |
| | 228 | helper: "original", |
| | 229 | appendTo: "parent", |
| | 230 | cancel: ['input','textarea','button','select','option'], |
| | 231 | distance: 1, |
| | 232 | delay: 0 |
| | 233 | }; |
| | 234 | |
| | 235 | |
| 295 | | } |
| 296 | | }); |
| 297 | | |
| 298 | | $.ui.plugin.add("draggable", "iframeFix", { |
| 299 | | start: function(e, ui) { |
| 300 | | |
| 301 | | var o = ui.options; |
| 302 | | if(ui.instance.slowMode) return; // Make clones on top of iframes (only if we are not in slowMode) |
| 303 | | |
| 304 | | if(o.iframeFix.constructor == Array) { |
| 305 | | for(var i=0;i<o.iframeFix.length;i++) { |
| 306 | | var co = $(o.iframeFix[i]).offset({ border: false }); |
| 307 | | $('<div class="DragDropIframeFix"" style="background: #fff;"></div>').css("width", $(o.iframeFix[i])[0].offsetWidth+"px").css("height", $(o.iframeFix[i])[0].offsetHeight+"px").css("position", "absolute").css("opacity", "0.001").css("z-index", "1000").css("top", co.top+"px").css("left", co.left+"px").appendTo("body"); |
| 308 | | } |
| 309 | | } else { |
| 310 | | $("iframe").each(function() { |
| 311 | | var co = $(this).offset({ border: false }); |
| 312 | | $('<div class="DragDropIframeFix" style="background: #fff;"></div>').css("width", this.offsetWidth+"px").css("height", this.offsetHeight+"px").css("position", "absolute").css("opacity", "0.001").css("z-index", "1000").css("top", co.top+"px").css("left", co.left+"px").appendTo("body"); |
| 313 | | }); |
| 314 | | } |
| 315 | | |
| 316 | | }, |
| 317 | | stop: function(e, ui) { |
| 318 | | if(ui.options.iframeFix) $("div.DragDropIframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers |
| 319 | | } |
| 320 | | }); |
| 321 | | |
| 322 | | $.ui.plugin.add("draggable", "containment", { |
| 323 | | start: function(e, ui) { |
| 324 | | |
| 325 | | var o = ui.options; |
| 326 | | var self = ui.instance; |
| 327 | | if((o.containment.left != undefined || o.containment.constructor == Array) && !o._containment) return; |
| 328 | | if(!o._containment) o._containment = o.containment; |
| 329 | | |
| 330 | | if(o._containment == 'parent') o._containment = this[0].parentNode; |
| 331 | | if(o._containment == 'document') { |
| 332 | | o.containment = [ |
| 333 | | 0, |
| 334 | | 0, |
| 335 | | $(document).width(), |
| 336 | | ($(document).height() || document.body.parentNode.scrollHeight) |
| 337 | | ]; |
| 338 | | } else { //I'm a node, so compute top/left/right/bottom |
| 339 | | |
| 340 | | var ce = $(o._containment)[0]; |
| 341 | | var co = $(o._containment).offset(); |
| 342 | | |
| 343 | | o.containment = [ |
| 344 | | co.left + parseInt($(ce).css("borderLeftWidth")), |
| 345 | | co.top + parseInt($(ce).css("borderTopWidth")), |
| 346 | | co.left+(ce.offsetWidth || ce.scrollWidth) - parseInt($(ce).css("borderRightWidth")), |
| 347 | | co.top+(ce.offsetHeight || ce.scrollHeight) - parseInt($(ce).css("borderBottomWidth")) |
| 348 | | ]; |
| 349 | | } |
| 350 | | |
| 351 | | var c = o.containment; |
| 352 | | ui.instance.setContrains( |
| 353 | | c[0] - (self.offset.left - self.clickOffset.left), //min left |
| 354 | | c[2] - (self.offset.left - self.clickOffset.left), //max left |
| 355 | | c[1] - (self.offset.top - self.clickOffset.top), //min top |
| 356 | | c[3] - (self.offset.top - self.clickOffset.top) //max top |
| 357 | | ); |
| 358 | | |
| 359 | | } |
| 360 | | }); |
| 361 | | |
| 362 | | $.ui.plugin.add("draggable", "grid", { |
| 363 | | drag: function(e, ui) { |
| 364 | | var o = ui.options; |
| 365 | | var newLeft = ui.instance.originalPosition.left + Math.round((e.pageX - ui.instance._pageX) / o.grid[0]) * o.grid[0]; |
| 366 | | var newTop = ui.instance.originalPosition.top + Math.round((e.pageY - ui.instance._pageY) / o.grid[1]) * o.grid[1]; |
| 367 | | |
| 368 | | ui.instance.position.left = newLeft; |
| 369 | | ui.instance.position.top = newTop; |
| 370 | | |
| 371 | | } |
| 372 | | }); |
| 373 | | |
| 374 | | $.ui.plugin.add("draggable", "axis", { |
| 375 | | drag: function(e, ui) { |
| 376 | | var o = ui.options; |
| 377 | | if(o.constraint) o.axis = o.constraint; //Legacy check |
| 378 | | switch (o.axis) { |
| 379 | | case 'x' : ui.instance.position.top = ui.instance.originalPosition.top; break; |
| 380 | | case 'y' : ui.instance.position.left = ui.instance.originalPosition.left; break; |
| 381 | | } |
| 382 | | } |
| 383 | | }); |
| 384 | | |
| 385 | | $.ui.plugin.add("draggable", "scroll", { |
| 386 | | start: function(e, ui) { |
| 387 | | var o = ui.options; |
| 388 | | o.scrollSensitivity = o.scrollSensitivity || 20; |
| 389 | | o.scrollSpeed = o.scrollSpeed || 20; |
| 390 | | |
| 391 | | ui.instance.overflowY = function(el) { |
| 392 | | do { if(/auto|scroll/.test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-y'))) return el; el = el.parent(); } while (el[0].parentNode); |
| 393 | | return $(document); |
| 394 | | }(this); |
| 395 | | ui.instance.overflowX = function(el) { |
| 396 | | do { if(/auto|scroll/.test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-x'))) return el; el = el.parent(); } while (el[0].parentNode); |
| 397 | | return $(document); |
| 398 | | }(this); |
| 399 | | }, |
| 400 | | drag: function(e, ui) { |
| 401 | | |
| 402 | | var o = ui.options; |
| 403 | | var i = ui.instance; |
| 404 | | |
| 405 | | if(i.overflowY[0] != document && i.overflowY[0].tagName != 'HTML') { |
| 406 | | if(i.overflowY[0].offsetHeight - (ui.position.top - i.overflowY[0].scrollTop + i.clickOffset.top) < o.scrollSensitivity) |
| 407 | | i.overflowY[0].scrollTop = i.overflowY[0].scrollTop + o.scrollSpeed; |
| 408 | | if((ui.position.top - i.overflowY[0].scrollTop + i.clickOffset.top) < o.scrollSensitivity) |
| 409 | | i.overflowY[0].scrollTop = i.overflowY[0].scrollTop - o.scrollSpeed; |
| 410 | | } else { |
| 411 | | //$(document.body).append('<p>'+(e.pageY - $(document).scrollTop())+'</p>'); |
| 412 | | if(e.pageY - $(document).scrollTop() < o.scrollSensitivity) |
| 413 | | $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); |
| 414 | | if($(window).height() - (e.pageY - $(document).scrollTop()) < o.scrollSensitivity) |
| 415 | | $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); |
| 416 | | } |
| 417 | | |
| 418 | | if(i.overflowX[0] != document && i.overflowX[0].tagName != 'HTML') { |
| 419 | | if(i.overflowX[0].offsetWidth - (ui.position.left - i.overflowX[0].scrollLeft + i.clickOffset.left) < o.scrollSensitivity) |
| 420 | | i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft + o.scrollSpeed; |
| 421 | | if((ui.position.top - i.overflowX[0].scrollLeft + i.clickOffset.left) < o.scrollSensitivity) |
| 422 | | i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft - o.scrollSpeed; |
| 423 | | } else { |
| 424 | | if(e.pageX - $(document).scrollLeft() < o.scrollSensitivity) |
| 425 | | $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); |
| 426 | | if($(window).width() - (e.pageX - $(document).scrollLeft()) < o.scrollSensitivity) |
| 427 | | $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); |
| 428 | | } |
| 429 | | |
| 430 | | ui.instance.recallOffset(e); |
| 431 | | |
| 432 | | } |
| 433 | | |