diff options
author | xue <> | 2007-03-26 00:27:59 +0000 |
---|---|---|
committer | xue <> | 2007-03-26 00:27:59 +0000 |
commit | 0f00e85e311955b3f84dde559da6b5a2ab5c3cda (patch) | |
tree | ccb93c4e2d056c69209307fcb680fc23a9c57370 /framework/Web/Javascripts/effects/dragdrop.js | |
parent | cbee2945d1858f7f256b44a3fbfe816dc0202f4d (diff) |
merge from 3.0 branch till 1769.
Diffstat (limited to 'framework/Web/Javascripts/effects/dragdrop.js')
-rw-r--r-- | framework/Web/Javascripts/effects/dragdrop.js | 187 |
1 files changed, 100 insertions, 87 deletions
diff --git a/framework/Web/Javascripts/effects/dragdrop.js b/framework/Web/Javascripts/effects/dragdrop.js index 1528eced..32c91bc3 100644 --- a/framework/Web/Javascripts/effects/dragdrop.js +++ b/framework/Web/Javascripts/effects/dragdrop.js @@ -1,9 +1,10 @@ -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) -// -// See scriptaculous.js for full license. +// script.aculo.us dragdrop.js v1.7.0, Fri Jan 19 19:16:36 CET 2007 -/*--------------------------------------------------------------------------*/ +// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// (c) 2005, 2006 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ if(typeof Effect == 'undefined') throw("dragdrop.js requires including script.aculo.us' effects.js library"); @@ -148,8 +149,16 @@ var Draggables = { }, activate: function(draggable) { - window.focus(); // allows keypress events if window isn't currently focused, fails for Safari - this.activeDraggable = draggable; + if(draggable.options.delay) { + this._timeout = setTimeout(function() { + Draggables._timeout = null; + window.focus(); + Draggables.activeDraggable = draggable; + }.bind(this), draggable.options.delay); + } else { + window.focus(); // allows keypress events if window isn't currently focused, fails for Safari + this.activeDraggable = draggable; + } }, deactivate: function() { @@ -163,10 +172,15 @@ var Draggables = { // the same coordinates, prevent needless redrawing (moz bug?) if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; this._lastPointer = pointer; + this.activeDraggable.updateDrag(event, pointer); }, endDrag: function(event) { + if(this._timeout) { + clearTimeout(this._timeout); + this._timeout = null; + } if(!this.activeDraggable) return; this._lastPointer = null; this.activeDraggable.endDrag(event); @@ -193,6 +207,7 @@ var Draggables = { this.observers.each( function(o) { if(o[eventName]) o[eventName](eventName, draggable, event); }); + if(draggable.options[eventName]) draggable.options[eventName](draggable, event); }, _cacheObserverCallbacks: function() { @@ -207,30 +222,25 @@ var Draggables = { /*--------------------------------------------------------------------------*/ var Draggable = Class.create(); -Draggable._revertCache = {}; Draggable._dragging = {}; Draggable.prototype = { initialize: function(element) { - var options = Object.extend({ + var defaults = { handle: false, - starteffect: function(element) { - element._opacity = Element.getOpacity(element); - Draggable._dragging[element] = true; - new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); - }, reverteffect: function(element, top_offset, left_offset) { var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; - Draggable._revertCache[element] = - new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur, - queue: {scope:'_draggable', position:'end'} - }); + new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur, + queue: {scope:'_draggable', position:'end'} + }); }, endeffect: function(element) { var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0; new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, queue: {scope:'_draggable', position:'end'}, - afterFinish: function(){ Draggable._dragging[element] = false } + afterFinish: function(){ + Draggable._dragging[element] = false + } }); }, zindex: 1000, @@ -238,20 +248,33 @@ Draggable.prototype = { scroll: false, scrollSensitivity: 20, scrollSpeed: 15, - snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] } - }, arguments[1] || {}); + snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] } + delay: 0 + }; + + if(!arguments[1] || typeof arguments[1].endeffect == 'undefined') + Object.extend(defaults, { + starteffect: function(element) { + element._opacity = Element.getOpacity(element); + Draggable._dragging[element] = true; + new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); + } + }); + + var options = Object.extend(defaults, arguments[1] || {}); this.element = $(element); - if(options.handle && (typeof options.handle == 'string')) { - var h = Element.childrenWithClassName(this.element, options.handle, true); - if(h.length>0) this.handle = h[0]; - } + if(options.handle && (typeof options.handle == 'string')) + this.handle = this.element.down('.'+options.handle, 0); + if(!this.handle) this.handle = $(options.handle); if(!this.handle) this.handle = this.element; - if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) + if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) { options.scroll = $(options.scroll); + this._isScrollChild = Element.childOf(this.element, options.scroll); + } Element.makePositioned(this.element); // fix IE @@ -277,23 +300,18 @@ Draggable.prototype = { }, initDrag: function(event) { - if(typeof Draggable._dragging[this.element] != undefined && + if(typeof Draggable._dragging[this.element] != 'undefined' && Draggable._dragging[this.element]) return; if(Event.isLeftClick(event)) { // abort on form elements, fixes a Firefox issue var src = Event.element(event); - if(src.tagName && ( - src.tagName=='INPUT' || - src.tagName=='SELECT' || - src.tagName=='OPTION' || - src.tagName=='BUTTON' || - src.tagName=='TEXTAREA')) return; + if((tag_name = src.tagName.toUpperCase()) && ( + tag_name=='INPUT' || + tag_name=='SELECT' || + tag_name=='OPTION' || + tag_name=='BUTTON' || + tag_name=='TEXTAREA')) return; - if(Draggable._revertCache[this.element]) { - Draggable._revertCache[this.element].cancel(); - Draggable._revertCache[this.element] = null; - } - var pointer = [Event.pointerX(event), Event.pointerY(event)]; var pos = Position.cumulativeOffset(this.element); this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); @@ -329,6 +347,7 @@ Draggable.prototype = { } Draggables.notify('onStart', this, event); + if(this.options.starteffect) this.options.starteffect(this.element); }, @@ -337,6 +356,7 @@ Draggable.prototype = { Position.prepare(); Droppables.show(pointer, this.element); Draggables.notify('onDrag', this, event); + this.draw(pointer); if(this.options.change) this.options.change(this); @@ -348,8 +368,8 @@ Draggable.prototype = { with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; } } else { p = Position.page(this.options.scroll); - p[0] += this.options.scroll.scrollLeft; - p[1] += this.options.scroll.scrollTop; + p[0] += this.options.scroll.scrollLeft + Position.deltaX; + p[1] += this.options.scroll.scrollTop + Position.deltaY; p.push(p[0]+this.options.scroll.offsetWidth); p.push(p[1]+this.options.scroll.offsetHeight); } @@ -395,7 +415,7 @@ Draggable.prototype = { if(this.options.endeffect) this.options.endeffect(this.element); - + Draggables.deactivate(this); Droppables.reset(); }, @@ -415,10 +435,15 @@ Draggable.prototype = { draw: function(point) { var pos = Position.cumulativeOffset(this.element); + if(this.options.ghosting) { + var r = Position.realOffset(this.element); + pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY; + } + var d = this.currentDelta(); pos[0] -= d[0]; pos[1] -= d[1]; - if(this.options.scroll && (this.options.scroll != window)) { + if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) { pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; } @@ -445,6 +470,7 @@ Draggable.prototype = { style.left = p[0] + "px"; if((!this.options.constraint) || (this.options.constraint=='vertical')) style.top = p[1] + "px"; + if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering }, @@ -482,14 +508,16 @@ Draggable.prototype = { Position.prepare(); Droppables.show(Draggables._lastPointer, this.element); Draggables.notify('onDrag', this); - Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer); - Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000; - Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000; - if (Draggables._lastScrollPointer[0] < 0) - Draggables._lastScrollPointer[0] = 0; - if (Draggables._lastScrollPointer[1] < 0) - Draggables._lastScrollPointer[1] = 0; - this.draw(Draggables._lastScrollPointer); + if (this._isScrollChild) { + Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer); + Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000; + Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000; + if (Draggables._lastScrollPointer[0] < 0) + Draggables._lastScrollPointer[0] = 0; + if (Draggables._lastScrollPointer[1] < 0) + Draggables._lastScrollPointer[1] = 0; + this.draw(Draggables._lastScrollPointer); + } if(this.options.change) this.options.change(this); }, @@ -541,10 +569,12 @@ SortableObserver.prototype = { } var Sortable = { + SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, + sortables: {}, _findRootElement: function(element) { - while (element.tagName != "BODY") { + while (element.tagName.toUpperCase() != "BODY") { if(element.id && Sortable.sortables[element.id]) return element; element = element.parentNode; } @@ -581,12 +611,13 @@ var Sortable = { containment: element, // also takes array of elements (or id's); or false handle: false, // or a CSS class only: false, + delay: 0, hoverclass: null, ghosting: false, scroll: false, scrollSensitivity: 20, scrollSpeed: 15, - format: /^[^_]*_(.*)$/, + format: this.SERIALIZE_RULE, onChange: Prototype.emptyFunction, onUpdate: Prototype.emptyFunction }, arguments[1] || {}); @@ -600,6 +631,7 @@ var Sortable = { scroll: options.scroll, scrollSpeed: options.scrollSpeed, scrollSensitivity: options.scrollSensitivity, + delay: options.delay, ghosting: options.ghosting, constraint: options.constraint, handle: options.handle }; @@ -628,7 +660,6 @@ var Sortable = { tree: options.tree, hoverclass: options.hoverclass, onHover: Sortable.onHover - //greedy: !options.dropOnEmpty } var options_for_tree = { @@ -653,7 +684,7 @@ var Sortable = { (this.findElements(element, options) || []).each( function(e) { // handles are per-draggable var handle = options.handle ? - Element.childrenWithClassName(e, options.handle)[0] : e; + $(e).down('.'+options.handle,0) : e; options.draggables.push( new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); Droppables.add(e, options_for_droppable); @@ -751,7 +782,7 @@ var Sortable = { }, unmark: function() { - if(Sortable._marker) Element.hide(Sortable._marker); + if(Sortable._marker) Sortable._marker.hide(); }, mark: function(dropon, position) { @@ -760,23 +791,21 @@ var Sortable = { if(sortable && !sortable.ghosting) return; if(!Sortable._marker) { - Sortable._marker = $('dropmarker') || document.createElement('DIV'); - Element.hide(Sortable._marker); - Element.addClassName(Sortable._marker, 'dropmarker'); - Sortable._marker.style.position = 'absolute'; + Sortable._marker = + ($('dropmarker') || Element.extend(document.createElement('DIV'))). + hide().addClassName('dropmarker').setStyle({position:'absolute'}); document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); } var offsets = Position.cumulativeOffset(dropon); - Sortable._marker.style.left = offsets[0] + 'px'; - Sortable._marker.style.top = offsets[1] + 'px'; + Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'}); if(position=='after') if(sortable.overlap == 'horizontal') - Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px'; + Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'}); else - Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px'; + Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'}); - Element.show(Sortable._marker); + Sortable._marker.show(); }, _tree: function(element, options, parent) { @@ -791,9 +820,9 @@ var Sortable = { id: encodeURIComponent(match ? match[1] : null), element: element, parent: parent, - children: new Array, + children: [], position: parent.children.length, - container: Sortable._findChildrenElement(children[i], options.treeTag.toUpperCase()) + container: $(children[i]).down(options.treeTag) } /* Get the element containing the children and recurse over it */ @@ -806,17 +835,6 @@ var Sortable = { return parent; }, - /* Finds the first element of the given tag type within a parent element. - Used for finding the first LI[ST] within a L[IST]I[TEM].*/ - _findChildrenElement: function (element, containerTag) { - if (element && element.hasChildNodes) - for (var i = 0; i < element.childNodes.length; ++i) - if (element.childNodes[i].tagName == containerTag) - return element.childNodes[i]; - - return null; - }, - tree: function(element) { element = $(element); var sortableOptions = this.options(element); @@ -831,12 +849,12 @@ var Sortable = { var root = { id: null, parent: null, - children: new Array, + children: [], container: element, position: 0 } - return Sortable._tree (element, options, root); + return Sortable._tree(element, options, root); }, /* Construct a [i] index for a particular node */ @@ -896,12 +914,10 @@ var Sortable = { } } -/* Returns true if child is contained within element */ +// Returns true if child is contained within element Element.isParent = function(child, element) { if (!child.parentNode || child == element) return false; - if (child.parentNode == element) return true; - return Element.isParent(child.parentNode, element); } @@ -924,8 +940,5 @@ Element.findChildren = function(element, only, recursive, tagName) { } Element.offsetSize = function (element, type) { - if (type == 'vertical' || type == 'height') - return element.offsetHeight; - else - return element.offsetWidth; -}
\ No newline at end of file + return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')]; +} |