r2741 - + Added support for reverting positioned elements back to their original spots (as closel...

r2741 - + Added support for reverting positioned elements back to their original spots (as closel...


Author: vtGavin
Date: Fri Jun 12 19:41:18 2009
New Revision: 2741
Modified:
branches/dev/positionTo/ui/utils.positionTo.js
Log:
+ Added support for reverting positioned elements back to their original
spots (as closely as possible).
+ Put in stubs for a method wherein positionTo will use a document-bound
data() index for referencing positioned elements within call-backs (to
avoid unnecessary selector latency).
+ Fleshed out revert a bit more.
Modified: branches/dev/positionTo/ui/utils.positionTo.js
==============================================================================
--- branches/dev/positionTo/ui/utils.positionTo.js    (original)
+++ branches/dev/positionTo/ui/utils.positionTo.js    Fri Jun 12 19:41:18 2009
@@ -10,8 +10,11 @@
* Depends:
*    ui.core.js
*/
-
$.fn.positionTo = function(parentElem, options){
+    // !!!
+    // think about implementing an indexing scheme using a document-bound
data tuple to
+    // reduce the need for constant selector invocation
+    
var positionTo_handlers = {
scroll: function(){
console.log('scroll detected');
@@ -20,27 +23,39 @@
var $parentElem = $(parentElem),
parentOffset = $parentElem.offset(),
- // store the border widths (if they exist) for the parent element
- parentElem_borderWidths = {
- left:
parseInt($parentElem.css('border-left-width').replace(/px/, '')),
- right:
parseInt($parentElem.css('border-right-width').replace(/px/, '')),
- top:
parseInt($parentElem.css('border-top-width').replace(/px/, '')),
- bottom:
parseInt($parentElem.css('border-bottom-width').replace(/px/, ''))
- },
// calculate parent element coordinates and pad accordingly for
any border styling
parentElem_coords = {
- left: parentOffset.left - parentElem_borderWidths.left,
- right: parentOffset.left + $parentElem.outerWidth() +
parentElem_borderWidths.right,
- top: parentOffset.top - parentElem_borderWidths.top,
- bottom: parentOffset.top + $parentElem.outerHeight() +
parentElem_borderWidths.bottom
+ left: parentOffset.left,
+ right: parentOffset.left + $parentElem.outerWidth(),
+ top: parentOffset.top,
+ bottom: parentOffset.top + $parentElem.outerHeight()
};
+
+ this.data('positionTo_uniqueNodeID', {
+     elem_originalParent: (this.parent().length ? this.parent()[0] :
false),
+     ordinalSibling: {
+         $previous: false,
+         $next: false
+     },
+     originalCSS: {
+         display: this.css('display'),
+         position: this.css('position'),
+         left: this.css('left'),
+         right: this.css('right'),
+         top: this.css('top'),
+         bottom: this.css('bottom')
+     }
+ });
+ // set the pertinent ordinal sibling for this positionable element
before it is appended
+ // to the body
+ // !!!
+
$('body').append(this);
-
+
// prep this element for being positioned
this.css('display', 'block')
- .css('position', 'absolute')
- .css('margin', '0');
+ .css('position', 'absolute');
// !!! arbitrarily position the element
this.css('left', parentElem_coords.right + 'px')
@@ -53,78 +68,6 @@
$(this).bind('scroll.positionTo_uniqueNodeID',
positionTo_handlers.scroll)
.addClass('positionTo_tagged_uniqueNodeID');
});
-
- /**
-    var _options = $.extend({
-        around: 'mouse',
-        direction: 'default',
-        forceDirection: false,
-        offset: [0, 0]
-    }, options);
-
-    var leftOffset    = 0,
-        topOffset    = 0,
-        height        = this[0].offsetHeight,
-        width        = this[0].offsetWidth,
-        op            = this.offsetParent(),
-        sp            = $(this.scrollParent()[0] || document.body),
-        spBorderTop = parseInt(op.css('borderTopWidth'),10),
-        spBorderLeft= parseInt(op.css('borderLeftWidth'),10),
-        opBorderTop = parseInt(op.css('borderTopWidth'),10),
-        opBorderLeft= parseInt(op.css('borderLeftWidth'),10),
-        opOffset    = op.offset(),
-        spOffset    = sp.offset()
-    ;
-
-    //Ugly fix for the issues of offset related to the body element
-    opOffset = (/(html|body)/).test(op[0].tagName.toLowerCase()) ? { top: 0,
left: 0 } : opOffset;
-    spOffset = (/(html|body)/).test(op[0].tagName.toLowerCase()) ? { top: 0,
left: 0 } : spOffset;
-
-    var bottomEdge = (/(html|body)/).test(op[0].tagName.toLowerCase()) ?
$(window).height() : spOffset.top + spBorderTop + sp.height();
-    var rightEdge = (/(html|body)/).test(op[0].tagName.toLowerCase()) ?
$(window).width() : spOffset.left + spBorderLeft + sp.width();
-
-    if($(options.around).length && $(options.around)[0].nodeName) { //If
around is an element
-
-        var element = $(options.around),
-            offset = element.offset(),
-            relHeight = element[0].offsetHeight,
-            relWidth = element[0].offsetWidth
-        ;
-
-        if((/(left|right)/).test(options.direction)) {
-
-            leftOffset = ( options.direction == 'left' ? (offset.left -
spOffset.left - spBorderLeft > width || options.forceDirection) :
(rightEdge-offset.left-relWidth < width && !options.forceDirection) ) ?
-(width) : relWidth;
-            topOffset = event ? ( bottomEdge - offset.top < height ?
-(height-relHeight) : 0 ) : 0;
-        } else {
-            topOffset = ( options.direction == 'above' ? (offset.top - spOffset.top
- spBorderTop > height || options.forceDirection) :
(bottomEdge-offset.top-relHeight < height && !options.forceDirection) ) ?
-(height) : relHeight;
-        }
-
-        this.css({
-            left: offset.left - opOffset.left - opBorderLeft + leftOffset +
options.offset[0],
-            top: offset.top - opOffset.top - opBorderTop + topOffset +
options.offset[1]
-        });
-
-    } else {
-
-        if((/(below|default)/).test(options.direction)) {
-            topOffset = bottomEdge - event.pageY < height
&& !options.forceDirection ? -(height) : 0;
-        } else if ((/above/).test(options.direction)) {
-            topOffset = (event.pageY - spOffset.top - spBorderTop) > height ||
options.forceDirection ? -(height) : 0;
-        }
-
-        if((/(right|default)/).test(options.direction)) {
-            leftOffset = rightEdge - event.pageX < width
&& !options.forceDirection ? -(width) : 0;
-        } else if ((/left/).test(options.direction)) {
-            leftOffset = (event.pageX - spOffset.left - spBorderLeft) > width ||
options.forceDirection ? -(width) : 0;
-        }
-
-
-        this.css({
-            left: event.pageX - opOffset.left - opBorderLeft + leftOffset +
options.offset[0],
-            top: event.pageY - opOffset.top - opBorderTop + topOffset +
options.offset[1]
-        });
-
-    }*/
};
/**
@@ -136,8 +79,49 @@
*/
$.fn.positionRevert = function()
{
+    var $elem_parent =
$(this.data('positionTo_uniqueNodeID').elem_originalParent),
+        ordinalSibling = this.data('positionTo_uniqueNodeID').ordinalSibling;
+    
+    // if: this positionable element had a valid parent element when it was
first positioned
+    // then: attempt to place it back where it was originally positioned
+    if ($elem_parent.length)
+    {
+        // if: an ordinal previous sibling was specified
+        // AND
+        // it still exists in the DOM
+        // then: insert this element after it
+        if (ordinalSibling.$previous && ordinalSibling.$previous.length)
+        {
+            ordinalSibling.$previous.after(this);
+        }
+        // else if: an ordinal next sibling was specified
+        // AND
+        // it still exists in the DOM
+        // then: insert this element before it
+        else if (ordinalSibling.$next && ordinalSibling.$next.length)
+        {
+            ordinalSibling.$next.before(this);
+        }
+        // else: if all else fails, just append it directly to the parent node
+        else
+        {
+            $elem_parent.append(this);
+        }
+    }
+    
+    // reset this positionable element to its original css values
+    var originalCSS = this.data('positionTo_uniqueNodeID').originalCSS;
+    this.css('display', originalCSS.display)
+     .css('position', originalCSS.position)
+     .css('left', originalCSS.left)
+     .css('right', originalCSS.right)
+     .css('top', originalCSS.top)
+     .css('bottom', originalCSS.bottom);
+    
$(document).unbind('.positionTo_uniqueNodeID');
$('.positionTo_tagged_uniqueNodeID').unbind('.positionTo_uniqueNodeID')
.removeClass('positionTo_tagged_uniqueNodeID');
+
+ this.removeData('positionTo_uniqueNodeID');
}