summaryrefslogtreecommitdiffstats
path: root/comiccontrol/draganddrop
diff options
context:
space:
mode:
Diffstat (limited to 'comiccontrol/draganddrop')
-rw-r--r--comiccontrol/draganddrop/cookies.js34
-rw-r--r--comiccontrol/draganddrop/coordinates.js154
-rw-r--r--comiccontrol/draganddrop/core.js170
-rw-r--r--comiccontrol/draganddrop/css.js17
-rw-r--r--comiccontrol/draganddrop/drag.js235
-rw-r--r--comiccontrol/draganddrop/dragsort.js87
-rw-r--r--comiccontrol/draganddrop/events.js43
7 files changed, 740 insertions, 0 deletions
diff --git a/comiccontrol/draganddrop/cookies.js b/comiccontrol/draganddrop/cookies.js
new file mode 100644
index 0000000..6e097b2
--- /dev/null
+++ b/comiccontrol/draganddrop/cookies.js
@@ -0,0 +1,34 @@
+/* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt)
+
+based on http://www.quirksmode.org/js/cookies.html
+*/
+
+ToolMan._cookieOven = {
+
+ set : function(name, value, expirationInDays) {
+ if (expirationInDays) {
+ var date = new Date()
+ date.setTime(date.getTime() + (expirationInDays * 24 * 60 * 60 * 1000))
+ var expires = "; expires=" + date.toGMTString()
+ } else {
+ var expires = ""
+ }
+ document.cookie = name + "=" + value + expires + "; path=/"
+ },
+
+ get : function(name) {
+ var namePattern = name + "="
+ var cookies = document.cookie.split(';')
+ for(var i = 0, n = cookies.length; i < n; i++) {
+ var c = cookies[i]
+ while (c.charAt(0) == ' ') c = c.substring(1, c.length)
+ if (c.indexOf(namePattern) == 0)
+ return c.substring(namePattern.length, c.length)
+ }
+ return null
+ },
+
+ eraseCookie : function(name) {
+ createCookie(name, "", -1)
+ }
+}
diff --git a/comiccontrol/draganddrop/coordinates.js b/comiccontrol/draganddrop/coordinates.js
new file mode 100644
index 0000000..15e8d3e
--- /dev/null
+++ b/comiccontrol/draganddrop/coordinates.js
@@ -0,0 +1,154 @@
+/* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt) */
+
+/* FIXME: assumes position styles are specified in 'px' */
+
+ToolMan._coordinatesFactory = {
+
+ create : function(x, y) {
+ // FIXME: Safari won't parse 'throw' and aborts trying to do anything with this file
+ //if (isNaN(x) || isNaN(y)) throw "invalid x,y: " + x + "," + y
+ return new _ToolManCoordinate(this, x, y)
+ },
+
+ origin : function() {
+ return this.create(0, 0)
+ },
+
+ /*
+ * FIXME: Safari 1.2, returns (0,0) on absolutely positioned elements
+ */
+ topLeftPosition : function(element) {
+ var left = parseInt(ToolMan.css().readStyle(element, "left"))
+ var left = isNaN(left) ? 0 : left
+ var top = parseInt(ToolMan.css().readStyle(element, "top"))
+ var top = isNaN(top) ? 0 : top
+
+ return this.create(left, top)
+ },
+
+ bottomRightPosition : function(element) {
+ return this.topLeftPosition(element).plus(this._size(element))
+ },
+
+ topLeftOffset : function(element) {
+ var offset = this._offset(element)
+
+ var parent = element.offsetParent
+ while (parent) {
+ offset = offset.plus(this._offset(parent))
+ parent = parent.offsetParent
+ }
+ return offset
+ },
+
+ bottomRightOffset : function(element) {
+ return this.topLeftOffset(element).plus(
+ this.create(element.offsetWidth, element.offsetHeight))
+ },
+
+ scrollOffset : function() {
+ if (window.pageXOffset) {
+ return this.create(window.pageXOffset, window.pageYOffset)
+ } else if (document.documentElement) {
+ return this.create(
+ document.body.scrollLeft + document.documentElement.scrollLeft,
+ document.body.scrollTop + document.documentElement.scrollTop)
+ } else if (document.body.scrollLeft >= 0) {
+ return this.create(document.body.scrollLeft, document.body.scrollTop)
+ } else {
+ return this.create(0, 0)
+ }
+ },
+
+ clientSize : function() {
+ if (window.innerHeight >= 0) {
+ return this.create(window.innerWidth, window.innerHeight)
+ } else if (document.documentElement) {
+ return this.create(document.documentElement.clientWidth,
+ document.documentElement.clientHeight)
+ } else if (document.body.clientHeight >= 0) {
+ return this.create(document.body.clientWidth,
+ document.body.clientHeight)
+ } else {
+ return this.create(0, 0)
+ }
+ },
+
+ /**
+ * mouse coordinate relative to the window (technically the
+ * browser client area) i.e. the part showing your page
+ *
+ * NOTE: in Safari the coordinate is relative to the document
+ */
+ mousePosition : function(event) {
+ event = ToolMan.events().fix(event)
+ return this.create(event.clientX, event.clientY)
+ },
+
+ /**
+ * mouse coordinate relative to the document
+ */
+ mouseOffset : function(event) {
+ event = ToolMan.events().fix(event)
+ if (event.pageX >= 0 || event.pageX < 0) {
+ return this.create(event.pageX, event.pageY)
+ } else if (event.clientX >= 0 || event.clientX < 0) {
+ return this.mousePosition(event).plus(this.scrollOffset())
+ }
+ },
+
+ _size : function(element) {
+ /* TODO: move to a Dimension class */
+ return this.create(element.offsetWidth, element.offsetHeight)
+ },
+
+ _offset : function(element) {
+ return this.create(element.offsetLeft, element.offsetTop)
+ }
+}
+
+function _ToolManCoordinate(factory, x, y) {
+ this.factory = factory
+ this.x = isNaN(x) ? 0 : x
+ this.y = isNaN(y) ? 0 : y
+}
+
+_ToolManCoordinate.prototype = {
+ toString : function() {
+ return "(" + this.x + "," + this.y + ")"
+ },
+
+ plus : function(that) {
+ return this.factory.create(this.x + that.x, this.y + that.y)
+ },
+
+ minus : function(that) {
+ return this.factory.create(this.x - that.x, this.y - that.y)
+ },
+
+ min : function(that) {
+ return this.factory.create(
+ Math.min(this.x , that.x), Math.min(this.y , that.y))
+ },
+
+ max : function(that) {
+ return this.factory.create(
+ Math.max(this.x , that.x), Math.max(this.y , that.y))
+ },
+
+ constrainTo : function (one, two) {
+ var min = one.min(two)
+ var max = one.max(two)
+
+ return this.max(min).min(max)
+ },
+
+ distance : function (that) {
+ return Math.sqrt(Math.pow(this.x - that.x, 2) + Math.pow(this.y - that.y, 2))
+ },
+
+ reposition : function(element) {
+ element.style["top"] = this.y + "px"
+ element.style["left"] = this.x + "px"
+ }
+}
diff --git a/comiccontrol/draganddrop/core.js b/comiccontrol/draganddrop/core.js
new file mode 100644
index 0000000..494b9ec
--- /dev/null
+++ b/comiccontrol/draganddrop/core.js
@@ -0,0 +1,170 @@
+/*
+Copyright (c) 2005 Tim Taylor Consulting <http://tool-man.org/>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+*/
+
+var ToolMan = {
+ events : function() {
+ if (!ToolMan._eventsFactory) throw "ToolMan Events module isn't loaded";
+ return ToolMan._eventsFactory
+ },
+
+ css : function() {
+ if (!ToolMan._cssFactory) throw "ToolMan CSS module isn't loaded";
+ return ToolMan._cssFactory
+ },
+
+ coordinates : function() {
+ if (!ToolMan._coordinatesFactory) throw "ToolMan Coordinates module isn't loaded";
+ return ToolMan._coordinatesFactory
+ },
+
+ drag : function() {
+ if (!ToolMan._dragFactory) throw "ToolMan Drag module isn't loaded";
+ return ToolMan._dragFactory
+ },
+
+ dragsort : function() {
+ if (!ToolMan._dragsortFactory) throw "ToolMan DragSort module isn't loaded";
+ return ToolMan._dragsortFactory
+ },
+
+ helpers : function() {
+ return ToolMan._helpers
+ },
+
+ cookies : function() {
+ if (!ToolMan._cookieOven) throw "ToolMan Cookie module isn't loaded";
+ return ToolMan._cookieOven
+ },
+
+ junkdrawer : function() {
+ return ToolMan._junkdrawer
+ }
+
+}
+
+ToolMan._helpers = {
+ map : function(array, func) {
+ for (var i = 0, n = array.length; i < n; i++) func(array[i])
+ },
+
+ nextItem : function(item, nodeName) {
+ if (item == null) return
+ var next = item.nextSibling
+ while (next != null) {
+ if (next.nodeName == nodeName) return next
+ next = next.nextSibling
+ }
+ return null
+ },
+
+ previousItem : function(item, nodeName) {
+ var previous = item.previousSibling
+ while (previous != null) {
+ if (previous.nodeName == nodeName) return previous
+ previous = previous.previousSibling
+ }
+ return null
+ },
+
+ moveBefore : function(item1, item2) {
+ var parent = item1.parentNode
+ parent.removeChild(item1)
+ parent.insertBefore(item1, item2)
+ },
+
+ moveAfter : function(item1, item2) {
+ var parent = item1.parentNode
+ parent.removeChild(item1)
+ parent.insertBefore(item1, item2 ? item2.nextSibling : null)
+ }
+}
+
+/**
+ * scripts without a proper home
+ *
+ * stuff here is subject to change unapologetically and without warning
+ */
+ToolMan._junkdrawer = {
+ serializeList : function(list) {
+ var items = list.getElementsByTagName("li")
+ var array = new Array()
+ for (var i = 0, n = items.length; i < n; i++) {
+ var item = items[i]
+
+ array.push(item.id)
+ }
+ return array;
+ },
+
+ inspectListOrder : function(id) {
+ alert(ToolMan.junkdrawer().serializeList(document.getElementById(id)))
+ },
+
+ restoreListOrder : function(listID) {
+ var list = document.getElementById(listID)
+ if (list == null) return
+
+ var cookie = ToolMan.cookies().get("list-" + listID)
+ if (!cookie) return;
+
+ var IDs = cookie.split('|')
+ var items = ToolMan.junkdrawer()._itemsByID(list)
+
+ for (var i = 0, n = IDs.length; i < n; i++) {
+ var itemID = IDs[i]
+ if (itemID in items) {
+ var item = items[itemID]
+ list.removeChild(item)
+ list.insertBefore(item, null)
+ }
+ }
+ },
+
+ _identifier : function(item) {
+ var trim = ToolMan.junkdrawer().trim
+ var identifier
+
+ identifier = trim(item.getAttribute("id"))
+ if (identifier != null && identifier.length > 0) return identifier;
+
+ identifier = trim(item.getAttribute("itemID"))
+ if (identifier != null && identifier.length > 0) return identifier;
+
+ // FIXME: strip out special chars or make this an MD5 hash or something
+ return trim(item.innerHTML)
+ },
+
+ _itemsByID : function(list) {
+ var array = new Array()
+ var items = list.getElementsByTagName('li')
+ for (var i = 0, n = items.length; i < n; i++) {
+ var item = items[i]
+ array[ToolMan.junkdrawer()._identifier(item)] = item
+ }
+ return array
+ },
+
+ trim : function(text) {
+ if (text == null) return null
+ return text.replace(/^(\s+)?(.*\S)(\s+)?$/, '$2')
+ }
+}
diff --git a/comiccontrol/draganddrop/css.js b/comiccontrol/draganddrop/css.js
new file mode 100644
index 0000000..9ffe0a0
--- /dev/null
+++ b/comiccontrol/draganddrop/css.js
@@ -0,0 +1,17 @@
+/* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt) */
+
+// TODO: write unit tests
+ToolMan._cssFactory = {
+ readStyle : function(element, property) {
+ if (element.style[property]) {
+ return element.style[property]
+ } else if (element.currentStyle) {
+ return element.currentStyle[property]
+ } else if (document.defaultView && document.defaultView.getComputedStyle) {
+ var style = document.defaultView.getComputedStyle(element, null)
+ return style.getPropertyValue(property)
+ } else {
+ return null
+ }
+ }
+}
diff --git a/comiccontrol/draganddrop/drag.js b/comiccontrol/draganddrop/drag.js
new file mode 100644
index 0000000..861c7ea
--- /dev/null
+++ b/comiccontrol/draganddrop/drag.js
@@ -0,0 +1,235 @@
+/* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt) */
+
+ToolMan._dragFactory = {
+ createSimpleGroup : function(element, handle) {
+ handle = handle ? handle : element
+ var group = this.createGroup(element)
+ group.setHandle(handle)
+ group.transparentDrag()
+ group.onTopWhileDragging()
+ return group
+ },
+
+ createGroup : function(element) {
+ var group = new _ToolManDragGroup(this, element)
+
+ var position = ToolMan.css().readStyle(element, 'position')
+ if (position == 'static') {
+ element.style["position"] = 'relative'
+ } else if (position == 'absolute') {
+ /* for Safari 1.2 */
+ ToolMan.coordinates().topLeftOffset(element).reposition(element)
+ }
+
+ // TODO: only if ToolMan.isDebugging()
+ group.register('draginit', this._showDragEventStatus)
+ group.register('dragmove', this._showDragEventStatus)
+ group.register('dragend', this._showDragEventStatus)
+
+ return group
+ },
+
+ _showDragEventStatus : function(dragEvent) {
+ window.status = dragEvent.toString()
+ },
+
+ constraints : function() {
+ return this._constraintFactory
+ },
+
+ _createEvent : function(type, event, group) {
+ return new _ToolManDragEvent(type, event, group)
+ }
+}
+
+function _ToolManDragGroup(factory, element) {
+ this.factory = factory
+ this.element = element
+ this._handle = null
+ this._thresholdDistance = 0
+ this._transforms = new Array()
+ // TODO: refactor into a helper object, move into events.js
+ this._listeners = new Array()
+ this._listeners['draginit'] = new Array()
+ this._listeners['dragstart'] = new Array()
+ this._listeners['dragmove'] = new Array()
+ this._listeners['dragend'] = new Array()
+}
+
+_ToolManDragGroup.prototype = {
+ /*
+ * TODO:
+ * - unregister(type, func)
+ * - move custom event listener stuff into Event library
+ * - keyboard nudging of "selected" group
+ */
+
+ setHandle : function(handle) {
+ var events = ToolMan.events()
+
+ handle.toolManDragGroup = this
+ events.register(handle, 'mousedown', this._dragInit)
+ handle.onmousedown = function() { return false }
+
+ if (this.element != handle)
+ events.unregister(this.element, 'mousedown', this._dragInit)
+ },
+
+ register : function(type, func) {
+ this._listeners[type].push(func)
+ },
+
+ addTransform : function(transformFunc) {
+ this._transforms.push(transformFunc)
+ },
+
+ verticalOnly : function() {
+ this.addTransform(this.factory.constraints().vertical())
+ },
+
+ horizontalOnly : function() {
+ this.addTransform(this.factory.constraints().horizontal())
+ },
+
+ setThreshold : function(thresholdDistance) {
+ this._thresholdDistance = thresholdDistance
+ },
+
+ transparentDrag : function(opacity) {
+ var opacity = typeof(opacity) != "undefined" ? opacity : 0.75;
+ var originalOpacity = ToolMan.css().readStyle(this.element, "opacity")
+
+ this.register('dragstart', function(dragEvent) {
+ var element = dragEvent.group.element
+ element.style.opacity = opacity
+ element.style.filter = 'alpha(opacity=' + (opacity * 100) + ')'
+ })
+ this.register('dragend', function(dragEvent) {
+ var element = dragEvent.group.element
+ element.style.opacity = originalOpacity
+ element.style.filter = 'alpha(opacity=100)'
+ })
+ },
+
+ onTopWhileDragging : function(zIndex) {
+ var zIndex = typeof(zIndex) != "undefined" ? zIndex : 100000;
+ var originalZIndex = ToolMan.css().readStyle(this.element, "z-index")
+
+ this.register('dragstart', function(dragEvent) {
+ dragEvent.group.element.style.zIndex = zIndex
+ })
+ this.register('dragend', function(dragEvent) {
+ dragEvent.group.element.style.zIndex = originalZIndex
+ })
+ },
+
+ _dragInit : function(event) {
+ event = ToolMan.events().fix(event)
+ var group = document.toolManDragGroup = this.toolManDragGroup
+ var dragEvent = group.factory._createEvent('draginit', event, group)
+
+ group._isThresholdExceeded = false
+ group._initialMouseOffset = dragEvent.mouseOffset
+ group._grabOffset = dragEvent.mouseOffset.minus(dragEvent.topLeftOffset)
+ ToolMan.events().register(document, 'mousemove', group._drag)
+ document.onmousemove = function() { return false }
+ ToolMan.events().register(document, 'mouseup', group._dragEnd)
+
+ group._notifyListeners(dragEvent)
+ },
+
+ _drag : function(event) {
+ event = ToolMan.events().fix(event)
+ var coordinates = ToolMan.coordinates()
+ var group = this.toolManDragGroup
+ if (!group) return
+ var dragEvent = group.factory._createEvent('dragmove', event, group)
+
+ var newTopLeftOffset = dragEvent.mouseOffset.minus(group._grabOffset)
+
+ // TODO: replace with DragThreshold object
+ if (!group._isThresholdExceeded) {
+ var distance =
+ dragEvent.mouseOffset.distance(group._initialMouseOffset)
+ if (distance < group._thresholdDistance) return
+ group._isThresholdExceeded = true
+ group._notifyListeners(
+ group.factory._createEvent('dragstart', event, group))
+ }
+
+ for (i in group._transforms) {
+ var transform = group._transforms[i]
+ newTopLeftOffset = transform(newTopLeftOffset, dragEvent)
+ }
+
+ var dragDelta = newTopLeftOffset.minus(dragEvent.topLeftOffset)
+ var newTopLeftPosition = dragEvent.topLeftPosition.plus(dragDelta)
+ newTopLeftPosition.reposition(group.element)
+ dragEvent.transformedMouseOffset = newTopLeftOffset.plus(group._grabOffset)
+
+ group._notifyListeners(dragEvent)
+
+ var errorDelta = newTopLeftOffset.minus(coordinates.topLeftOffset(group.element))
+ if (errorDelta.x != 0 || errorDelta.y != 0) {
+ coordinates.topLeftPosition(group.element).plus(errorDelta).reposition(group.element)
+ }
+ },
+
+ _dragEnd : function(event) {
+ event = ToolMan.events().fix(event)
+ var group = this.toolManDragGroup
+ var dragEvent = group.factory._createEvent('dragend', event, group)
+
+ group._notifyListeners(dragEvent)
+
+ this.toolManDragGroup = null
+ ToolMan.events().unregister(document, 'mousemove', group._drag)
+ document.onmousemove = null
+ ToolMan.events().unregister(document, 'mouseup', group._dragEnd)
+ },
+
+ _notifyListeners : function(dragEvent) {
+ var listeners = this._listeners[dragEvent.type]
+ for (i in listeners) {
+ listeners[i](dragEvent)
+ }
+ }
+}
+
+function _ToolManDragEvent(type, event, group) {
+ this.type = type
+ this.group = group
+ this.mousePosition = ToolMan.coordinates().mousePosition(event)
+ this.mouseOffset = ToolMan.coordinates().mouseOffset(event)
+ this.transformedMouseOffset = this.mouseOffset
+ this.topLeftPosition = ToolMan.coordinates().topLeftPosition(group.element)
+ this.topLeftOffset = ToolMan.coordinates().topLeftOffset(group.element)
+}
+
+_ToolManDragEvent.prototype = {
+ toString : function() {
+ return "mouse: " + this.mousePosition + this.mouseOffset + " " +
+ "xmouse: " + this.transformedMouseOffset + " " +
+ "left,top: " + this.topLeftPosition + this.topLeftOffset
+ }
+}
+
+ToolMan._dragFactory._constraintFactory = {
+ vertical : function() {
+ return function(coordinate, dragEvent) {
+ var x = dragEvent.topLeftOffset.x
+ return coordinate.x != x
+ ? coordinate.factory.create(x, coordinate.y)
+ : coordinate
+ }
+ },
+
+ horizontal : function() {
+ return function(coordinate, dragEvent) {
+ var y = dragEvent.topLeftOffset.y
+ return coordinate.y != y
+ ? coordinate.factory.create(coordinate.x, y)
+ : coordinate
+ }
+ }
+}
diff --git a/comiccontrol/draganddrop/dragsort.js b/comiccontrol/draganddrop/dragsort.js
new file mode 100644
index 0000000..2886c62
--- /dev/null
+++ b/comiccontrol/draganddrop/dragsort.js
@@ -0,0 +1,87 @@
+/* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt) */
+
+ToolMan._dragsortFactory = {
+ makeSortable : function(item) {
+ var group = ToolMan.drag().createSimpleGroup(item)
+
+ group.register('dragstart', this._onDragStart)
+ group.register('dragmove', this._onDragMove)
+ group.register('dragend', this._onDragEnd)
+
+ return group
+ },
+
+ /**
+ * Iterates over a list's items, making them sortable, applying
+ * optional functions to each item.
+ *
+ * example: makeListSortable(myList, myFunc1, myFunc2, ... , myFuncN)
+ */
+ makeListSortable : function(list) {
+ var helpers = ToolMan.helpers()
+ var coordinates = ToolMan.coordinates()
+ var items = list.getElementsByTagName("li")
+
+ helpers.map(items, function(item) {
+ var dragGroup = dragsort.makeSortable(item)
+ dragGroup.setThreshold(4)
+ var min, max
+ dragGroup.addTransform(function(coordinate, dragEvent) {
+ return coordinate.constrainTo(min, max)
+ })
+ dragGroup.register('dragstart', function() {
+ var items = list.getElementsByTagName("li")
+ min = max = coordinates.topLeftOffset(items[0])
+ for (var i = 1, n = items.length; i < n; i++) {
+ var offset = coordinates.topLeftOffset(items[i])
+ min = min.min(offset)
+ max = max.max(offset)
+ }
+ })
+ })
+ for (var i = 1, n = arguments.length; i < n; i++)
+ helpers.map(items, arguments[i])
+ },
+
+ _onDragStart : function(dragEvent) {
+ },
+
+ _onDragMove : function(dragEvent) {
+ var helpers = ToolMan.helpers()
+ var coordinates = ToolMan.coordinates()
+
+ var item = dragEvent.group.element
+ var xmouse = dragEvent.transformedMouseOffset
+ var moveTo = null
+
+ var previous = helpers.previousItem(item, item.nodeName)
+ while (previous != null) {
+ var bottomRight = coordinates.bottomRightOffset(previous)
+ if (xmouse.y <= bottomRight.y && xmouse.x <= bottomRight.x) {
+ moveTo = previous
+ }
+ previous = helpers.previousItem(previous, item.nodeName)
+ }
+ if (moveTo != null) {
+ helpers.moveBefore(item, moveTo)
+ return
+ }
+
+ var next = helpers.nextItem(item, item.nodeName)
+ while (next != null) {
+ var topLeft = coordinates.topLeftOffset(next)
+ if (topLeft.y <= xmouse.y && topLeft.x <= xmouse.x) {
+ moveTo = next
+ }
+ next = helpers.nextItem(next, item.nodeName)
+ }
+ if (moveTo != null) {
+ helpers.moveBefore(item, helpers.nextItem(moveTo, item.nodeName))
+ return
+ }
+ },
+
+ _onDragEnd : function(dragEvent) {
+ ToolMan.coordinates().create(0, 0).reposition(dragEvent.group.element)
+ }
+}
diff --git a/comiccontrol/draganddrop/events.js b/comiccontrol/draganddrop/events.js
new file mode 100644
index 0000000..90b2058
--- /dev/null
+++ b/comiccontrol/draganddrop/events.js
@@ -0,0 +1,43 @@
+/* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt) */
+
+ToolMan._eventsFactory = {
+ fix : function(event) {
+ if (!event) event = window.event
+
+ if (event.target) {
+ if (event.target.nodeType == 3) event.target = event.target.parentNode
+ } else if (event.srcElement) {
+ event.target = event.srcElement
+ }
+
+ return event
+ },
+
+ register : function(element, type, func) {
+ if (element.addEventListener) {
+ element.addEventListener(type, func, false)
+ } else if (element.attachEvent) {
+ if (!element._listeners) element._listeners = new Array()
+ if (!element._listeners[type]) element._listeners[type] = new Array()
+ var workaroundFunc = function() {
+ func.apply(element, new Array())
+ }
+ element._listeners[type][func] = workaroundFunc
+ element.attachEvent('on' + type, workaroundFunc)
+ }
+ },
+
+ unregister : function(element, type, func) {
+ if (element.removeEventListener) {
+ element.removeEventListener(type, func, false)
+ } else if (element.detachEvent) {
+ if (element._listeners
+ && element._listeners[type]
+ && element._listeners[type][func]) {
+
+ element.detachEvent('on' + type,
+ element._listeners[type][func])
+ }
+ }
+ }
+}