Author: pyaschenko
Date: 2010-02-03 10:26:43 -0500 (Wed, 03 Feb 2010)
New Revision: 16402
Added:
root/framework/trunk/impl/src/main/resources/META-INF/resources/jquery.position.js
Log:
position plugin for jQuery was added
Added: root/framework/trunk/impl/src/main/resources/META-INF/resources/jquery.position.js
===================================================================
--- root/framework/trunk/impl/src/main/resources/META-INF/resources/jquery.position.js
(rev 0)
+++
root/framework/trunk/impl/src/main/resources/META-INF/resources/jquery.position.js 2010-02-03
15:26:43 UTC (rev 16402)
@@ -0,0 +1,253 @@
+// draft examples of usage
+// jQuery('#tooltip').position('#aaa',{from:'LB',
to:'AA'});
+//
jQuery('#bbb').bind("click",function(e){jQuery('#tooltip').position(e);});
+// TODO: clear code
+// TODO: optimization
+
+(function($) {
+ $.fn.position = function(source, params) {
+ var stype = typeof source;
+ if (stype == "object" || stype == "string") {
+ var rect = {};
+ if (source.type) {
+ rect = getPointerRect(source);
+ } else if (stype == "string" || source.nodeType || source instanceof jQuery)
{
+ stype = "element";
+ rect = getElementRect(source);
+ } else {
+ rect = source;
+ }
+
+ var params = params || {};
+ var options = $.extend({}, defaults, $.PositionTypes[params.type || defaults.type],
params);
+ return this.each(function() {
+ element = $(this);
+ //alert(rect.left+" "+rect.top+" "+rect.width+"
"+rect.height);
+ position(rect, element, options);
+ });
+ }
+ };
+
+ var defaults = {
+ type: "TOOLTIP",
+ collision: "",
+ offset: [0,0]
+ };
+ var re = /^(left|right)-(top|buttom|auto)$/i;
+
+ $.PositionTypes = {
+ // horisontal constants: L-left, R-right, C-center, A-auto
+ // vertical constants: T-top, B-bottom, M-middle, A-auto
+ // for auto: list of joinPoint-Direction pairs
+ TOOLTIP: {from:"RB", to:"AA", auto:["RBRT",
"RBLT", "RBLB", "RBRB"]},
+ DROPDOWN:{from:"RB", to:"AA", auto:["RBLB",
"RTLT", "LBRB", "LTRT"]}
+ };
+
+ $.addPositionType = function (type, options) {
+ // TODO: change [options] to [from, to, auto]
+ /*var obj = {};
+ if (match=from.match(re))!=null ) {
+ obj.from = [ match[1]=='right' ? 'R' : 'L',
match[2]=='bottom' ? 'B' : 'T'];
+ }
+ if (match=to.match(re))!=null ) {
+ obj.to = [ match[1]=='right' ? 'R' : match[1]=='left' ?
'L' : 'A', match[2]=='bottom' ? 'B' :
match[2]=='top' ? 'T' : 'A'];
+ }*/
+ $.PositionTypes[type] = options;
+ }
+
+ function cropPx(value) {
+ if (typeof value == "string") {
+ if (!isNaN(value)) {
+ return parseInt(value);
+ }
+ }
+ return NaN;
+ };
+
+ function getPointerRect (event) {
+ var e = $.event.fix(event);
+ return {width: 0, height: 0, left: e.pageX, top: e.pageY};
+ };
+
+ function getElementRect (element) {
+ var jqe = $(element);
+ var offset = jqe.offset();
+ return {width: jqe.width(), height: jqe.height(), left: offset.left, top: offset.top};
+ };
+
+ function checkCollision (elementRect, windowRect) {
+ // return 0 if elementRect in windowRect without collision
+ if (elementRect.left >= windowRect.left &&
+ elementRect.top >= windowRect.top &&
+ elementRect.right <= windowRect.right &&
+ elementRect.bottom <= windowRect.bottom)
+ return 0;
+ // return collision squire
+ var rect = {left: (elementRect.left>windowRect.left ? elementRect.left :
windowRect.left),
+ top: (elementRect.top>windowRect.top ? elementRect.top : windowRect.top),
+ right: (elementRect.right<windowRect.right ? elementRect.right :
windowRect.right),
+ bottom: (elementRect.bottom<windowRect.bottom ? elementRect.bottom :
windowRect.bottom)};
+ return (rect.right-rect.left) * (rect.bottom-rect.top);
+ };
+
+ //function fromLeft() {
+ /*
+ * params: {
+ * left,top,width,height, //baseRect
+ * ox,oy, //rectoffset
+ * w,h // elementDim
+ * }
+ */
+ /* return this.left;
+ }
+
+ function fromRight(params) {
+ return this.left + this.width - this.w;
+ }
+
+ function (params) {
+ var rect = {left:fromLeft.call(params), right:fromRight.call(params), top:}
+ }*/
+
+ function getPositionRect(baseRect, rectOffset, elementDim, pos) {
+ var rect = {};
+ // TODO: add support for center and middle // may be middle rename to center too
+ // TODO: add rectOffset support
+
+ var v = pos.charAt(0);
+ if (v=='L') {
+ rect.left = baseRect.left// + rectOffset.left;
+ } else if (v=='R') {
+ rect.left = baseRect.left + baseRect.width;// - rectOffset.left;
+ }
+
+ v = pos.charAt(1);
+ if (v=='T') {
+ rect.top = baseRect.top// + rectOffset.left;
+ } else if (v=='B') {
+ rect.top = baseRect.top + baseRect.height;// - rectOffset.left;
+ }
+
+ v = pos.charAt(2);
+ if (v=='L') {
+ rect.right = rect.left;
+ rect.left -= elementDim.width;
+ } else if (v=='R') {
+ rect.right = rect.left + elementDim.width;
+ }
+
+ v = pos.charAt(3);
+ if (v=='T') {
+ rect.bottom = rect.top;
+ rect.top -= elementDim.height;
+ } else if (v=='B') {
+ rect.bottom = rect.top + elementDim.height;
+ }
+
+ return rect;
+ }
+
+ function __mergePos(s1,s2) {
+ var result = "";
+ var ch;
+ while (result.length < s1.length) {
+ ch = s1.charAt(result.length);
+ result += ch == 'A' ? s2.charAt(result.length) : ch;
+ }
+ return result;
+ }
+
+ function calculatePosition (baseRect, rectOffset, windowRect, elementDim, options) {
+
+ var theBest = {square:0};
+ var rect;
+ var s;
+ var ox, oy;
+ var p = options.from+options.to;
+
+ if (p.indexOf('A')<0) {
+ return getPositionRect(baseRect, rectOffset, elementDim, p);
+ } else {
+ var pos;
+ for (var i = 0; i<options.auto.length; i++) {
+
+ // TODO: draft functional
+ pos = __mergePos(p, options.auto[i]);
+ rect = getPositionRect(baseRect, rectOffset, elementDim, pos);
+ ox = rect.left; oy = rect.top;
+ s = checkCollision(rect, windowRect);
+ if (s!=0) {
+ if (ox>=0 && oy>=0 && theBest.square<s) theBest = {x:ox,
y:oy, square:s};
+ } else break;
+ }
+ if (s!=0 && (ox<0 || oy<0 || theBest.square>s)) {
+ ox=theBest.x; oy=theBest.y
+ }
+ }
+
+ /*
+ // jointPoint: bottom-right, direction: bottom-left
+ var basex = baseRect.left - rectOffset.left;
+ var basey = baseRect.top + rectOffset.top;
+ var rect = {right: basex + baseRect.width, top: basey + baseRect.height};
+ rect.left = rect.right - elementDim.width;
+ rect.bottom = rect.top + elementDim.height;
+
+ // jointPoint: top-right, direction: top-left
+ basex = baseRect.left - rectOffset.left;
+ basey = baseRect.top - rectOffset.top;
+ rect = {right: basex + baseRect.width, bottom: basey};
+ rect.left = rect.right - elementDim.width;
+ rect.top = rect.bottom - elementDim.height;
+
+ // jointPoint: bottom-left, direction: bottom-right
+ basex = baseRect.left + rectOffset.left;
+ basey = baseRect.top + rectOffset.top;
+ rect = {left: basex, top: basey + baseRect.height};
+ rect.right = rect.left + elementDim.width;
+ rect.bottom = rect.top + elementDim.height;
+
+ // jointPoint: top-left, direction: top-right
+ basex = baseRect.left + rectOffset.left;
+ basey = baseRect.top + rectOffset.top;
+ rect = {left: basex, bottom: basey};
+ rect.right = rect.left + elementDim.width;
+ rect.top = rect.bottom - elementDim.height;
+ }*/
+
+ return {left:ox, top:oy};
+ }
+
+ function position (rect, element, options) {
+ var width = element.width();
+ var height = element.height();
+
+ var left = cropPx(element.css('left'));
+ if (isNaN(left)) {
+ left = 0;
+ element.css('left', '0px');
+ }
+
+ var top = cropPx(element.css('top'));
+ if (isNaN(top)) {
+ top = 0;
+ element.css('top', '0px');
+ }
+
+ var elementOffset = element.offset();
+
+ var jqw = $(window);
+ var winRect = {left:jqw.scrollLeft(), top:jqw.scrollTop()};
+ winRect.right = winRect.left + jqw.width();
+ winRect.bottom = winRect.top + jqw.height();
+
+ var pos = calculatePosition(rect, options.offset, winRect, {width:width,
height:height}, options);
+
+ pos.left -= elementOffset.left;
+ pos.top -= elementOffset.top;
+
+ element.css('left', (pos.left + 'px')).css('top', (pos.top +
'px'));
+ };
+
+})(jQuery);
+