(no commit message)
[atutor.git] / jscripts / fluid-components / js / jquery / jquery.tooltip.js
1 /*
2  * jQuery Tooltip plugin 1.2
3  *
4  * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
5  * http://docs.jquery.com/Plugins/Tooltip
6  *
7  * Copyright (c) 2006 - 2008 Jörn Zaefferer
8  *
9  * $Id: jquery.tooltip.js 5243 2008-07-18 22:13:15Z antranig@caret.cam.ac.uk $
10  * 
11  * Dual licensed under the MIT and GPL licenses:
12  *   http://www.opensource.org/licenses/mit-license.php
13  *   http://www.gnu.org/licenses/gpl.html
14  */
15  
16 ;(function($) {
17         
18                 // the tooltip element
19         var helper = {},
20                 // the current tooltipped element
21                 current,
22                 // the title of the current element, used for restoring
23                 title,
24                 // timeout id for delayed tooltips
25                 tID,
26                 // IE 5.5 or 6
27                 IE = $.browser.msie && /MSIE\s(5\.5|6\.)/.test(navigator.userAgent),
28                 // flag for mouse tracking
29                 track = false;
30         
31         $.tooltip = {
32                 blocked: false,
33                 defaults: {
34                         delay: 200,
35                         showURL: true,
36                         extraClass: "",
37                         top: 15,
38                         left: 15,
39                         id: "tooltip"
40                 },
41                 block: function() {
42                         $.tooltip.blocked = !$.tooltip.blocked;
43                 }
44         };
45         
46         $.fn.extend({
47                 tooltip: function(settings) {
48                         settings = $.extend({}, $.tooltip.defaults, settings);
49                         createHelper(settings);
50                         return this.each(function() {
51                                         $.data(this, "tooltip-settings", settings);
52                                         // copy tooltip into its own expando and remove the title
53                                         this.tooltipText = this.title;
54                                         $(this).removeAttr("title");
55                                         // also remove alt attribute to prevent default tooltip in IE
56                                         this.alt = "";
57                                 })
58                                 .hover(save, hide)
59                                 .click(hide);
60                 },
61                 fixPNG: IE ? function() {
62                         return this.each(function () {
63                                 var image = $(this).css('backgroundImage');
64                                 if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
65                                         image = RegExp.$1;
66                                         $(this).css({
67                                                 'backgroundImage': 'none',
68                                                 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
69                                         }).each(function () {
70                                                 var position = $(this).css('position');
71                                                 if (position != 'absolute' && position != 'relative')
72                                                         $(this).css('position', 'relative');
73                                         });
74                                 }
75                         });
76                 } : function() { return this; },
77                 unfixPNG: IE ? function() {
78                         return this.each(function () {
79                                 $(this).css({'filter': '', backgroundImage: ''});
80                         });
81                 } : function() { return this; },
82                 hideWhenEmpty: function() {
83                         return this.each(function() {
84                                 $(this)[ $(this).html() ? "show" : "hide" ]();
85                         });
86                 },
87                 url: function() {
88                         return this.attr('href') || this.attr('src');
89                 }
90         });
91         
92         function createHelper(settings) {
93                 // there can be only one tooltip helper
94                 if( helper.parent )
95                         return;
96                 // create the helper, h3 for title, div for url
97                 helper.parent = $('<div id="' + settings.id + '"><h3></h3><div class="body"></div><div class="url"></div></div>')
98                         // add to document
99                         .appendTo(document.body)
100                         // hide it at first
101                         .hide();
102                         
103                 // apply bgiframe if available
104                 if ( $.fn.bgiframe )
105                         helper.parent.bgiframe();
106                 
107                 // save references to title and url elements
108                 helper.title = $('h3', helper.parent);
109                 helper.body = $('div.body', helper.parent);
110                 helper.url = $('div.url', helper.parent);
111         }
112         
113         function settings(element) {
114                 return $.data(element, "tooltip-settings");
115         }
116         
117         // main event handler to start showing tooltips
118         function handle(event) {
119                 // show helper, either with timeout or on instant
120                 if( settings(this).delay )
121                         tID = setTimeout(show, settings(this).delay);
122                 else
123                         show();
124                 
125                 // if selected, update the helper position when the mouse moves
126                 track = !!settings(this).track;
127                 $(document.body).bind('mousemove', update);
128                         
129                 // update at least once
130                 update(event);
131         }
132         
133         // save elements title before the tooltip is displayed
134         function save() {
135                 // if this is the current source, or it has no title (occurs with click event), stop
136                 if ( $.tooltip.blocked || this == current || (!this.tooltipText && !settings(this).bodyHandler) )
137                         return;
138
139                 // save current
140                 current = this;
141                 title = this.tooltipText;
142                 
143                 if ( settings(this).bodyHandler ) {
144                         helper.title.hide();
145                         var bodyContent = settings(this).bodyHandler.call(this);
146                         if (bodyContent.nodeType || bodyContent.jquery) {
147                                 helper.body.empty().append(bodyContent)
148                         } else {
149                                 helper.body.html( bodyContent );
150                         }
151                         helper.body.show();
152                 } else if ( settings(this).showBody ) {
153                         var parts = title.split(settings(this).showBody);
154                         helper.title.html(parts.shift()).show();
155                         helper.body.empty();
156                         for(var i = 0, part; part = parts[i]; i++) {
157                                 if(i > 0)
158                                         helper.body.append("<br/>");
159                                 helper.body.append(part);
160                         }
161                         helper.body.hideWhenEmpty();
162                 } else {
163                         helper.title.html(title).show();
164                         helper.body.hide();
165                 }
166                 
167                 // if element has href or src, add and show it, otherwise hide it
168                 if( settings(this).showURL && $(this).url() )
169                         helper.url.html( $(this).url().replace('http://', '') ).show();
170                 else 
171                         helper.url.hide();
172                 
173                 // add an optional class for this tip
174                 helper.parent.addClass(settings(this).extraClass);
175
176                 // fix PNG background for IE
177                 if (settings(this).fixPNG )
178                         helper.parent.fixPNG();
179                         
180                 handle.apply(this, arguments);
181         }
182         
183         // delete timeout and show helper
184         function show() {
185                 tID = null;
186                 helper.parent.show();
187                 update();
188         }
189         
190         /**
191          * callback for mousemove
192          * updates the helper position
193          * removes itself when no current element
194          */
195         function update(event)  {
196                 if($.tooltip.blocked)
197                         return;
198                 
199                 // stop updating when tracking is disabled and the tooltip is visible
200                 if ( !track && helper.parent.is(":visible")) {
201                         $(document.body).unbind('mousemove', update)
202                 }
203                 
204                 // if no current element is available, remove this listener
205                 if( current == null ) {
206                         $(document.body).unbind('mousemove', update);
207                         return; 
208                 }
209                 
210                 // remove position helper classes
211                 helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");
212                 
213                 var left = helper.parent[0].offsetLeft;
214                 var top = helper.parent[0].offsetTop;
215                 if(event) {
216                         // position the helper 15 pixel to bottom right, starting from mouse position
217                         left = event.pageX + settings(current).left;
218                         top = event.pageY + settings(current).top;
219                         helper.parent.css({
220                                 left: left + 'px',
221                                 top: top + 'px'
222                         });
223                 }
224                 
225                 var v = viewport(),
226                         h = helper.parent[0];
227                 // check horizontal position
228                 if(v.x + v.cx < h.offsetLeft + h.offsetWidth) {
229                         left -= h.offsetWidth + 20 + settings(current).left;
230                         helper.parent.css({left: left + 'px'}).addClass("viewport-right");
231                 }
232                 // check vertical position
233                 if(v.y + v.cy < h.offsetTop + h.offsetHeight) {
234                         top -= h.offsetHeight + 20 + settings(current).top;
235                         helper.parent.css({top: top + 'px'}).addClass("viewport-bottom");
236                 }
237         }
238         
239         function viewport() {
240                 return {
241                         x: $(window).scrollLeft(),
242                         y: $(window).scrollTop(),
243                         cx: $(window).width(),
244                         cy: $(window).height()
245                 };
246         }
247         
248         // hide helper and restore added classes and the title
249         function hide(event) {
250                 if($.tooltip.blocked)
251                         return;
252                 // clear timeout if possible
253                 if(tID)
254                         clearTimeout(tID);
255                 // no more current element
256                 current = null;
257                 
258                 helper.parent.hide().removeClass( settings(this).extraClass );
259                 
260                 if( settings(this).fixPNG )
261                         helper.parent.unfixPNG();
262         }
263         
264         $.fn.Tooltip = $.fn.tooltip;
265         
266 })(jQuery);