1 /* This notice must be untouched at all times.
 
   2 Copyright (c) 2002-2008 Walter Zorn. All rights reserved.
 
   6 The latest version is available at
 
   7 http://www.walterzorn.com
 
   8 or http://www.devira.com
 
   9 or http://www.walterzorn.de
 
  11 Created 1.12.2002 by Walter Zorn (Web: http://www.walterzorn.com )
 
  12 Last modified: 7.11.2008
 
  14 Easy-to-use cross-browser tooltips.
 
  15 Just include the script at the beginning of the <body> section, and invoke
 
  16 Tip('Tooltip text') to show and UnTip() to hide the tooltip, from the desired
 
  17 HTML eventhandlers. Example:
 
  18 <a onmouseover="Tip('Some text')" onmouseout="UnTip()" href="index.htm">My home page</a>
 
  19 No container DIV required.
 
  20 By default, width and height of tooltips are automatically adapted to content.
 
  21 Is even capable of dynamically converting arbitrary HTML elements to tooltips
 
  22 by calling TagToTip('ID_of_HTML_element_to_be_converted') instead of Tip(),
 
  23 which means you can put important, search-engine-relevant stuff into tooltips.
 
  24 Appearance & behaviour of tooltips can be individually configured
 
  25 via commands passed to Tip() or TagToTip().
 
  30 This library is free software; you can redistribute it and/or
 
  31 modify it under the terms of the GNU Lesser General Public
 
  32 License (LGPL) as published by the Free Software Foundation; either
 
  33 version 2.1 of the License, or (at your option) any later version.
 
  35 This library is distributed in the hope that it will be useful,
 
  36 but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  37 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
  39 For more details on the GNU Lesser General Public License,
 
  40 see http://www.gnu.org/copyleft/lesser.html
 
  43 var config = new Object();
 
  46 //===================  GLOBAL TOOLTIP CONFIGURATION  =========================//
 
  47 var tt_Debug    = true          // false or true - recommended: false once you release your page to the public
 
  48 var tt_Enabled  = true          // Allows to (temporarily) suppress tooltips, e.g. by providing the user with a button that sets this global variable to false
 
  49 var TagsToTip   = true          // false or true - if true, HTML elements to be converted to tooltips via TagToTip() are automatically hidden;
 
  50                                                         // if false, you should hide those HTML elements yourself
 
  52 // For each of the following config variables there exists a command, which is
 
  53 // just the variablename in uppercase, to be passed to Tip() or TagToTip() to
 
  54 // configure tooltips individually. Individual commands override global
 
  55 // configuration. Order of commands is arbitrary.
 
  56 // Example: onmouseover="Tip('Tooltip text', LEFT, true, BGCOLOR, '#FF9900', FADEIN, 400)"
 
  58 config. Above                   = false         // false or true - tooltip above mousepointer
 
  59 config. BgColor                 = '#E2E7FF'     // Background colour (HTML colour value, in quotes)
 
  60 config. BgImg                   = ''            // Path to background image, none if empty string ''
 
  61 config. BorderColor             = '#003099'
 
  62 config. BorderStyle             = 'solid'       // Any permitted CSS value, but I recommend 'solid', 'dotted' or 'dashed'
 
  63 config. BorderWidth             = 1
 
  64 config. CenterMouse             = false         // false or true - center the tip horizontally below (or above) the mousepointer
 
  65 config. ClickClose              = false         // false or true - close tooltip if the user clicks somewhere
 
  66 config. ClickSticky             = false         // false or true - make tooltip sticky if user left-clicks on the hovered element while the tooltip is active
 
  67 config. CloseBtn                = false         // false or true - closebutton in titlebar
 
  68 config. CloseBtnColors  = ['#990000', '#FFFFFF', '#DD3333', '#FFFFFF']  // [Background, text, hovered background, hovered text] - use empty strings '' to inherit title colours
 
  69 config. CloseBtnText    = ' X '       // Close button text (may also be an image tag)
 
  70 config. CopyContent             = true          // When converting a HTML element to a tooltip, copy only the element's content, rather than converting the element by its own
 
  71 config. Delay                   = 400           // Time span in ms until tooltip shows up
 
  72 config. Duration                = 0                     // Time span in ms after which the tooltip disappears; 0 for infinite duration, < 0 for delay in ms _after_ the onmouseout until the tooltip disappears
 
  73 config. Exclusive               = false         // false or true - no other tooltip can appear until the current one has actively been closed
 
  74 config. FadeIn                  = 100           // Fade-in duration in ms, e.g. 400; 0 for no animation
 
  76 config. FadeInterval    = 30            // Duration of each fade step in ms (recommended: 30) - shorter is smoother but causes more CPU-load
 
  77 config. Fix                             = null          // Fixated position, two modes. Mode 1: x- an y-coordinates in brackets, e.g. [210, 480]. Mode 2: Show tooltip at a position related to an HTML element: [ID of HTML element, x-offset, y-offset from HTML element], e.g. ['SomeID', 10, 30]. Value null (default) for no fixated positioning.
 
  78 config. FollowMouse             = true          // false or true - tooltip follows the mouse
 
  79 config. FontColor               = '#000044'
 
  80 config. FontFace                = 'Verdana,Geneva,sans-serif'
 
  81 config. FontSize                = '8pt'         // E.g. '9pt' or '12px' - unit is mandatory
 
  82 config. FontWeight              = 'normal'      // 'normal' or 'bold';
 
  83 config. Height                  = 0                     // Tooltip height; 0 for automatic adaption to tooltip content, < 0 (e.g. -100) for a maximum for automatic adaption
 
  84 config. JumpHorz                = false         // false or true - jump horizontally to other side of mouse if tooltip would extend past clientarea boundary
 
  85 config. JumpVert                = true          // false or true - jump vertically              "
 
  86 config. Left                    = false         // false or true - tooltip on the left of the mouse
 
  87 config. OffsetX                 = 14            // Horizontal offset of left-top corner from mousepointer
 
  88 config. OffsetY                 = 8                     // Vertical offset
 
  89 config. Opacity                 = 100           // Integer between 0 and 100 - opacity of tooltip in percent
 
  90 config. Padding                 = 3                     // Spacing between border and content
 
  91 config. Shadow                  = false         // false or true
 
  92 config. ShadowColor             = '#C0C0C0'
 
  93 config. ShadowWidth             = 5
 
  94 config. Sticky                  = false         // false or true - fixate tip, ie. don't follow the mouse and don't hide on mouseout
 
  95 config. TextAlign               = 'left'        // 'left', 'right' or 'justify'
 
  96 config. Title                   = ''            // Default title text applied to all tips (no default title: empty string '')
 
  97 config. TitleAlign              = 'left'        // 'left' or 'right' - text alignment inside the title bar
 
  98 config. TitleBgColor    = ''            // If empty string '', BorderColor will be used
 
  99 config. TitleFontColor  = '#FFFFFF'     // Color of title text - if '', BgColor (of tooltip body) will be used
 
 100 config. TitleFontFace   = ''            // If '' use FontFace (boldified)
 
 101 config. TitleFontSize   = ''            // If '' use FontSize
 
 102 config. TitlePadding    = 2
 
 103 config. Width                   = 0                     // Tooltip width; 0 for automatic adaption to tooltip content; < -1 (e.g. -240) for a maximum width for that automatic adaption;
 
 104                                                                         // -1: tooltip width confined to the width required for the titlebar
 
 105 //=======  END OF TOOLTIP CONFIG, DO NOT CHANGE ANYTHING BELOW  ==============//
 
 110 //=====================  PUBLIC  =============================================//
 
 113         tt_Tip(arguments, null);
 
 117         var t2t = tt_GetElt(arguments[0]);
 
 119                 tt_Tip(arguments, t2t);
 
 124         if(tt_aV[DURATION] < 0 && (tt_iState & 0x2))
 
 125                 tt_tDurt.Timer("tt_HideInit()", -tt_aV[DURATION], true);
 
 126         else if(!(tt_aV[STICKY] && (tt_iState & 0x2)))
 
 130 //==================  PUBLIC PLUGIN API  =====================================//
 
 131 // Extension eventhandlers currently supported:
 
 132 // OnLoadConfig, OnCreateContentString, OnSubDivsCreated, OnShow, OnMoveBefore,
 
 133 // OnMoveAfter, OnHideInit, OnHide, OnKill
 
 135 var tt_aElt = new Array(10), // Container DIV, outer title & body DIVs, inner title & body TDs, closebutton SPAN, shadow DIVs, and IFRAME to cover windowed elements in IE
 
 136 tt_aV = new Array(),    // Caches and enumerates config data for currently active tooltip
 
 137 tt_sContent,                    // Inner tooltip text or HTML
 
 138 tt_t2t, tt_t2tDad,              // Tag converted to tip, and its DOM parent element
 
 141 tt_x, tt_y, tt_w, tt_h; // Position, width and height of currently displayed tooltip
 
 143 function tt_Extension()
 
 146         tt_aExt[tt_aExt.length] = this;
 
 149 function tt_SetTipPos(x, y)
 
 151         var css = tt_aElt[0].style;
 
 159                 var ifrm = tt_aElt[tt_aElt.length - 1];
 
 162                         ifrm.style.left = css.left;
 
 163                         ifrm.style.top = css.top;
 
 167 function tt_HideInit()
 
 171                 tt_ExtCallFncs(0, "HideInit");
 
 172                 tt_iState &= ~(0x4 | 0x8);
 
 173                 if(tt_flagOpa && tt_aV[FADEOUT])
 
 178                                 var n = Math.round(tt_aV[FADEOUT] / (tt_aV[FADEINTERVAL] * (tt_aV[OPACITY] / tt_opa)));
 
 179                                 tt_Fade(tt_opa, tt_opa, 0, n);
 
 183                 tt_tHide.Timer("tt_Hide();", 1, false);
 
 188         if(tt_db && tt_iState)
 
 193                         tt_aElt[0].style.visibility = "hidden";
 
 194                         tt_ExtCallFncs(0, "Hide");
 
 202                         tt_tWaitMov.EndTimer();
 
 205                 if(tt_aV[CLICKCLOSE] || tt_aV[CLICKSTICKY])
 
 206                         tt_RemEvtFnc(document, "mouseup", tt_OnLClick);
 
 207                 tt_ExtCallFncs(0, "Kill");
 
 208                 // In case of a TagToTip tip, hide converted DOM node and
 
 209                 // re-insert it into DOM
 
 210                 if(tt_t2t && !tt_aV[COPYCONTENT])
 
 215                 if(tt_aElt[tt_aElt.length - 1])
 
 216                         tt_aElt[tt_aElt.length - 1].style.display = "none";
 
 219 function tt_GetElt(id)
 
 221         return(document.getElementById ? document.getElementById(id)
 
 222                         : document.all ? document.all[id]
 
 225 function tt_GetDivW(el)
 
 227         return(el ? (el.offsetWidth || el.style.pixelWidth || 0) : 0);
 
 229 function tt_GetDivH(el)
 
 231         return(el ? (el.offsetHeight || el.style.pixelHeight || 0) : 0);
 
 233 function tt_GetScrollX()
 
 235         return(window.pageXOffset || (tt_db ? (tt_db.scrollLeft || 0) : 0));
 
 237 function tt_GetScrollY()
 
 239         return(window.pageYOffset || (tt_db ? (tt_db.scrollTop || 0) : 0));
 
 241 function tt_GetClientW()
 
 243         return tt_GetWndCliSiz("Width");
 
 245 function tt_GetClientH()
 
 247         return tt_GetWndCliSiz("Height");
 
 249 function tt_GetEvtX(e)
 
 251         return (e ? ((typeof(e.pageX) != tt_u) ? e.pageX : (e.clientX + tt_GetScrollX())) : 0);
 
 253 function tt_GetEvtY(e)
 
 255         return (e ? ((typeof(e.pageY) != tt_u) ? e.pageY : (e.clientY + tt_GetScrollY())) : 0);
 
 257 function tt_AddEvtFnc(el, sEvt, PFnc)
 
 261                 if(el.addEventListener)
 
 262                         el.addEventListener(sEvt, PFnc, false);
 
 264                         el.attachEvent("on" + sEvt, PFnc);
 
 267 function tt_RemEvtFnc(el, sEvt, PFnc)
 
 271                 if(el.removeEventListener)
 
 272                         el.removeEventListener(sEvt, PFnc, false);
 
 274                         el.detachEvent("on" + sEvt, PFnc);
 
 277 function tt_GetDad(el)
 
 279         return(el.parentNode || el.parentElement || el.offsetParent);
 
 281 function tt_MovDomNode(el, dadFrom, dadTo)
 
 284                 dadFrom.removeChild(el);
 
 286                 dadTo.appendChild(el);
 
 289 //======================  PRIVATE  ===========================================//
 
 290 var tt_aExt = new Array(),      // Array of extension objects
 
 292 tt_db, tt_op, tt_ie, tt_ie56, tt_bBoxOld,       // Browser flags
 
 294 tt_ovr_,                                // HTML element the mouse is currently over
 
 295 tt_flagOpa,                             // Opacity support: 1=IE, 2=Khtml, 3=KHTML, 4=Moz, 5=W3C
 
 296 tt_maxPosX, tt_maxPosY,
 
 297 tt_iState = 0,                  // Tooltip active |= 1, shown |= 2, move with mouse |= 4, exclusive |= 8
 
 298 tt_opa,                                 // Currently applied opacity
 
 299 tt_bJmpVert, tt_bJmpHorz,// Tip temporarily on other side of mouse
 
 300 tt_elDeHref,                    // The tag from which we've removed the href attribute
 
 302 tt_tShow = new Number(0), tt_tHide = new Number(0), tt_tDurt = new Number(0),
 
 303 tt_tFade = new Number(0), tt_tWaitMov = new Number(0),
 
 311         // Send old browsers instantly to hell
 
 312         if(!tt_Browser() || !tt_MkMainDiv())
 
 316         tt_AddEvtFnc(document, "mousemove", tt_Move);
 
 317         // In Debug mode we search for TagToTip() calls in order to notify
 
 318         // the user if they've forgotten to set the TagsToTip config flag
 
 319         if(TagsToTip || tt_Debug)
 
 321         // Ensure the tip be hidden when the page unloads
 
 322         tt_AddEvtFnc(window, "unload", tt_Hide);
 
 324 // Creates command names by translating config variable names to upper case
 
 325 function tt_MkCmdEnum()
 
 329                 eval("window." + i.toString().toUpperCase() + " = " + n++);
 
 332 function tt_Browser()
 
 336         n = navigator.userAgent.toLowerCase(),
 
 337         nv = navigator.appVersion;
 
 338         tt_op = (document.defaultView && typeof(eval("w" + "indow" + "." + "o" + "p" + "er" + "a")) != tt_u);
 
 339         tt_ie = n.indexOf("msie") != -1 && document.all && !tt_op;
 
 342                 var ieOld = (!document.compatMode || document.compatMode == "BackCompat");
 
 343                 tt_db = !ieOld ? document.documentElement : (document.body || null);
 
 345                         tt_ie56 = parseFloat(nv.substring(nv.indexOf("MSIE") + 5)) >= 5.5
 
 346                                         && typeof document.body.style.maxHeight == tt_u;
 
 350                 tt_db = document.documentElement || document.body ||
 
 351                                 (document.getElementsByTagName ? document.getElementsByTagName("body")[0]
 
 355                         n6 = document.defaultView && typeof document.defaultView.getComputedStyle != tt_u;
 
 356                         w3c = !n6 && document.getElementById;
 
 359         tt_body = (document.getElementsByTagName ? document.getElementsByTagName("body")[0]
 
 360                                 : (document.body || null));
 
 361         if(tt_ie || n6 || tt_op || w3c)
 
 365                         if(document.attachEvent || document.addEventListener)
 
 369                         tt_Err("wz_tooltip.js must be included INSIDE the body section,"
 
 370                                         + " immediately after the opening <body> tag.", false);
 
 375 function tt_MkMainDiv()
 
 377         // Create the tooltip DIV
 
 378         if(tt_body.insertAdjacentHTML)
 
 379                 tt_body.insertAdjacentHTML("afterBegin", tt_MkMainDivHtm());
 
 380         else if(typeof tt_body.innerHTML != tt_u && document.createElement && tt_body.appendChild)
 
 381                 tt_body.appendChild(tt_MkMainDivDom());
 
 382         if(window.tt_GetMainDivRefs /* FireFox Alzheimer */ && tt_GetMainDivRefs())
 
 387 function tt_MkMainDivHtm()
 
 390                 '<div id="WzTtDiV"></div>' +
 
 391                 (tt_ie56 ? ('<iframe id="WzTtIfRm" src="javascript:false" scrolling="no" frameborder="0" style="filter:Alpha(opacity=0);position:absolute;top:0px;left:0px;display:none;"></iframe>')
 
 395 function tt_MkMainDivDom()
 
 397         var el = document.createElement("div");
 
 402 function tt_GetMainDivRefs()
 
 404         tt_aElt[0] = tt_GetElt("WzTtDiV");
 
 405         if(tt_ie56 && tt_aElt[0])
 
 407                 tt_aElt[tt_aElt.length - 1] = tt_GetElt("WzTtIfRm");
 
 408                 if(!tt_aElt[tt_aElt.length - 1])
 
 413                 var css = tt_aElt[0].style;
 
 415                 css.visibility = "hidden";
 
 416                 css.position = "absolute";
 
 417                 css.overflow = "hidden";
 
 422 function tt_ResetMainDiv()
 
 425         tt_aElt[0].innerHTML = "";
 
 426         tt_aElt[0].style.width = "0px";
 
 429 function tt_IsW3cBox()
 
 431         var css = tt_aElt[0].style;
 
 433         css.padding = "10px";
 
 435         tt_bBoxOld = (tt_GetDivW(tt_aElt[0]) == 40);
 
 439 function tt_OpaSupport()
 
 441         var css = tt_body.style;
 
 443         tt_flagOpa = (typeof(css.KhtmlOpacity) != tt_u) ? 2
 
 444                                 : (typeof(css.KHTMLOpacity) != tt_u) ? 3
 
 445                                 : (typeof(css.MozOpacity) != tt_u) ? 4
 
 446                                 : (typeof(css.opacity) != tt_u) ? 5
 
 447                                 : (typeof(css.filter) != tt_u) ? 1
 
 450 // Ported from http://dean.edwards.name/weblog/2006/06/again/
 
 451 // (Dean Edwards et al.)
 
 452 function tt_SetOnloadFnc()
 
 454         tt_AddEvtFnc(document, "DOMContentLoaded", tt_HideSrcTags);
 
 455         tt_AddEvtFnc(window, "load", tt_HideSrcTags);
 
 456         if(tt_body.attachEvent)
 
 457                 tt_body.attachEvent("onreadystatechange",
 
 459                                 if(tt_body.readyState == "complete")
 
 462         if(/WebKit|KHTML/i.test(navigator.userAgent))
 
 464                 var t = setInterval(function() {
 
 465                                         if(/loaded|complete/.test(document.readyState))
 
 473 function tt_HideSrcTags()
 
 475         if(!window.tt_HideSrcTags || window.tt_HideSrcTags.done)
 
 477         window.tt_HideSrcTags.done = true;
 
 478         if(!tt_HideSrcTagsRecurs(tt_body))
 
 479                 tt_Err("There are HTML elements to be converted to tooltips.\nIf you"
 
 480                                 + " want these HTML elements to be automatically hidden, you"
 
 481                                 + " must edit wz_tooltip.js, and set TagsToTip in the global"
 
 482                                 + " tooltip configuration to true.", true);
 
 484 function tt_HideSrcTagsRecurs(dad)
 
 487         // Walk the DOM tree for tags that have an onmouseover or onclick attribute
 
 488         // containing a TagToTip('...') call.
 
 489         // (.childNodes first since .children is bugous in Safari)
 
 490         var a = dad.childNodes || dad.children || null;
 
 492         for(var i = a ? a.length : 0; i;)
 
 494                 if(!tt_HideSrcTagsRecurs(a[i]))
 
 496                 ovr = a[i].getAttribute ? (a[i].getAttribute("onmouseover") || a[i].getAttribute("onclick"))
 
 497                                 : (typeof a[i].onmouseover == "function") ? (a[i].onmouseover || a[i].onclick)
 
 501                         asT2t = ovr.toString().match(/TagToTip\s*\(\s*'[^'.]+'\s*[\),]/);
 
 502                         if(asT2t && asT2t.length)
 
 504                                 if(!tt_HideSrcTag(asT2t[0]))
 
 511 function tt_HideSrcTag(sT2t)
 
 515         // The ID passed to the found TagToTip() call identifies an HTML element
 
 516         // to be converted to a tooltip, so hide that element
 
 517         id = sT2t.replace(/.+'([^'.]+)'.+/, "$1");
 
 521                 if(tt_Debug && !TagsToTip)
 
 524                         el.style.display = "none";
 
 527                 tt_Err("Invalid ID\n'" + id + "'\npassed to TagToTip()."
 
 528                                 + " There exists no HTML element with that ID.", true);
 
 531 function tt_Tip(arg, t2t)
 
 533         if(!tt_db || (tt_iState & 0x8))
 
 540         if(!tt_ReadCmds(arg))
 
 542         tt_iState = 0x1 | 0x4;
 
 544         tt_MkTipContent(arg);
 
 549         tt_maxPosX = tt_GetClientW() + tt_GetScrollX() - tt_w - 1;
 
 550         tt_maxPosY = tt_GetClientH() + tt_GetScrollY() - tt_h - 1;
 
 552         // Ensure the tip be shown and positioned before the first onmousemove
 
 557 function tt_ReadCmds(a)
 
 561         // First load the global config values, to initialize also values
 
 562         // for which no command is passed
 
 565                 tt_aV[i++] = config[j];
 
 566         // Then replace each cached config value for which a command is
 
 567         // passed (ensure the # of command args plus value args be even)
 
 570                 for(i = a.length - 1; i > 0; i -= 2)
 
 571                         tt_aV[a[i - 1]] = a[i];
 
 574         tt_Err("Incorrect call of Tip() or TagToTip().\n"
 
 575                         + "Each command must be followed by a value.", true);
 
 578 function tt_AdaptConfig1()
 
 580         tt_ExtCallFncs(0, "LoadConfig");
 
 581         // Inherit unspecified title formattings from body
 
 582         if(!tt_aV[TITLEBGCOLOR].length)
 
 583                 tt_aV[TITLEBGCOLOR] = tt_aV[BORDERCOLOR];
 
 584         if(!tt_aV[TITLEFONTCOLOR].length)
 
 585                 tt_aV[TITLEFONTCOLOR] = tt_aV[BGCOLOR];
 
 586         if(!tt_aV[TITLEFONTFACE].length)
 
 587                 tt_aV[TITLEFONTFACE] = tt_aV[FONTFACE];
 
 588         if(!tt_aV[TITLEFONTSIZE].length)
 
 589                 tt_aV[TITLEFONTSIZE] = tt_aV[FONTSIZE];
 
 592                 // Use title colours for non-specified closebutton colours
 
 593                 if(!tt_aV[CLOSEBTNCOLORS])
 
 594                         tt_aV[CLOSEBTNCOLORS] = new Array("", "", "", "");
 
 597                         if(!tt_aV[CLOSEBTNCOLORS][i].length)
 
 598                                 tt_aV[CLOSEBTNCOLORS][i] = (i & 1) ? tt_aV[TITLEFONTCOLOR] : tt_aV[TITLEBGCOLOR];
 
 600                 // Enforce titlebar be shown
 
 601                 if(!tt_aV[TITLE].length)
 
 604         // Circumvents broken display of images and fade-in flicker in Geckos < 1.8
 
 605         if(tt_aV[OPACITY] == 100 && typeof tt_aElt[0].style.MozOpacity != tt_u && !Array.every)
 
 607         // Smartly shorten the delay for fade-in tooltips
 
 608         if(tt_aV[FADEIN] && tt_flagOpa && tt_aV[DELAY] > 100)
 
 609                 tt_aV[DELAY] = Math.max(tt_aV[DELAY] - tt_aV[FADEIN], 100);
 
 611 function tt_AdaptConfig2()
 
 613         if(tt_aV[CENTERMOUSE])
 
 615                 tt_aV[OFFSETX] -= ((tt_w - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0)) >> 1);
 
 616                 tt_aV[JUMPHORZ] = false;
 
 619 // Expose content globally so extensions can modify it
 
 620 function tt_MkTipContent(a)
 
 624                 if(tt_aV[COPYCONTENT])
 
 625                         tt_sContent = tt_t2t.innerHTML;
 
 631         tt_ExtCallFncs(0, "CreateContentString");
 
 633 function tt_MkTipSubDivs()
 
 635         var sCss = 'position:relative;margin:0px;padding:0px;border-width:0px;left:0px;top:0px;line-height:normal;width:auto;',
 
 636         sTbTrTd = ' cellspacing="0" cellpadding="0" border="0" style="' + sCss + '"><tbody style="' + sCss + '"><tr><td ';
 
 638         tt_aElt[0].style.width = tt_GetClientW() + "px";
 
 639         tt_aElt[0].innerHTML =
 
 641                 + (tt_aV[TITLE].length ?
 
 642                         ('<div id="WzTiTl" style="position:relative;z-index:1;">'
 
 643                         + '<table id="WzTiTlTb"' + sTbTrTd + 'id="WzTiTlI" style="' + sCss + '">'
 
 647                                 ('<td align="right" style="' + sCss
 
 648                                 + 'text-align:right;">'
 
 649                                 + '<span id="WzClOsE" style="position:relative;left:2px;padding-left:2px;padding-right:2px;'
 
 650                                 + 'cursor:' + (tt_ie ? 'hand' : 'pointer')
 
 651                                 + ';" onmouseover="tt_OnCloseBtnOver(1)" onmouseout="tt_OnCloseBtnOver(0)" onclick="tt_HideInit()">'
 
 652                                 + tt_aV[CLOSEBTNTEXT]
 
 655                         + '</tr></tbody></table></div>')
 
 657                 + '<div id="WzBoDy" style="position:relative;z-index:0;">'
 
 658                 + '<table' + sTbTrTd + 'id="WzBoDyI" style="' + sCss + '">'
 
 660                 + '</td></tr></tbody></table></div>'
 
 662                         ? ('<div id="WzTtShDwR" style="position:absolute;overflow:hidden;"></div>'
 
 663                                 + '<div id="WzTtShDwB" style="position:relative;overflow:hidden;"></div>')
 
 667         // Convert DOM node to tip
 
 668         if(tt_t2t && !tt_aV[COPYCONTENT])
 
 670         tt_ExtCallFncs(0, "SubDivsCreated");
 
 672 function tt_GetSubDivRefs()
 
 674         var aId = new Array("WzTiTl", "WzTiTlTb", "WzTiTlI", "WzClOsE", "WzBoDy", "WzBoDyI", "WzTtShDwB", "WzTtShDwR");
 
 676         for(var i = aId.length; i; --i)
 
 677                 tt_aElt[i] = tt_GetElt(aId[i - 1]);
 
 679 function tt_FormatTip()
 
 681         var css, w, h, pad = tt_aV[PADDING], padT, wBrd = tt_aV[BORDERWIDTH],
 
 682         iOffY, iOffSh, iAdd = (pad + wBrd) << 1;
 
 684         //--------- Title DIV ----------
 
 685         if(tt_aV[TITLE].length)
 
 687                 padT = tt_aV[TITLEPADDING];
 
 688                 css = tt_aElt[1].style;
 
 689                 css.background = tt_aV[TITLEBGCOLOR];
 
 690                 css.paddingTop = css.paddingBottom = padT + "px";
 
 691                 css.paddingLeft = css.paddingRight = (padT + 2) + "px";
 
 692                 css = tt_aElt[3].style;
 
 693                 css.color = tt_aV[TITLEFONTCOLOR];
 
 694                 if(tt_aV[WIDTH] == -1)
 
 695                         css.whiteSpace = "nowrap";
 
 696                 css.fontFamily = tt_aV[TITLEFONTFACE];
 
 697                 css.fontSize = tt_aV[TITLEFONTSIZE];
 
 698                 css.fontWeight = "bold";
 
 699                 css.textAlign = tt_aV[TITLEALIGN];
 
 703                         css = tt_aElt[4].style;
 
 704                         css.background = tt_aV[CLOSEBTNCOLORS][0];
 
 705                         css.color = tt_aV[CLOSEBTNCOLORS][1];
 
 706                         css.fontFamily = tt_aV[TITLEFONTFACE];
 
 707                         css.fontSize = tt_aV[TITLEFONTSIZE];
 
 708                         css.fontWeight = "bold";
 
 714                         tt_w = tt_GetDivW(tt_aElt[3]) + tt_GetDivW(tt_aElt[4]);
 
 715                         // Some spacing between title DIV and closebutton
 
 718                         // Restrict auto width to max width
 
 719                         if(tt_aV[WIDTH] < -1 && tt_w > -tt_aV[WIDTH])
 
 720                                 tt_w = -tt_aV[WIDTH];
 
 722                 // Ensure the top border of the body DIV be covered by the title DIV
 
 731         //-------- Body DIV ------------
 
 732         css = tt_aElt[5].style;
 
 733         css.top = iOffY + "px";
 
 736                 css.borderColor = tt_aV[BORDERCOLOR];
 
 737                 css.borderStyle = tt_aV[BORDERSTYLE];
 
 738                 css.borderWidth = wBrd + "px";
 
 740         if(tt_aV[BGCOLOR].length)
 
 741                 css.background = tt_aV[BGCOLOR];
 
 742         if(tt_aV[BGIMG].length)
 
 743                 css.backgroundImage = "url(" + tt_aV[BGIMG] + ")";
 
 744         css.padding = pad + "px";
 
 745         css.textAlign = tt_aV[TEXTALIGN];
 
 748                 css.overflow = "auto";
 
 749                 if(tt_aV[HEIGHT] > 0)
 
 750                         css.height = (tt_aV[HEIGHT] + iAdd) + "px";
 
 752                         tt_h = iAdd - tt_aV[HEIGHT];
 
 754         // TD inside body DIV
 
 755         css = tt_aElt[6].style;
 
 756         css.color = tt_aV[FONTCOLOR];
 
 757         css.fontFamily = tt_aV[FONTFACE];
 
 758         css.fontSize = tt_aV[FONTSIZE];
 
 759         css.fontWeight = tt_aV[FONTWEIGHT];
 
 760         css.textAlign = tt_aV[TEXTALIGN];
 
 763         // Width like title (if existent)
 
 764         else if(tt_aV[WIDTH] == -1 && tt_w)
 
 768                 // Measure width of the body's inner TD, as some browsers would expand
 
 769                 // the container and outer body DIV to 100%
 
 770                 w = tt_GetDivW(tt_aElt[6]);
 
 771                 // Restrict auto width to max width
 
 772                 if(tt_aV[WIDTH] < -1 && w > -tt_aV[WIDTH])
 
 779         //--------- Shadow DIVs ------------
 
 782                 tt_w += tt_aV[SHADOWWIDTH];
 
 783                 iOffSh = Math.floor((tt_aV[SHADOWWIDTH] * 4) / 3);
 
 785                 css = tt_aElt[7].style;
 
 786                 css.top = iOffY + "px";
 
 787                 css.left = iOffSh + "px";
 
 788                 css.width = (tt_w - iOffSh - tt_aV[SHADOWWIDTH]) + "px";
 
 789                 css.height = tt_aV[SHADOWWIDTH] + "px";
 
 790                 css.background = tt_aV[SHADOWCOLOR];
 
 792                 css = tt_aElt[8].style;
 
 793                 css.top = iOffSh + "px";
 
 794                 css.left = (tt_w - tt_aV[SHADOWWIDTH]) + "px";
 
 795                 css.width = tt_aV[SHADOWWIDTH] + "px";
 
 796                 css.background = tt_aV[SHADOWCOLOR];
 
 801         //-------- Container DIV -------
 
 802         tt_SetTipOpa(tt_aV[FADEIN] ? 0 : tt_aV[OPACITY]);
 
 803         tt_FixSize(iOffY, iOffSh);
 
 805 // Fixate the size so it can't dynamically change while the tooltip is moving.
 
 806 function tt_FixSize(iOffY, iOffSh)
 
 808         var wIn, wOut, h, add, pad = tt_aV[PADDING], wBrd = tt_aV[BORDERWIDTH], i;
 
 810         tt_aElt[0].style.width = tt_w + "px";
 
 811         tt_aElt[0].style.pixelWidth = tt_w;
 
 812         wOut = tt_w - ((tt_aV[SHADOW]) ? tt_aV[SHADOWWIDTH] : 0);
 
 816                 wIn -= (pad + wBrd) << 1;
 
 817         tt_aElt[5].style.width = wIn + "px";
 
 821                 wIn = wOut - ((tt_aV[TITLEPADDING] + 2) << 1);
 
 824                 tt_aElt[1].style.width = wOut + "px";
 
 825                 tt_aElt[2].style.width = wIn + "px";
 
 827         // Max height specified
 
 830                 h = tt_GetDivH(tt_aElt[5]);
 
 834                                 tt_h -= (pad + wBrd) << 1;
 
 835                         tt_aElt[5].style.height = tt_h + "px";
 
 838         tt_h = tt_GetDivH(tt_aElt[0]) + iOffY;
 
 841                 tt_aElt[8].style.height = (tt_h - iOffSh) + "px";
 
 842         i = tt_aElt.length - 1;
 
 845                 tt_aElt[i].style.width = tt_w + "px";
 
 846                 tt_aElt[i].style.height = tt_h + "px";
 
 849 function tt_DeAlt(el)
 
 859                 aKid = el.childNodes || el.children || null;
 
 862                         for(var i = aKid.length; i;)
 
 867 // This hack removes the native tooltips over links in Opera
 
 868 function tt_OpDeHref(el)
 
 876                 if(el.hasAttribute && el.hasAttribute("href"))
 
 878                         el.t_href = el.getAttribute("href");
 
 879                         el.t_stats = window.status;
 
 880                         el.removeAttribute("href");
 
 881                         el.style.cursor = "hand";
 
 882                         tt_AddEvtFnc(el, "mousedown", tt_OpReHref);
 
 883                         window.status = el.t_href;
 
 890 function tt_OpReHref()
 
 894                 tt_elDeHref.setAttribute("href", tt_elDeHref.t_href);
 
 895                 tt_RemEvtFnc(tt_elDeHref, "mousedown", tt_OpReHref);
 
 896                 window.status = tt_elDeHref.t_stats;
 
 902         var css = tt_t2t.style;
 
 904         // Store previous positioning
 
 905         tt_t2t.t_cp = css.position;
 
 906         tt_t2t.t_cl = css.left;
 
 907         tt_t2t.t_ct = css.top;
 
 908         tt_t2t.t_cd = css.display;
 
 909         // Store the tag's parent element so we can restore that DOM branch
 
 910         // when the tooltip is being hidden
 
 911         tt_t2tDad = tt_GetDad(tt_t2t);
 
 912         tt_MovDomNode(tt_t2t, tt_t2tDad, tt_aElt[6]);
 
 913         css.display = "block";
 
 914         css.position = "static";
 
 915         css.left = css.top = css.marginLeft = css.marginTop = "0px";
 
 917 function tt_UnEl2Tip()
 
 919         // Restore positioning and display
 
 920         var css = tt_t2t.style;
 
 922         css.display = tt_t2t.t_cd;
 
 923         tt_MovDomNode(tt_t2t, tt_GetDad(tt_t2t), tt_t2tDad);
 
 924         css.position = tt_t2t.t_cp;
 
 925         css.left = tt_t2t.t_cl;
 
 926         css.top = tt_t2t.t_ct;
 
 929 function tt_OverInit()
 
 932                 tt_over = window.event.target || window.event.srcElement;
 
 936         tt_OpDeHref(tt_over);
 
 938 function tt_ShowInit()
 
 940         tt_tShow.Timer("tt_Show()", tt_aV[DELAY], true);
 
 941         if(tt_aV[CLICKCLOSE] || tt_aV[CLICKSTICKY])
 
 942                 tt_AddEvtFnc(document, "mouseup", tt_OnLClick);
 
 946         var css = tt_aElt[0].style;
 
 948         // Override the z-index of the topmost wz_dragdrop.js D&D item
 
 949         css.zIndex = Math.max((window.dd && dd.z) ? (dd.z + 2) : 0, 1010);
 
 950         if(tt_aV[STICKY] || !tt_aV[FOLLOWMOUSE])
 
 954         if(tt_aV[DURATION] > 0)
 
 955                 tt_tDurt.Timer("tt_HideInit()", tt_aV[DURATION], true);
 
 956         tt_ExtCallFncs(0, "Show")
 
 957         css.visibility = "visible";
 
 960                 tt_Fade(0, 0, tt_aV[OPACITY], Math.round(tt_aV[FADEIN] / tt_aV[FADEINTERVAL]));
 
 963 function tt_ShowIfrm()
 
 967                 var ifrm = tt_aElt[tt_aElt.length - 1];
 
 970                         var css = ifrm.style;
 
 971                         css.zIndex = tt_aElt[0].style.zIndex - 1;
 
 972                         css.display = "block";
 
 979                 tt_ovr_ = e.target || e.srcElement;
 
 980         e = e || window.event;
 
 983                 tt_musX = tt_GetEvtX(e);
 
 984                 tt_musY = tt_GetEvtY(e);
 
 988                 // Prevent jam of mousemove events
 
 994                         tt_tWaitMov.Timer("tt_bWait = false;", 1, true);
 
1001                 else if(!tt_ExtCallFncs(e, "MoveBefore"))
 
1002                         tt_SetTipPos(tt_Pos(0), tt_Pos(1));
 
1003                 tt_ExtCallFncs([tt_musX, tt_musY], "MoveAfter")
 
1006 function tt_Pos(iDim)
 
1008         var iX, bJmpMod, cmdAlt, cmdOff, cx, iMax, iScrl, iMus, bJmp;
 
1010         // Map values according to dimension to calculate
 
1013                 bJmpMod = tt_aV[JUMPVERT];
 
1018                 iScrl = tt_GetScrollY();
 
1024                 bJmpMod = tt_aV[JUMPHORZ];
 
1029                 iScrl = tt_GetScrollX();
 
1035                 if(tt_aV[cmdAlt] && (!bJmp || tt_CalcPosAlt(iDim) >= iScrl + 16))
 
1036                         iX = tt_PosAlt(iDim);
 
1037                 else if(!tt_aV[cmdAlt] && bJmp && tt_CalcPosDef(iDim) > iMax - 16)
 
1038                         iX = tt_PosAlt(iDim);
 
1040                         iX = tt_PosDef(iDim);
 
1046                         iX -= cx + tt_aV[cmdOff] - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0);
 
1048                         iX += tt_aV[cmdOff];
 
1050         // Prevent tip from extending past clientarea boundary
 
1052                 iX = bJmpMod ? tt_PosAlt(iDim) : iMax;
 
1053         // In case of insufficient space on both sides, ensure the left/upper part
 
1054         // of the tip be visible
 
1056                 iX = bJmpMod ? tt_PosDef(iDim) : iScrl;
 
1059 function tt_PosDef(iDim)
 
1062                 tt_bJmpVert = tt_aV[ABOVE];
 
1064                 tt_bJmpHorz = tt_aV[LEFT];
 
1065         return tt_CalcPosDef(iDim);
 
1067 function tt_PosAlt(iDim)
 
1070                 tt_bJmpVert = !tt_aV[ABOVE];
 
1072                 tt_bJmpHorz = !tt_aV[LEFT];
 
1073         return tt_CalcPosAlt(iDim);
 
1075 function tt_CalcPosDef(iDim)
 
1077         return iDim ? (tt_musY + tt_aV[OFFSETY]) : (tt_musX + tt_aV[OFFSETX]);
 
1079 function tt_CalcPosAlt(iDim)
 
1081         var cmdOff = iDim ? OFFSETY : OFFSETX;
 
1082         var dx = tt_aV[cmdOff] - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0);
 
1083         if(tt_aV[cmdOff] > 0 && dx <= 0)
 
1085         return((iDim ? (tt_musY - tt_h) : (tt_musX - tt_w)) - dx);
 
1087 function tt_PosFix()
 
1091         if(typeof(tt_aV[FIX][0]) == "number")
 
1098                 if(typeof(tt_aV[FIX][0]) == "string")
 
1099                         el = tt_GetElt(tt_aV[FIX][0]);
 
1100                 // First slot in array is direct reference to HTML element
 
1105                 // By default, vert pos is related to bottom edge of HTML element
 
1106                 if(!tt_aV[ABOVE] && el)
 
1107                         iY += tt_GetDivH(el);
 
1108                 for(; el; el = el.offsetParent)
 
1110                         iX += el.offsetLeft || 0;
 
1111                         iY += el.offsetTop || 0;
 
1114         // For a fixed tip positioned above the mouse, use the bottom edge as anchor
 
1115         // (recommended by Christophe Rebeschini, 31.1.2008)
 
1118         tt_SetTipPos(iX, iY);
 
1120 function tt_Fade(a, now, z, n)
 
1124                 now += Math.round((z - now) / n);
 
1125                 if((z > a) ? (now >= z) : (now <= z))
 
1130                                 + a + "," + now + "," + z + "," + (n - 1)
 
1132                                 tt_aV[FADEINTERVAL],
 
1136         now ? tt_SetTipOpa(now) : tt_Hide();
 
1138 function tt_SetTipOpa(opa)
 
1140         // To circumvent the opacity nesting flaws of IE, we set the opacity
 
1141         // for each sub-DIV separately, rather than for the container DIV.
 
1142         tt_SetOpa(tt_aElt[5], opa);
 
1144                 tt_SetOpa(tt_aElt[1], opa);
 
1147                 opa = Math.round(opa * 0.8);
 
1148                 tt_SetOpa(tt_aElt[7], opa);
 
1149                 tt_SetOpa(tt_aElt[8], opa);
 
1152 function tt_OnCloseBtnOver(iOver)
 
1154         var css = tt_aElt[4].style;
 
1157         css.background = tt_aV[CLOSEBTNCOLORS][iOver];
 
1158         css.color = tt_aV[CLOSEBTNCOLORS][iOver + 1];
 
1160 function tt_OnLClick(e)
 
1162         //  Ignore right-clicks
 
1163         e = e || window.event;
 
1164         if(!((e.button && e.button & 2) || (e.which && e.which == 3)))
 
1166                 if(tt_aV[CLICKSTICKY] && (tt_iState & 0x4))
 
1168                         tt_aV[STICKY] = true;
 
1171                 else if(tt_aV[CLICKCLOSE])
 
1179         return(isNaN(y = parseInt(x)) ? 0 : y);
 
1181 Number.prototype.Timer = function(s, iT, bUrge)
 
1183         if(!this.value || bUrge)
 
1184                 this.value = window.setTimeout(s, iT);
 
1186 Number.prototype.EndTimer = function()
 
1190                 window.clearTimeout(this.value);
 
1194 function tt_GetWndCliSiz(s)
 
1196         var db, y = window["inner" + s], sC = "client" + s, sN = "number";
 
1201                         // Gecko or Opera with scrollbar
 
1203                         ((db = document.body) && typeof(y2 = db[sC]) == sN && y2 &&  y2 <= y) ? y2 
 
1205                         : ((db = document.documentElement) && typeof(y2 = db[sC]) == sN && y2 && y2 <= y) ? y2
 
1206                         // No scrollbar, or clientarea size == 0, or other browser (KHTML etc.)
 
1212                 // document.documentElement.client+s functional, returns > 0
 
1213                 ((db = document.documentElement) && (y = db[sC])) ? y
 
1214                 // ... not functional, in which case document.body.client+s 
 
1215                 // is the clientarea size, fortunately
 
1219 function tt_SetOpa(el, opa)
 
1228                         // Hacks for bugs of IE:
 
1229                         // 1.) Once a CSS filter has been applied, fonts are no longer
 
1230                         // anti-aliased, so we store the previous 'non-filter' to be
 
1231                         // able to restore it
 
1232                         if(typeof(el.filtNo) == tt_u)
 
1233                                 el.filtNo = css.filter;
 
1234                         // 2.) A DIV cannot be made visible in a single step if an
 
1235                         // opacity < 100 has been applied while the DIV was hidden
 
1236                         var bVis = css.visibility != "hidden";
 
1237                         // 3.) In IE6, applying an opacity < 100 has no effect if the
 
1238                         //         element has no layout (position, size, zoom, ...)
 
1241                                 css.visibility = "visible";
 
1242                         css.filter = "alpha(opacity=" + opa + ")";
 
1244                                 css.visibility = "hidden";
 
1246                 else if(typeof(el.filtNo) != tt_u)
 
1247                         // Restore 'non-filter'
 
1248                         css.filter = el.filtNo;
 
1256                         css.KhtmlOpacity = opa; break;
 
1258                         css.KHTMLOpacity = opa; break;
 
1260                         css.MozOpacity = opa; break;
 
1262                         css.opacity = opa; break;
 
1266 function tt_Err(sErr, bIfDebug)
 
1268         if(tt_Debug || !bIfDebug)
 
1269                 alert("Tooltip Script Error Message:\n\n" + sErr);
 
1272 //============  EXTENSION (PLUGIN) MANAGER  ===============//
 
1273 function tt_ExtCmdEnum()
 
1277         // Add new command(s) to the commands enum
 
1278         for(var i in config)
 
1280                 s = "window." + i.toString().toUpperCase();
 
1281                 if(eval("typeof(" + s + ") == tt_u"))
 
1283                         eval(s + " = " + tt_aV.length);
 
1284                         tt_aV[tt_aV.length] = null;
 
1288 function tt_ExtCallFncs(arg, sFnc)
 
1291         for(var i = tt_aExt.length; i;)
 
1293                 var fnc = tt_aExt[i]["On" + sFnc];
 
1294                 // Call the method the extension has defined for this event