The actual commit.
[redakcja.git] / project / static / js / lib / jquery.wtooltip.js
1 /* Wayfarer Tooltip\r
2  * Version 1.0.4\r
3  * Author Abel Mohler\r
4  * URI: http://www.wayfarerweb.com/wtooltip.php\r
5  * Released with the MIT License: http://www.wayfarerweb.com/mit.php\r
6  */\r
7 (function($){ //jQuery.noConflict()compliant\r
8     $.fn.wTooltip = function(o, callback){\r
9         o = $.extend({ //defaults, can be overidden\r
10             content: null, //string content for tooltip.\r
11             ajax: null, //path to content for tooltip\r
12             follow: true, //does tooltip follow the cursor?\r
13             auto: true, //If false, tooltip won't automatically transition, it must be manually shown/hidden\r
14             fadeIn: 0, //fade in, in milliseconds ("fast, "slow", etc may also be used)\r
15             fadeOut: 0, //fade out, in milliseconds ("fast, "slow", etc may also be used)\r
16             appendTip: document.body, //should probably not need to be overridden\r
17             degrade: false, //if true, in IE6 tooltip will degrade to a title attribute message\r
18             offsetY: 10, //offsetY and offsetX properties designate position from the cursor\r
19             offsetX: 1,\r
20             style: {},\r
21             className: null, //to style the tooltip externally, pass a className or id\r
22             id: null,\r
23             callBefore: function(tooltip, node, settings){\r
24             }, //called when mouse enters the area\r
25             callAfter: function(tooltip, node, settings){\r
26             }, //called when mouse leaves the area (same as "callback" option)\r
27             clickAction: function(tooltip, node){\r
28                 $(tooltip).hide();\r
29             }, //called when the element is clicked, with access to tooltip\r
30             delay: 0, //delay (in milliseconds)before tooltip appears and callBefore executes\r
31             timeout: 0, //delay (in milliseconds)before tooltip transitions away, and callAfter executes\r
32             cloneable: false //UNWORKING.  Requires $().wClone plugin. If true, tooltip may be dragged and placed anywhere on the screen.\r
33         }, o ||\r
34         {});\r
35         \r
36         if (!o.style && typeof o.style != "object") {\r
37             o.style = {};\r
38             o.style.zIndex = "1000";\r
39         }\r
40         else {\r
41             o.style = $.extend({ //the default style rules of the tooltip\r
42                 border: "1px solid gray",\r
43                 background: "#edeef0",\r
44                 color: "#000",\r
45                 padding: "10px",\r
46                 zIndex: "1000",\r
47                 textAlign: "left"\r
48             }, o.style ||\r
49             {});\r
50         }\r
51         \r
52         if (typeof callback == "function") \r
53             o.callAfter = callback || o.callAfter;\r
54         \r
55         o.style.display = "none", o.style.position = "absolute"; //permanent defaults\r
56         //private settings\r
57         var title, timeout, timeout2, iId, over = {}, firstMove = true, hovered = false, maxed = false, tooltip = document.createElement('div'), ie6 = (typeof document.body.style.maxWidth == "undefined") ? true : false, talk = (typeof $.talk == "function" && typeof $.listen == "function") ? true : false;\r
58         \r
59         if (o.id) \r
60             tooltip.id = o.id;\r
61         if (o.className) \r
62             tooltip.className = o.className;\r
63         \r
64         o.degrade = (o.degrade && ie6) ? true : false; //only degrades if also IE6\r
65         for (var p in o.style)//apply styles to tooltip\r
66              tooltip.style[p] = o.style[p];\r
67         \r
68         function fillTooltip(condition){\r
69             if (condition) {\r
70                 if (o.degrade)//replace html characters for proper degradation to title attribute\r
71                     $(tooltip).html(o.content.replace(/<\/?[^>]+>/gi, ''));\r
72                 else //otherwise just fill the tooltip with content\r
73                      $(tooltip).html(o.content);\r
74             }\r
75         }\r
76         \r
77         if (o.ajax) { //if o.ajax is selected, this will fill and thus override o.content\r
78             $.get(o.ajax, function(data){\r
79                 if (data) \r
80                     o.content = data;\r
81                 fillTooltip(o.content);\r
82             });\r
83         }\r
84         \r
85         function offConditions(that){\r
86             function _offActions(that){\r
87                 if (title && !o.content) {\r
88                     that.title = title;\r
89                     title = null;\r
90                 }\r
91             }\r
92             function _execute(){\r
93                 if (!hovered && o.auto) {\r
94                     clearInterval(iId);\r
95                     if (o.fadeOut) {\r
96                         $(tooltip).fadeOut(o.fadeOut, function(){\r
97                             _offActions(that);\r
98                         });\r
99                     }\r
100                     else {\r
101                         _offActions(that);\r
102                         tooltip.style.display = "none";\r
103                     }\r
104                 }\r
105                 if (typeof o.callAfter == "function") \r
106                     o.callAfter(tooltip, that, o);\r
107                 if (talk) \r
108                     o = $.listen(o);\r
109             }\r
110             if (o.timeout > 0) {\r
111                 timeout2 = setTimeout(function(){\r
112                     _execute();\r
113                 }, o.timeout);\r
114             }\r
115             else {\r
116                 _execute();\r
117             }\r
118         }\r
119         \r
120         $(tooltip).hover(function(){\r
121             hovered = true;\r
122         }, function(){\r
123             hovered = false;\r
124             offConditions(over);\r
125         });\r
126         \r
127         //initialize\r
128         if (talk) { //A "channel" for plugins to "talk" to each other, and callbacks to manipulate settings\r
129             o.key = tooltip;\r
130             o.plugin = "wTooltip";\r
131             o.channel = "wayfarer";\r
132             $.talk(o);\r
133         }\r
134         \r
135         fillTooltip(o.content && !o.ajax);\r
136         $(tooltip).appendTo(o.appendTip);\r
137         \r
138         return this.each(function(){ //returns the element chain\r
139             this.onmouseover = function(ev){\r
140                 var that = this;\r
141                 clearTimeout(timeout2);\r
142                 if (this.title && !o.degrade && !o.content) {\r
143                     title = this.title;\r
144                     this.title = "";\r
145                 }\r
146                 if (o.content && o.degrade) \r
147                     this.title = tooltip.innerHTML;\r
148                 \r
149                 function _execute(){\r
150                     if (typeof o.callBefore == "function") \r
151                         o.callBefore(tooltip, that, o);\r
152                     if (talk) \r
153                         o = $.listen(o); //ping for new settings\r
154                     if (o.auto) {\r
155                         var display;\r
156                         if (o.content) {\r
157                             if (!o.degrade) \r
158                                 display = "block";\r
159                         }\r
160                         else \r
161                             if (title && !o.degrade) {\r
162                                 $(tooltip).html(unescape(title));\r
163                                 display = "block";\r
164                             }\r
165                             else {\r
166                                 display = "none";\r
167                             }\r
168                         if (display == "block" && o.fadeIn) \r
169                             $(tooltip).fadeIn(o.fadeIn);\r
170                         else \r
171                             tooltip.style.display = display;\r
172                     }\r
173                 }\r
174                 \r
175                 if (o.delay > 0) {\r
176                     timeout = setTimeout(function(){\r
177                         _execute();\r
178                     }, o.delay);\r
179                 }\r
180                 else {\r
181                     _execute();\r
182                 }\r
183             }\r
184             \r
185             this.onmousemove = function(ev){\r
186                 var e = (ev) ? ev : window.event, that = this;\r
187                 over = this; //tracks the event trigger in the plugin-global "over"\r
188                 if (o.follow || firstMove) {\r
189                     var scrollY = $(window).scrollTop(), scrollX = $(window).scrollLeft(), top = e.clientY + scrollY + o.offsetY, left = e.clientX + scrollX + o.offsetX, outerH = $(o.appendTip).outerHeight(), innerH = $(o.appendTip).innerHeight(), maxLeft = $(window).width() + scrollX - $(tooltip).outerWidth(), maxTop = $(window).height() + scrollY - $(tooltip).outerHeight();\r
190                     \r
191                     top = (outerH > innerH) ? top - (outerH - innerH) : top; //if appended area (usually BODY) has a border on top, adjust\r
192                     maxed = (top > maxTop || left > maxLeft) ? true : false;\r
193                     \r
194                     if (left - scrollX <= 0 && o.offsetX < 0) \r
195                         left = scrollX;\r
196                     else \r
197                         if (left > maxLeft) \r
198                             left = maxLeft;\r
199                     if (top - scrollY <= 0 && o.offsetY < 0) \r
200                         top = scrollY;\r
201                     else \r
202                         if (top > maxTop) \r
203                             top = maxTop;\r
204                     \r
205                     tooltip.style.top = top + "px";\r
206                     tooltip.style.left = left + "px";\r
207                     firstMove = false;\r
208                 }\r
209             }\r
210             \r
211             this.onmouseout = function(){\r
212                 clearTimeout(timeout);\r
213                 var that = this;\r
214                 firstMove = true;\r
215                 if (!o.follow || maxed || (o.offsetX < 0 && o.offsetY < 0)) {\r
216                     setTimeout(function(){\r
217                         iId = setInterval(function(){\r
218                             offConditions(that)\r
219                         }, 1)\r
220                     }, 1);\r
221                 }\r
222                 else {\r
223                     offConditions(this);\r
224                 }\r
225             }\r
226             \r
227             if (typeof o.clickAction == "function") {\r
228                 this.onclick = function(){\r
229                     o.clickAction(tooltip, this);\r
230                 }\r
231             }\r
232         });\r
233     }\r
234 })(jQuery);