# HG changeset patch # User Pawel Solyga # Date 1241457824 -7200 # Node ID 8566fb2b8012f33846b56a57718b3d55af52b05c # Parent be2c150d1a1fb24b4af17011486e4410cd923b1b Replace BeautyTips tooltips with purr info box for all form fields with help text. Patch by: Mario Ferraro Reviewed by: Pawel Solyga diff -r be2c150d1a1f -r 8566fb2b8012 app/jquery/jquery-bt-0.7.js --- a/app/jquery/jquery-bt-0.7.js Fri May 01 01:37:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,813 +0,0 @@ -/* - * jQuery Beauty Tips plugin - * Version 0.7 (10/20/2008) - * @requires jQuery v1.2+ (not fully tested on versions prior to 1.2.6) - * - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - * - * No guarantees, warranties, or promises of any kind - * - */ - -/** - * @name Beauty Tips - * @type jQuery - * @cat Plugins/bt - * @return jQuery - * @author Jeff Robbins - Lullabot - http://www.lullabot.com - * - * @credit Inspired by Karl Swedberg's ClueTip - * (http://plugins.learningjquery.com/cluetip/), which in turn was inspired - * by Cody Lindley's jTip (http://www.codylindley.com) - * - * @fileoverview - * Beauty Tips is a jQuery tooltips plugin which uses the canvas drawing element - * in the HTML5 spec in order to dynamically draw tooltip "talk bubbles" around - * the descriptive help text associated with an item. This is in many ways - * similar to Google Maps which both provides similar talk-bubbles and uses the - * canvas element to draw them. - * - * The canvas element is supported in modern versions of FireFox, Safari, and - * Opera. However, Internet Explorer needs a separate library called ExplorerCanvas - * included on the page in order to support canvas drawing functions. ExplorerCanvas - * was created by Google for use with their web apps and you can find it here: - * http://excanvas.sourceforge.net/ - * - * Beauty Tips was written to be simple to use and pretty. All of its options - * are documented at the bottom of this file and defaults can be overwritten - * globally for the entire page, or individually on each call. - * - * By default each tooltip will be positioned on the side of the target element - * which has the most free space. This is affected by the scroll position and - * size of the current window, so each Beauty Tip is redrawn each time it is - * displayed. It may appear above an element at the bottom of the page, but when - * the page is scrolled down (and the element is at the top of the page) it will - * then appear below it. Additionally, positions can be forced or a preferred - * order can be defined. See examples below. - * - * Usage - * The function can be called in a number of ways. - * $(selector).bt(); - * $(selector).bt('Content text'); - * $(selector).bt('Content text', {option1: value, option2: value}); - * $(selector).bt({option1: value, option2: value}); - * - * Some examples: - * - * @example - * $('[title]').bt(); - * This is probably the simplest example. It will go through the page finding - * every element which has a title attribute and give it a Beauty Tips popup - * which gets fired on hover. - * - * @example - * $('h2').bt('I am an H2 element!', {trigger: 'click', positions: 'top'}); - * When any H2 element on the page is clicked on, a tip will appear above it. - * - * @example - * $('a[href]').bt({ - * titleSelector: "attr('href')", - * fill: 'red', - * cssStyles: {color: 'white', fontWeight: 'bold', width: 'auto'}, - * width: 400, - * padding: 10, - * cornerRadius: 10, - * animate: true, - * spikeLength: 15, - * spikeGirth: 5, - * positions: ['left', 'right', 'bottom'], - * }); - * This will find all tags and display a red baloon with bold white text - * containing the href link. The box will be a variable width up to 400px with - * rounded corners and will fade in and animate position toward the target - * object when appearing. The script will try to position the box to the left, - * then to the right, and finally it will place it on the bottom if it does not - * fit elsewhere. - * - * @example - * $('#my-table td[title]').bt({ - * preShow: function() { - * $(this).data('origBG', $(this).css('background-color')); - * $(this).css('background-color', 'yellow'); - * }, - * postHide: function() { - * $(this).css('background-color', $(this).data('origBG')); - * } - * }); - * Find every table cell within #mytable with a title attribute. Hilight the cell - * yellow before displaying the BeautyTip. Restore it to its original background - * when hiding/removing the BeautyTip. - * - * @example - * $().bt.defaults.fill = 'rgba(102, 102, 255. .8)'; - * $(selector).bt(); - * All bubbles will be filled with a semi-transparent light-blue background - * unless otherwise specified. - * - */ -jQuery.fn.bt = function(content, options) { - - if (typeof content != 'string') { - var contentSelect = true; - options = content; - content = false; - } - else { - var contentSelect = false; - } - - var tooltips_pool = []; - - - return this.each(function(index) { - - tooltips_pool.push(this); - - var opts = jQuery.extend(false, jQuery.fn.bt.defaults, options); - - // clean up the options - opts.spikeLength = numb(opts.spikeLength); - opts.spikeGirth = numb(opts.spikeGirth); - opts.overlap = numb(opts.overlap); - - var turnOn = function () { - - for (var x in tooltips_pool) { - turnOff.apply(tooltips_pool[x]); - } - - if (typeof $(this).data('bt-box') == 'object') { - // if there's already a popup, remove it before creating a new one. - turnOff.apply(this); - } - - // trigger preShow function - opts.preShow.apply(this); - - if (contentSelect) { - // bizarre, I know - if (opts.killTitle) { - // if we've killed the title attribute, it's been stored in 'bt-xTitle' so get it.. - $(this).attr('title', $(this).attr('bt-xTitle')); - } - // then evaluate the selector... title is now in place - content = eval('$(this).' + opts.titleSelector); - if (opts.killTitle) { - // now remove the title again, so we don't get double tips - $(this).removeAttr('title'); - } - } - - var offsetParent = $(this).offsetParent(); - var pos = $(this).btPosition(); - var top = numb(pos.top) + numb($(this).css('margin-top')); // IE can return 'auto' for margins - var left = numb(pos.left) + numb($(this).css('margin-left')); - var width = $(this).outerWidth(); - var height = $(this).outerHeight(); - - // get the dimensions of the text box - var $text = $('
').append(content).css({padding: opts.padding + 'px', position: 'absolute', width: opts.width + 'px', zIndex: opts.textzIndex}).css(opts.cssStyles); - var $box = $('
').append($text).addClass(opts.cssClass).css({position: 'absolute', width: opts.width + 'px'}).appendTo(offsetParent); - - $(this).data('bt-box', $box); - - // see if the text box will fit in the various positions - var scrollTop = numb($(document).scrollTop()); - var scrollLeft = numb($(document).scrollLeft()); - var docWidth = numb($(window).width()); - var docHeight = numb($(window).height()); - var winRight = scrollLeft + docWidth; - var winBottom = scrollTop + docHeight; - var space = new Object(); - space.top = $(this).offset().top - scrollTop; - space.bottom = docHeight - (($(this).offset().top + height) - scrollTop); - space.left = $(this).offset().left - scrollLeft; - space.right = docWidth - (($(this).offset().left + width) - scrollLeft); - var textOutHeight = numb($text.outerHeight()); - var textOutWidth = numb($text.outerWidth()); - if (opts.positions.constructor == String) { - opts.positions = opts.positions.replace(/ /, '').split(','); - } - if (opts.positions[0] == 'most') { - // figure out which is the largest - var position = 'top'; // prime the pump - for (var pig in space) { // pigs in space! - position = space[pig] > space[position] ? pig : position; - } - } - else { - for (var x in opts.positions) { - var position = opts.positions[x]; - if ((position == 'left' || position == 'right') && space[position] > textOutWidth + opts.spikeLength) { - break; - } - else if ((position == 'top' || position == 'bottom') && space[position] > textOutHeight + opts.spikeLength) { - break; - } - } - } - - var horiz = left + ((width - textOutWidth)/2); - var vert = top + ((height - textOutHeight)/2); - var animDist = opts.animate ? numb(opts.distance) : 0; - var points = new Array(); - var textTop, textLeft, textRight, textBottom, textTopSpace, textBottomSpace, textLeftSpace, textRightSpace, crossPoint, textCenter; - - // Yes, yes, this next bit really could use to be condensed - // each switch case is basically doing the same thing in slightly different ways - switch(position) { - case 'top': - // spike on bottom - $text.css('margin-bottom', opts.spikeLength + 'px'); - $box.css({top: (top - $text.outerHeight(true) - animDist) + opts.overlap, left: horiz}); - // move text left/right if extends out of window - textRightSpace = (winRight - opts.windowMargin) - ($text.offset().left + $text.outerWidth(true)); - var xShift = 0; - if (textRightSpace < 0) { - // shift it left - $box.css('left', (numb($box.css('left')) + textRightSpace) + 'px'); - xShift -= textRightSpace; - } - // we test left space second to ensure that left of box is visible - textLeftSpace = ($text.offset().left + numb($text.css('margin-left'))) - (scrollLeft + opts.windowMargin); - if (textLeftSpace < 0) { - // shift it right - $box.css('left', (numb($box.css('left')) - textLeftSpace) + 'px'); - xShift += textLeftSpace; - } - textTop = $text.btPosition().top + numb($text.css('margin-top')); - textLeft = $text.btPosition().left + numb($text.css('margin-left')); - textRight = textLeft + $text.outerWidth(); - textBottom = textTop + $text.outerHeight(); - textCenter = {x: textLeft + ($text.outerWidth()/2), y: textTop + ($text.outerHeight()/2)}; - // points[points.length] = {x: x, y: y}; - points[points.length] = spikePoint = {y: textBottom + opts.spikeLength, x: ((textRight-textLeft)/2) + xShift, type: 'spike'}; - crossPoint = findIntersectX(spikePoint.x, spikePoint.y, textCenter.x, textCenter.y, textBottom); - // make sure that the crossPoint is not outside of text box boundaries - crossPoint.x = crossPoint.x < textLeft + opts.spikeGirth/2 + opts.cornerRadius ? textLeft + opts.spikeGirth/2 + opts.cornerRadius : crossPoint.x; - crossPoint.x = crossPoint.x > (textRight - opts.spikeGirth/2) - opts.cornerRadius ? (textRight - opts.spikeGirth/2) - opts.CornerRadius : crossPoint.x; - points[points.length] = {x: crossPoint.x - (opts.spikeGirth/2), y: textBottom, type: 'join'}; - points[points.length] = {x: textLeft, y: textBottom, type: 'corner'}; // left bottom corner - points[points.length] = {x: textLeft, y: textTop, type: 'corner'}; // left top corner - points[points.length] = {x: textRight, y: textTop, type: 'corner'}; // right top corner - points[points.length] = {x: textRight, y: textBottom, type: 'corner'}; // right bottom corner - points[points.length] = {x: crossPoint.x + (opts.spikeGirth/2), y: textBottom, type: 'join'}; - points[points.length] = spikePoint; - break; - case 'left': - // spike on right - $text.css('margin-right', opts.spikeLength + 'px'); - $box.css({top: vert + 'px', left: ((left - $text.outerWidth(true) - animDist) + opts.overlap) + 'px'}); - // move text up/down if extends out of window - textBottomSpace = (winBottom - opts.windowMargin) - ($text.offset().top + $text.outerHeight(true)); - var yShift = 0; - if (textBottomSpace < 0) { - // shift it up - $box.css('top', (numb($box.css('top')) + textBottomSpace) + 'px'); - yShift -= textBottomSpace; - } - // we ensure top space second to ensure that top of box is visible - textTopSpace = ($text.offset().top + numb($text.css('margin-top'))) - (scrollTop + opts.windowMargin); - if (textTopSpace < 0) { - // shift it down - $box.css('top', (numb($box.css('top')) - textTopSpace) + 'px'); - yShift += textTopSpace; - } - textTop = $text.btPosition().top + numb($text.css('margin-top')); - textLeft = $text.btPosition().left + numb($text.css('margin-left')); - textRight = textLeft + $text.outerWidth(); - textBottom = textTop + $text.outerHeight(); - textCenter = {x: textLeft + ($text.outerWidth()/2), y: textTop + ($text.outerHeight()/2)}; - points[points.length] = spikePoint = {x: textRight + opts.spikeLength, y: ((textBottom-textTop)/2) + yShift, type: 'spike'}; - crossPoint = findIntersectY(spikePoint.x, spikePoint.y, textCenter.x, textCenter.y, textRight); - // make sure that the crossPoint is not outside of text box boundaries - crossPoint.y = crossPoint.y < textTop + opts.spikeGirth/2 + opts.cornerRadius ? textTop + opts.spikeGirth/2 + opts.cornerRadius : crossPoint.y; - crossPoint.y = crossPoint.y > (textBottom - opts.spikeGirth/2) - opts.cornerRadius ? (textBottom - opts.spikeGirth/2) - opts.cornerRadius : crossPoint.y; - points[points.length] = {x: textRight, y: crossPoint.y + opts.spikeGirth/2, type: 'join'}; - points[points.length] = {x: textRight, y: textBottom, type: 'corner'}; // right bottom corner - points[points.length] = {x: textLeft, y: textBottom, type: 'corner'}; // left bottom corner - points[points.length] = {x: textLeft, y: textTop, type: 'corner'}; // left top corner - points[points.length] = {x: textRight, y: textTop, type: 'corner'}; // right top corner - points[points.length] = {x: textRight, y: crossPoint.y - opts.spikeGirth/2, type: 'join'}; - points[points.length] = spikePoint; - break; - case 'bottom': - // spike on top - $text.css('margin-top', opts.spikeLength + 'px'); - $box.css({top: (top + height + animDist) - opts.overlap, left: horiz}); - // move text up/down if extends out of window - textRightSpace = (winRight - opts.windowMargin) - ($text.offset().left + $text.outerWidth(true)); - var xShift = 0; - if (textRightSpace < 0) { - // shift it left - $box.css('left', (numb($box.css('left')) + textRightSpace) + 'px'); - xShift -= textRightSpace; - } - // we ensure left space second to ensure that left of box is visible - textLeftSpace = ($text.offset().left + numb($text.css('margin-left'))) - (scrollLeft + opts.windowMargin); - if (textLeftSpace < 0) { - // shift it right - $box.css('left', (numb($box.css('left')) - textLeftSpace) + 'px'); - xShift += textLeftSpace; - } - textTop = $text.btPosition().top + numb($text.css('margin-top')); - textLeft = $text.btPosition().left + numb($text.css('margin-left')); - textRight = textLeft + $text.outerWidth(); - textBottom = textTop + $text.outerHeight(); - textCenter = {x: textLeft + ($text.outerWidth()/2), y: textTop + ($text.outerHeight()/2)}; - points[points.length] = spikePoint = {x: ((textRight-textLeft)/2) + xShift, y: 0, type: 'spike'}; - crossPoint = findIntersectX(spikePoint.x, spikePoint.y, textCenter.x, textCenter.y, textTop); - // make sure that the crossPoint is not outside of text box boundaries - crossPoint.x = crossPoint.x < textLeft + opts.spikeGirth/2 + opts.cornerRadius ? textLeft + opts.spikeGirth/2 + opts.cornerRadius : crossPoint.x; - crossPoint.x = crossPoint.x > (textRight - opts.spikeGirth/2) - opts.cornerRadius ? (textRight - opts.spikeGirth/2) - opts.cornerRadius : crossPoint.x; - points[points.length] = {x: crossPoint.x + opts.spikeGirth/2, y: textTop, type: 'join'}; - points[points.length] = {x: textRight, y: textTop, type: 'corner'}; // right top corner - points[points.length] = {x: textRight, y: textBottom, type: 'corner'}; // right bottom corner - points[points.length] = {x: textLeft, y: textBottom, type: 'corner'}; // left bottom corner - points[points.length] = {x: textLeft, y: textTop, type: 'corner'}; // left top corner - points[points.length] = {x: crossPoint.x - (opts.spikeGirth/2), y: textTop, type: 'join'}; - points[points.length] = spikePoint; - break; - case 'right': - // spike on left - $text.css('margin-left', (opts.spikeLength + 'px')); - $box.css({top: vert + 'px', left: ((left + width + animDist) - opts.overlap) + 'px'}); - // move text up/down if extends out of window - textBottomSpace = (winBottom - opts.windowMargin) - ($text.offset().top + $text.outerHeight(true)); - var yShift = 0; - if (textBottomSpace < 0) { - // shift it up - $box.css('top', (numb($box.css('top')) + textBottomSpace) + 'px'); - yShift -= textBottomSpace; - } - // we ensure top space second to ensure that top of box is visible - textTopSpace = ($text.offset().top + numb($text.css('margin-top'))) - (scrollTop + opts.windowMargin); - if (textTopSpace < 0) { - // shift it down - $box.css('top', (numb($box.css('top')) - textTopSpace) + 'px'); - yShift += textTopSpace; - } - textTop = $text.btPosition().top + numb($text.css('margin-top')); - textLeft = $text.btPosition().left + numb($text.css('margin-left')); - textRight = textLeft + $text.outerWidth(); - textBottom = textTop + $text.outerHeight(); - textCenter = {x: textLeft + ($text.outerWidth()/2), y: textTop + ($text.outerHeight()/2)}; - points[points.length] = spikePoint = {x: 0, y: ((textBottom-textTop)/2) + yShift, type: 'spike'}; - crossPoint = findIntersectY(spikePoint.x, spikePoint.y, textCenter.x, textCenter.y, textLeft); - // make sure that the crossPoint is not outside of text box boundaries - crossPoint.y = crossPoint.y < textTop + opts.spikeGirth/2 + opts.cornerRadius ? textTop + opts.spikeGirth/2 + opts.cornerRadius : crossPoint.y; - crossPoint.y = crossPoint.y > (textBottom - opts.spikeGirth/2) - opts.cornerRadius ? (textBottom - opts.spikeGirth/2) - opts.cornerRadius : crossPoint.y; - points[points.length] = {x: textLeft, y: crossPoint.y - opts.spikeGirth/2, type: 'join'}; - points[points.length] = {x: textLeft, y: textTop, type: 'corner'}; // left top corner - points[points.length] = {x: textRight, y: textTop, type: 'corner'}; // right top corner - points[points.length] = {x: textRight, y: textBottom, type: 'corner'}; // right bottom corner - points[points.length] = {x: textLeft, y: textBottom, type: 'corner'}; // left bottom corner - points[points.length] = {x: textLeft, y: crossPoint.y + opts.spikeGirth/2, type: 'join'}; - points[points.length] = spikePoint; - break; - } // - - var canvas = $('').appendTo($box).css({position: 'absolute', top: $text.btPosition().top, left: $text.btPosition().left, zIndex: opts.boxzIndex}).get(0); - - // if excanvas is set up, we need to initialize the new canvas element - if (typeof G_vmlCanvasManager != 'undefined') { - canvas = G_vmlCanvasManager.initElement(canvas); - } - - if (opts.cornerRadius > 0) { - // round the corners! - var newPoints = new Array(); - var newPoint; - for (var i=0; i 0) { - ctx.lineWidth = opts.strokeWidth; - ctx.strokeStyle = opts.strokeStyle; - ctx.beginPath(); - drawIt.apply(ctx, [points]); - ctx.closePath(); - ctx.stroke(); - } - - if (opts.animate) { - $box.css({opacity: 0.1}); - } - - $box.css({visibility: 'visible'}); - - if (opts.overlay) { - var overlay = $('
').css({ - position: 'absolute', - backgroundColor: 'blue', - top: top, - left: left, - width: width, - height: height, - opacity: '.2' - }).appendTo(offsetParent); - $(this).data('overlay', overlay); - } - - var animParams = {opacity: 1}; - if (opts.animate) { - switch (position) { - case 'top': - animParams.top = $box.btPosition().top + opts.distance; - break; - case 'left': - animParams.left = $box.btPosition().left + opts.distance; - break; - case 'bottom': - animParams.top = $box.btPosition().top - opts.distance; - break; - case 'right': - animParams.left = $box.btPosition().left - opts.distance; - break; - } - $box.animate(animParams, {duration: opts.speed, easing: opts.easing}); - } - - // trigger postShow function - opts.postShow.apply(this); - - - } // - - var turnOff = function() { - - // trigger preHide function - opts.preHide.apply(this); - - var box = $(this).data('bt-box'); - var overlay = $(this).data('bt-overlay'); - if (typeof box == 'object') { - $(box).remove(); - $(this).removeData('bt-box'); - } - if (typeof overlay == 'object') { - $(overlay).remove(); - $(this).removeData('bt-overlay'); - } - - // trigger postHide function - opts.postHide.apply(this); - - } // - - var refresh = function() { - turnOff.apply(this); - turnOn.apply(this); - } - - /** - * This is sort of the "starting spot" for the this.each() - * These are sort of the init functions to handle the call - */ - - if (opts.killTitle) { - $(this).find('[title]').andSelf().each(function() { - $(this).attr('bt-xTitle', $(this).attr('title')).removeAttr('title'); - }); - } - if (typeof opts.trigger == 'string') { - opts.trigger = [opts.trigger]; - } - if (opts.trigger[0] == 'hover') { - $(this).hover( - function() { - turnOn.apply(this); - }, - function() { - turnOff.apply(this); - } - ); - } - else if (opts.trigger[0] == 'now') { - var box = $(this).data('bt-box'); - if (typeof box == 'object') { - turnOff.apply(this); - } - else { - turnOn.apply(this); - } - } - else if (opts.trigger.length > 1 && opts.trigger[0] != opts.trigger[1]) { - $(this) - .bind(opts.trigger[0], function() { - turnOn.apply(this); - }) - .bind(opts.trigger[1], function() { - turnOff.apply(this); - }); - } - else { - // toggle using the same event - $(this).bind(opts.trigger[0], function() { - if (typeof this.triggerToggle == 'undefined') { - this.triggerToggle = false; - } - this.triggerToggle = !this.triggerToggle; - if (this.triggerToggle) { - turnOn.apply(this); - } - else { - turnOff.apply(this); - } - }); - } - }); // - - - function drawIt(points) { - this.moveTo(points[0].x, points[0].y); - for (i=1;i arcEnd.y) { - // arc is on upper left - startAngle = (Math.PI/180)*180; - endAngle = (Math.PI/180)*90; - } - else { - // arc is on upper right - startAngle = (Math.PI/180)*90; - endAngle = 0; - } - } - else { - if (arcStart.y > arcEnd.y) { - // arc is on lower left - startAngle = (Math.PI/180)*270; - endAngle = (Math.PI/180)*180; - } - else { - // arc is on lower right - startAngle = 0; - endAngle = (Math.PI/180)*270; - } - } - return {x: x, y: y, type: 'center', startAngle: startAngle, endAngle: endAngle}; - } - - /** - * Find the intersection point of two lines, each defined by two points - * arguments are x1, y1 and x2, y2 for r1 (line 1) and r2 (line 2) - * It's like an algebra party!!! - */ - function findIntersect(r1x1, r1y1, r1x2, r1y2, r2x1, r2y1, r2x2, r2y2) { - - if (r2x1 == r2x2) { - return findIntersectY(r1x1, r1y1, r1x2, r1y2, r2x1); - } - if (r2y1 == r2y2) { - return findIntersectX(r1x1, r1y1, r1x2, r1y2, r2y1); - } - - // m = (y1 - y2) / (x1 - x2) // <-- how to find the slope - // y = mx + b // the 'classic' linear equation - // b = y - mx // how to find b (the y-intersect) - // x = (y - b)/m // how to find x - var r1m = (r1y1 - r1y2) / (r1x1 - r1x2); - var r1b = r1y1 - (r1m * r1x1); - var r2m = (r2y1 - r2y2) / (r2x1 - r2x2); - var r2b = r2y1 - (r2m * r2x1); - - var x = (r2b - r1b) / (r1m - r2m); - var y = r1m * x + r1b; - - return {x: x, y: y}; - } - - /** - * Find the y intersection point of a line and given x vertical - */ - function findIntersectY(r1x1, r1y1, r1x2, r1y2, x) { - if (r1y1 == r1y2) { - return {x: x, y: r1y1}; - } - var r1m = (r1y1 - r1y2) / (r1x1 - r1x2); - var r1b = r1y1 - (r1m * r1x1); - - var y = r1m * x + r1b; - - return {x: x, y: y}; - } - - /** - * Find the x intersection point of a line and given y horizontal - */ - function findIntersectX(r1x1, r1y1, r1x2, r1y2, y) { - if (r1x1 == r1x2) { - return {x: r1x1, y: y}; - } - var r1m = (r1y1 - r1y2) / (r1x1 - r1x2); - var r1b = r1y1 - (r1m * r1x1); - - // y = mx + b // your old friend, linear equation - // x = (y - b)/m // linear equation solved for x - var x = (y - r1b) / r1m; - - return {x: x, y: y}; - - } - -}; // - -/** - * jQuery's compat.js (used in Drupal's jQuery upgrade module, overrides the $().position() function - * this is a copy of that function to allow the plugin to work when compat.js is present - * once compat.js is fixed to not override existing functions, this function can be removed - * and .btPosion() can be replaced with .position() above... - */ -jQuery.fn.btPosition = function() { - - function num(elem, prop) { - return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0; - } - - var left = 0, top = 0, results; - - if ( this[0] ) { - // Get *real* offsetParent - var offsetParent = this.offsetParent(), - - // Get correct offsets - offset = this.offset(), - parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset(); - - // Subtract element margins - // note: when an element has margin: auto the offsetLeft and marginLeft - // are the same in Safari causing offset.left to incorrectly be 0 - offset.top -= num( this, 'marginTop' ); - offset.left -= num( this, 'marginLeft' ); - - // Add offsetParent borders - parentOffset.top += num( offsetParent, 'borderTopWidth' ); - parentOffset.left += num( offsetParent, 'borderLeftWidth' ); - - // Subtract the two offsets - results = { - top: offset.top - parentOffset.top, - left: offset.left - parentOffset.left - }; - } - - return results; -}; // - - -/** - * Defaults for the beauty tips - * - * Note this is a variable definition and not a function. So defaults can be - * written for an entire page by simply redefining attributes like so: - * - * jQuery.fn.bt.defaults.width = 400; - * - * This would make all Beauty Tips boxes 400px wide. - * - * Each of these options may also be overridden during - * - * Can be overriden globally or at time of call. - * - */ -jQuery.fn.bt.defaults = { - trigger: 'hover', // trigger to show/hide tip - // use [on, off] to define separate on/off triggers - // also use space character to allow multiple events to trigger - // examples: - // ['focus', 'blur'] // focus displays, blur hides - // 'dblclick' // dblclick toggles on/off - // ['focus mouseover', 'blur mouseout'] - // 'now' // shows/hides tip without event - - width: 200, // width (in px) of tooltip box - // when combined with cssStyles: {width: 'auto'}, this becomes a max-width for the text - padding: 10, // padding for content (get more fine grained with cssStyles) - spikeGirth: 10, // width of spike - spikeLength: 15, // length of spike - overlap: 0, // spike overlap (px) onto target - overlay: false, // display overlay on target (use CSS to style) -- BUGGY! - killTitle: true, // kill title tag to avoid double tooltips - - textzIndex: 9999, // z-index for the text - boxzIndex: 9990, // z-index for the "talk" box (should always be less than textzIndex) - positions: ['most'], // preference of positions for tip (will use first with available space) - // possible values 'top', 'bottom', 'left', 'right' as an array in order of - // preference. Last value will be used if others don't have enough space. - - // or use 'most' to use the area with the most space - fill: "rgb(255, 255, 102)", // fill color for the tooltip box - windowMargin: 10, // space (px) to leave between text box and browser edge - - strokeWidth: 1, // width of stroke around box, **set to 0 for no stroke** - strokeStyle: "#000", // color/alpha of stroke - - cornerRadius: 5, // radius of corners (px), set to 0 for square corners - - shadow: false, // use drop shadow? (only displays in Safari and FF 3.1) - shadowOffsetX: 2, // shadow offset x (px) - shadowOffsetY: 2, // shadow offset y (px) - shadowBlur: 3, // shadow blur (px) - shadowColor: "#000", // shadow color/alpha - - animate: false, // animate show/hide of box - EXPERIMENTAL (buggy in IE) - distance: 15, // distance of animation movement (px) - easing: 'swing', // animation easing - speed: 200, // speed (ms) of animation - - cssClass: '', // CSS class to add to the box wrapper div - cssStyles: {}, // styles to add the text box - // example: {fontFamily: 'Georgia, Times, serif', fontWeight: 'bold'} - - titleSelector: "attr('title')", // if there is no content argument, use this selector to retrieve the title - - preShow: function(){return;}, // function to run before popup is built and displayed - postShow: function(){return;}, // function to run after popup is built and displayed - preHide: function(){return;}, // function to run before popup is removed - postHide: function(){return;} // function to run after popup is removed - -}; // diff -r be2c150d1a1f -r 8566fb2b8012 app/soc/content/css/soc-090421.css --- a/app/soc/content/css/soc-090421.css Fri May 01 01:37:43 2009 +0200 +++ b/app/soc/content/css/soc-090421.css Mon May 04 19:23:44 2009 +0200 @@ -229,6 +229,59 @@ padding: 2px; } +/* TOOLTIPS */ + +#purr-container { + position: fixed; + bottom: 0; + right: 0; +} + +.tooltip { + position: relative; + width: 300px; +} + +.tooltip .close { + position: absolute; + top: 12px; + right: 12px; + display: block; + width: 18px; + height: 17px; + text-indent: -9999px; + background: url('/soc/content/images/purrClose.png') no-repeat 0 10px; +} + +.tooltip-body { + min-height: 50px; + padding: 22px 22px 0 22px; + background: url('/soc/content/images/purrTop.png') no-repeat left top; + color: #f9f9f9; +} + +.tooltip-body img { + width: 50px; + margin: 0 10px 0 0; + float: left; +} + +.tooltip-body h3 { + margin: 0; + font-size: 1.1em; +} + +.tooltip-body p { + margin: 5px 0 0 60px; + font-size: 0.8em; + line-height: 1.4em; +} + +.tooltip-bottom { + height: 22px; + background: url('/soc/content/images/purrBottom.png') no-repeat left top; +} + /* * PAGE ELEMENTS */ diff -r be2c150d1a1f -r 8566fb2b8012 app/soc/content/js/tips-081027.js --- a/app/soc/content/js/tips-081027.js Fri May 01 01:37:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -$(function() { - // Change 'title' to something else first - $('tr[title]').each(function() { - $(this).attr('xtitle', $(this).attr('title')).removeAttr('title'); - }) - .children().children(':input') - // Set up event handlers - .bt({trigger: ['helperon', 'helperoff'], - titleSelector: "parent().parent().attr('xtitle')", - killTitle: false, - fill: 'rgba(135, 206, 250, .9)', - positions: ['bottom', 'top', 'right'] - }) - .bind('focus', function() { - $(this).trigger('helperon'); - }) - .bind('blur', function() { - $(this).trigger('helperoff'); - }) - .parent() - .bind('mouseover', function() { - $(this).children(':input').trigger('helperon'); - }) - .bind('mouseleave', function() { - $(this).children(':input').trigger('helperoff'); - }); -}); - diff -r be2c150d1a1f -r 8566fb2b8012 app/soc/templates/soc/base.html --- a/app/soc/templates/soc/base.html Fri May 01 01:37:43 2009 +0200 +++ b/app/soc/templates/soc/base.html Mon May 04 19:23:44 2009 +0200 @@ -55,9 +55,6 @@ {% if uses_json %} {% endif %} - {% if uses_jq_bt %} - - {% endif %} {% if uses_menu %} {% endif %} @@ -67,9 +64,6 @@ {% if uses_jq_spin %} {% endif %} - {% if uses_jq_bt %} - - {% endif %} {% if uses_jq_bgiframe %} {% endif %} diff -r be2c150d1a1f -r 8566fb2b8012 app/soc/templates/soc/templatetags/_as_table_row.html --- a/app/soc/templates/soc/templatetags/_as_table_row.html Fri May 01 01:37:43 2009 +0200 +++ b/app/soc/templates/soc/templatetags/_as_table_row.html Mon May 04 19:23:44 2009 +0200 @@ -27,7 +27,7 @@ {% block label_row %}{% endblock %} - + {% block label_column %} {{ label }} @@ -51,6 +51,22 @@ ); {% endif %} + {% if help_text %} + + {% endif %} {{ field|safe }} diff -r be2c150d1a1f -r 8566fb2b8012 app/soc/views/helper/params.py --- a/app/soc/views/helper/params.py Fri May 01 01:37:43 2009 +0200 +++ b/app/soc/views/helper/params.py Mon May 04 19:23:44 2009 +0200 @@ -54,7 +54,6 @@ 'jq_ajaqQueue', 'jq_autocomplete', 'jq_bgiframe', - 'jq_bt', 'jq_purr', 'jq_spin', 'jq_datetimepicker', @@ -240,8 +239,8 @@ new_params['js_uses_all'] = DEF_JS_USES_LIST new_params['js_uses_list'] = ['jq', 'menu'] new_params['js_uses_show'] = ['jq', 'menu'] - new_params['js_uses_edit'] = ['jq', 'menu', 'tinymce', 'jq_bt', - 'jq_purr','jq_spin','jq_autocomplete'] + new_params['js_uses_edit'] = ['jq', 'menu', 'tinymce', 'jq_purr', + 'jq_spin', 'jq_autocomplete'] new_params['error_public'] = 'soc/%(module_name)s/error.html' % params new_params['error_export'] = new_params['error_public']