/* * Tooltip - jQuery plugin  for styled tooltips * * Copyright (c) 2006 Jörn Zaefferer, Stefan Petre * * Dual licensed under the MIT and GPL licenses: *   http://www.opensource.org/licenses/mit-license.php *   http://www.gnu.org/licenses/gpl.html * *//** * Display a customized tooltip instead of the default one * for every selected element. The tooltip behaviour mimics * the default one, but lets you style the tooltip and * specify the delay before displaying it. * * In addition, it displays the href value, if it is available. *  * To style the tooltip, use these selectors in your stylesheet: * * #tooltip - The tooltip container * * #tooltip h3 - The tooltip title * * #tooltip p.body - The tooltip body, shown when using showBody * * #tooltip p.url - The tooltip url, shown when using showURL * * @example $('a, input, img').Tooltip(); * @desc Shows tooltips for anchors, inputs and images, if they have a title * * @example $('label').Tooltip({ *   delay: 0, *   track: true, *   event: "click" * }); * @desc Shows tooltips for labels with no delay, tracking mousemovement, displaying the tooltip when the label is clicked. * * @example // modify global settings * $.extend($.fn.Tooltip.defaults, { * 	track: true, * 	delay: 0, * 	showURL: false, * 	showBody: " - ", *  fixPNG: true * }); * // setup fancy tooltips * $('a.pretty').Tooltip({ * 	 extraClass: "fancy" * }); $('img.pretty').Tooltip({ * 	 extraClass: "fancy-img", * }); * @desc This example starts with modifying the global settings, applying them to all following Tooltips; Afterwards, Tooltips for anchors with class pretty are created with an extra class for the Tooltip: "fancy" for anchors, "fancy-img" for images * * @param Object settings (optional) Customize your Tooltips * @option Number delay The number of milliseconds before a tooltip is display, default is 250 * @option String event The event on which the tooltip is displayed, default is "mouseover", "click" works fine, too * @option Boolean track If true, let the tooltip track the mousemovement, default is false * @option Boolean showURL If true, shows the href or src attribute within p.url, default is true * @option String showBody If specified, uses the String to split the title, displaying the first part in the h3 tag, all following in the p.body tag, separated with <br/>s, default is null * @option String extraClass If specified, adds the class to the tooltip helper, default is null * @option Boolean fixPNG If true, fixes transparent PNGs in IE, default is false * * @name Tooltip * @type jQuery * @cat Plugins/Tooltip * @author Jörn Zaefferer (http://bassistance.de) */(function($) {// the tooltip elementvar helper,// it's title parttTitle,// it's body parttBody,// it's url parttUrl,// the current tooltipped elementcurrent,// the title of the current element, used for restoringoldTitle,// timeout id for delayed tooltipstID;// the public plugin method$.fn.Tooltip = function(settings) {// setup configuration// TODO: allow multiple arguments to extend, see bug #344settings = $.extend($.extend({}, arguments.callee.defaults), settings || {});// there can be only one tooltip helperif( !helper ) {// create the helper, h3 for title, div for urlhelper = $('<div id="tooltip"><h3></h3><p class="body"></p><p class="url"></p></div>')// hide it at first.hide()// move to top and position absolute, to let it follow the mouse.css({ position: 'absolute', zIndex: 3000 })// add to document.appendTo('body');// save references to title and url elementstTitle = $('h3', helper);tBody = $('p:eq(0)', helper);tUrl = $('p:eq(1)', helper);}// bind events for every selected element with a title attribute$(this).filter('[@title]')// save settings into each element// TODO: pass settings via event system, not yet possible.each(function() {this.tSettings = settings;})// bind events.bind("mouseover", save).bind(settings.event, handle);return this;};// main event handler to start showing tooltipsfunction handle(event) {// show helper, either with timeout or on instantif( this.tSettings.delay )tID = setTimeout(show, this.tSettings.delay);elseshow();// if selected, update the helper position when the mouse movesif(this.tSettings.track)$('body').bind('mousemove', update);// update at least onceupdate(event);// hide the helper when the mouse moves out of the element$(this).bind('mouseout', hide);}// save elements title before the tooltip is displayedfunction save() {// if this is the current source, or it has no title (occurs with click event), stopif(this == current || !this.title)return;// save currentcurrent = this;var source = $(this),settings = this.tSettings;// save title, remove from element and set to helperoldTitle = title = source.attr('title');source.attr('title','');if(settings.showBody) {var parts = title.split(settings.showBody);tTitle.html(parts.shift());tBody.empty();for(var i = 0, part; part = parts[i]; i++) {if(i > 0)tBody.append("<br/>");tBody.append(part);}if(tBody.html())tBody.show();elsetBody.hide();} else {tTitle.html(title);tBody.hide();}// if element has href or src, add and show it, otherwise hide ithref = (source.attr('href') || source.attr('src'));if( settings.showURL && href )tUrl.html(href.replace('http://', '')).show();else tUrl.hide();// add an optional class for this tipif( settings.extraClass ) {helper.addClass(settings.extraClass);}// fix PNG background for IEif (settings.fixPNG && $.browser.msie ) {helper.each(function () {if (this.currentStyle.backgroundImage != 'none') {var image = this.currentStyle.backgroundImage;image = image.substring(5, image.length - 2);$(this).css({'backgroundImage': 'none','filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"});}});}}// delete timeout and show helperfunction show() {tID = null;helper.show();update();}/** * callback for mousemove * updates the helper position * removes itself when no current element */function update(event)	{// if no current element is available, remove this listenerif( current == null ) {$('body').unbind('mousemove', update);return;	}var left = helper[0].offsetLeft;var top = helper[0].offsetTop;if(event) {// get the current mouse positionfunction pos(c) {var p = c == 'X' ? 'Left' : 'Top';return event['page' + c] || (event['client' + c] + (document.documentElement['scroll' + p] || document.body['scroll' + p])) || 0;}// position the helper 15 pixel to bottom right, starting from mouse positionleft = pos('X') + 15;top = pos('Y') + 15;helper.css({left: left + 'px',top: top + 'px'});}var v = viewport(),h = helper[0];// check horizontal positionif(v.x + v.cx < h.offsetLeft + h.offsetWidth) {left -= h.offsetWidth + 20;helper.css({left: left + 'px'});}// check vertical positionif(v.y + v.cy < h.offsetTop + h.offsetHeight) {top -= h.offsetHeight + 20;helper.css({top: top + 'px'});}}function viewport() {var e = document.documentElement || {},b = document.body || {},w = window;return {x: w.pageXOffset || e.scrollLeft || b.scrollLeft || 0,y: w.pageYOffset || e.scrollTop || b.scrollTop || 0,cx: min( e.clientWidth, b.clientWidth, w.innerWidth ),cy: min( e.clientHeight, b.clientHeight, w.innerHeight )};function min() {var v = Infinity;for( var i = 0;  i < arguments.length;  i++ ) {var n = arguments[i];if( n && n < v ) v = n;}return v;}}// hide helper and restore added classes and the titlefunction hide() {// clear timeout if possibleif(tID)clearTimeout(tID);// no more current elementcurrent = null;helper.hide();// remove optional classif( this.tSettings.extraClass ) {helper.removeClass( this.tSettings.extraClass);}// restore title and remove this listener$(this).attr('title', oldTitle).unbind('mouseout', hide);// remove PNG background fix for IEif( this.tSettings.fixPNG && $.browser.msie ) {helper.each(function () {$(this).css({'filter': '', backgroundImage: ''});});}}// define global defaults, editable by client$.fn.Tooltip.defaults = {delay: 250,event: "mouseover",track: false,showURL: true,showBody: null,extraClass: null,fixPNG: false};})(jQuery);