+/* Wayfarer Tooltip\r
+ * Version 1.0.4\r
+ * Author Abel Mohler\r
+ * URI: http://www.wayfarerweb.com/wtooltip.php\r
+ * Released with the MIT License: http://www.wayfarerweb.com/mit.php\r
+ */\r
+(function($){ //jQuery.noConflict()compliant\r
+ $.fn.wTooltip = function(o, callback){\r
+ o = $.extend({ //defaults, can be overidden\r
+ content: null, //string content for tooltip.\r
+ ajax: null, //path to content for tooltip\r
+ follow: true, //does tooltip follow the cursor?\r
+ auto: true, //If false, tooltip won't automatically transition, it must be manually shown/hidden\r
+ fadeIn: 0, //fade in, in milliseconds ("fast, "slow", etc may also be used)\r
+ fadeOut: 0, //fade out, in milliseconds ("fast, "slow", etc may also be used)\r
+ appendTip: document.body, //should probably not need to be overridden\r
+ degrade: false, //if true, in IE6 tooltip will degrade to a title attribute message\r
+ offsetY: 10, //offsetY and offsetX properties designate position from the cursor\r
+ offsetX: 1,\r
+ style: {},\r
+ className: null, //to style the tooltip externally, pass a className or id\r
+ id: null,\r
+ callBefore: function(tooltip, node, settings){\r
+ }, //called when mouse enters the area\r
+ callAfter: function(tooltip, node, settings){\r
+ }, //called when mouse leaves the area (same as "callback" option)\r
+ clickAction: function(tooltip, node){\r
+ $(tooltip).hide();\r
+ }, //called when the element is clicked, with access to tooltip\r
+ delay: 0, //delay (in milliseconds)before tooltip appears and callBefore executes\r
+ timeout: 0, //delay (in milliseconds)before tooltip transitions away, and callAfter executes\r
+ cloneable: false //UNWORKING. Requires $().wClone plugin. If true, tooltip may be dragged and placed anywhere on the screen.\r
+ }, o ||\r
+ {});\r
+ \r
+ if (!o.style && typeof o.style != "object") {\r
+ o.style = {};\r
+ o.style.zIndex = "1000";\r
+ }\r
+ else {\r
+ o.style = $.extend({ //the default style rules of the tooltip\r
+ border: "1px solid gray",\r
+ background: "#edeef0",\r
+ color: "#000",\r
+ padding: "10px",\r
+ zIndex: "1000",\r
+ textAlign: "left"\r
+ }, o.style ||\r
+ {});\r
+ }\r
+ \r
+ if (typeof callback == "function") \r
+ o.callAfter = callback || o.callAfter;\r
+ \r
+ o.style.display = "none", o.style.position = "absolute"; //permanent defaults\r
+ //private settings\r
+ 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
+ \r
+ if (o.id) \r
+ tooltip.id = o.id;\r
+ if (o.className) \r
+ tooltip.className = o.className;\r
+ \r
+ o.degrade = (o.degrade && ie6) ? true : false; //only degrades if also IE6\r
+ for (var p in o.style)//apply styles to tooltip\r
+ tooltip.style[p] = o.style[p];\r
+ \r
+ function fillTooltip(condition){\r
+ if (condition) {\r
+ if (o.degrade)//replace html characters for proper degradation to title attribute\r
+ $(tooltip).html(o.content.replace(/<\/?[^>]+>/gi, ''));\r
+ else //otherwise just fill the tooltip with content\r
+ $(tooltip).html(o.content);\r
+ }\r
+ }\r
+ \r
+ if (o.ajax) { //if o.ajax is selected, this will fill and thus override o.content\r
+ $.get(o.ajax, function(data){\r
+ if (data) \r
+ o.content = data;\r
+ fillTooltip(o.content);\r
+ });\r
+ }\r
+ \r
+ function offConditions(that){\r
+ function _offActions(that){\r
+ if (title && !o.content) {\r
+ that.title = title;\r
+ title = null;\r
+ }\r
+ }\r
+ function _execute(){\r
+ if (!hovered && o.auto) {\r
+ clearInterval(iId);\r
+ if (o.fadeOut) {\r
+ $(tooltip).fadeOut(o.fadeOut, function(){\r
+ _offActions(that);\r
+ });\r
+ }\r
+ else {\r
+ _offActions(that);\r
+ tooltip.style.display = "none";\r
+ }\r
+ }\r
+ if (typeof o.callAfter == "function") \r
+ o.callAfter(tooltip, that, o);\r
+ if (talk) \r
+ o = $.listen(o);\r
+ }\r
+ if (o.timeout > 0) {\r
+ timeout2 = setTimeout(function(){\r
+ _execute();\r
+ }, o.timeout);\r
+ }\r
+ else {\r
+ _execute();\r
+ }\r
+ }\r
+ \r
+ $(tooltip).hover(function(){\r
+ hovered = true;\r
+ }, function(){\r
+ hovered = false;\r
+ offConditions(over);\r
+ });\r
+ \r
+ //initialize\r
+ if (talk) { //A "channel" for plugins to "talk" to each other, and callbacks to manipulate settings\r
+ o.key = tooltip;\r
+ o.plugin = "wTooltip";\r
+ o.channel = "wayfarer";\r
+ $.talk(o);\r
+ }\r
+ \r
+ fillTooltip(o.content && !o.ajax);\r
+ $(tooltip).appendTo(o.appendTip);\r
+ \r
+ return this.each(function(){ //returns the element chain\r
+ this.onmouseover = function(ev){\r
+ var that = this;\r
+ clearTimeout(timeout2);\r
+ if (this.title && !o.degrade && !o.content) {\r
+ title = this.title;\r
+ this.title = "";\r
+ }\r
+ if (o.content && o.degrade) \r
+ this.title = tooltip.innerHTML;\r
+ \r
+ function _execute(){\r
+ if (typeof o.callBefore == "function") \r
+ o.callBefore(tooltip, that, o);\r
+ if (talk) \r
+ o = $.listen(o); //ping for new settings\r
+ if (o.auto) {\r
+ var display;\r
+ if (o.content) {\r
+ if (!o.degrade) \r
+ display = "block";\r
+ }\r
+ else \r
+ if (title && !o.degrade) {\r
+ $(tooltip).html(unescape(title));\r
+ display = "block";\r
+ }\r
+ else {\r
+ display = "none";\r
+ }\r
+ if (display == "block" && o.fadeIn) \r
+ $(tooltip).fadeIn(o.fadeIn);\r
+ else \r
+ tooltip.style.display = display;\r
+ }\r
+ }\r
+ \r
+ if (o.delay > 0) {\r
+ timeout = setTimeout(function(){\r
+ _execute();\r
+ }, o.delay);\r
+ }\r
+ else {\r
+ _execute();\r
+ }\r
+ }\r
+ \r
+ this.onmousemove = function(ev){\r
+ var e = (ev) ? ev : window.event, that = this;\r
+ over = this; //tracks the event trigger in the plugin-global "over"\r
+ if (o.follow || firstMove) {\r
+ 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
+ \r
+ top = (outerH > innerH) ? top - (outerH - innerH) : top; //if appended area (usually BODY) has a border on top, adjust\r
+ maxed = (top > maxTop || left > maxLeft) ? true : false;\r
+ \r
+ if (left - scrollX <= 0 && o.offsetX < 0) \r
+ left = scrollX;\r
+ else \r
+ if (left > maxLeft) \r
+ left = maxLeft;\r
+ if (top - scrollY <= 0 && o.offsetY < 0) \r
+ top = scrollY;\r
+ else \r
+ if (top > maxTop) \r
+ top = maxTop;\r
+ \r
+ tooltip.style.top = top + "px";\r
+ tooltip.style.left = left + "px";\r
+ firstMove = false;\r
+ }\r
+ }\r
+ \r
+ this.onmouseout = function(){\r
+ clearTimeout(timeout);\r
+ var that = this;\r
+ firstMove = true;\r
+ if (!o.follow || maxed || (o.offsetX < 0 && o.offsetY < 0)) {\r
+ setTimeout(function(){\r
+ iId = setInterval(function(){\r
+ offConditions(that)\r
+ }, 1)\r
+ }, 1);\r
+ }\r
+ else {\r
+ offConditions(this);\r
+ }\r
+ }\r
+ \r
+ if (typeof o.clickAction == "function") {\r
+ this.onclick = function(){\r
+ o.clickAction(tooltip, this);\r
+ }\r
+ }\r
+ });\r
+ }\r
+})(jQuery);
\ No newline at end of file