1/* This notice must be untouched at all times. 2Copyright (c) 2002-2008 Walter Zorn. All rights reserved. 3 4wz_tooltip.js v. 5.0 5 6The latest version is available at 7http://www.walterzorn.com 8or http://www.devira.com 9or http://www.walterzorn.de 10 11Created 1.12.2002 by Walter Zorn (Web: http://www.walterzorn.com ) 12Last modified: 4.3.2008 13 14Easy-to-use cross-browser tooltips. 15Just include the script at the beginning of the <body> section, and invoke 16Tip('Tooltip text') from the desired HTML onmouseover eventhandlers, 17and UnTip(), usually from the onmouseout eventhandlers, to hide the tip. 18No container DIV required. 19By default, width and height of tooltips are automatically adapted to content. 20Is even capable of dynamically converting arbitrary HTML elements to tooltips 21by calling TagToTip('ID_of_HTML_element_to_be_converted') instead of Tip(), 22which means you can put important, search-engine-relevant stuff into tooltips. 23Appearance of tooltips can be individually configured 24via commands passed to Tip() or TagToTip(). 25 26Tab Width: 4 27LICENSE: LGPL 28 29This library is free software; you can redistribute it and/or 30modify it under the terms of the GNU Lesser General Public 31License (LGPL) as published by the Free Software Foundation; either 32version 2.1 of the License, or (at your option) any later version. 33 34This library is distributed in the hope that it will be useful, 35but WITHOUT ANY WARRANTY; without even the implied warranty of 36MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 37 38For more details on the GNU Lesser General Public License, 39see http://www.gnu.org/copyleft/lesser.html 40*/ 41 42var config = new Object(); 43 44 45//=================== GLOBAL TOOPTIP CONFIGURATION =========================// 46var tt_Debug = true // false or true - recommended: false once you release your page to the public 47var tt_Enabled = true // Allows to (temporarily) suppress tooltips, e.g. by providing the user with a button that sets this global variable to false 48var TagsToTip = true // false or true - if true, HTML elements to be converted to tooltips via TagToTip() are automatically hidden; 49 // if false, you should hide those HTML elements yourself 50 51// For each of the following config variables there exists a command, which is 52// just the variablename in uppercase, to be passed to Tip() or TagToTip() to 53// configure tooltips individually. Individual commands override global 54// configuration. Order of commands is arbitrary. 55// Example: onmouseover="Tip('Tooltip text', LEFT, true, BGCOLOR, '#FF9900', FADEIN, 400)" 56 57config. Above = false // false or true - tooltip above mousepointer 58config. BgColor = '#E2E7FF' // Background colour (HTML colour value, in quotes) 59config. BgImg = '' // Path to background image, none if empty string '' 60config. BorderColor = '#003099' 61config. BorderStyle = 'solid' // Any permitted CSS value, but I recommend 'solid', 'dotted' or 'dashed' 62config. BorderWidth = 1 63config. CenterMouse = false // false or true - center the tip horizontally below (or above) the mousepointer 64config. ClickClose = false // false or true - close tooltip if the user clicks somewhere 65config. ClickSticky = false // false or true - make tooltip sticky if user left-clicks on the hovered element while the tooltip is active 66config. CloseBtn = false // false or true - closebutton in titlebar 67config. CloseBtnColors = ['#990000', '#FFFFFF', '#DD3333', '#FFFFFF'] // [Background, text, hovered background, hovered text] - use empty strings '' to inherit title colours 68config. CloseBtnText = ' X ' // Close button text (may also be an image tag) 69config. CopyContent = true // When converting a HTML element to a tooltip, copy only the element's content, rather than converting the element by its own 70config. Delay = 0 // Time span in ms until tooltip shows up 71config. 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 72config. FadeIn = 0 // Fade-in duration in ms, e.g. 400; 0 for no animation 73config. FadeOut = 0 74config. FadeInterval = 30 // Duration of each fade step in ms (recommended: 30) - shorter is smoother but causes more CPU-load 75config. Fix = null // Fixated position - x- an y-oordinates in brackets, e.g. [210, 480], or null for no fixation 76config. FollowMouse = true // false or true - tooltip follows the mouse 77config. FontColor = '#000044' 78config. FontFace = 'Verdana,Geneva,sans-serif' 79config. FontSize = '8pt' // E.g. '9pt' or '12px' - unit is mandatory 80config. FontWeight = 'normal' // 'normal' or 'bold'; 81config. Height = 0 // Tooltip height; 0 for automatic adaption to tooltip content, < 0 (e.g. -100) for a maximum for automatic adaption 82config. JumpHorz = false // false or true - jump horizontally to other side of mouse if tooltip would extend past clientarea boundary 83config. JumpVert = true // false or true - jump vertically " 84config. Left = false // false or true - tooltip on the left of the mouse 85config. OffsetX = 14 // Horizontal offset of left-top corner from mousepointer 86config. OffsetY = 8 // Vertical offset 87config. Opacity = 100 // Integer between 0 and 100 - opacity of tooltip in percent 88config. Padding = 3 // Spacing between border and content 89config. Shadow = false // false or true 90config. ShadowColor = '#C0C0C0' 91config. ShadowWidth = 5 92config. Sticky = false // false or true - fixate tip, ie. don't follow the mouse and don't hide on mouseout 93config. TextAlign = 'left' // 'left', 'right' or 'justify' 94config. Title = '' // Default title text applied to all tips (no default title: empty string '') 95config. TitleAlign = 'left' // 'left' or 'right' - text alignment inside the title bar 96config. TitleBgColor = '' // If empty string '', BorderColor will be used 97config. TitleFontColor = '#FFFFFF' // Color of title text - if '', BgColor (of tooltip body) will be used 98config. TitleFontFace = '' // If '' use FontFace (boldified) 99config. TitleFontSize = '' // If '' use FontSize 100config. Width = 0 // Tooltip width; 0 for automatic adaption to tooltip content; < -1 (e.g. -240) for a maximum width for that automatic adaption; 101 // -1: tooltip width confined to the width required for the titlebar 102//======= END OF TOOLTIP CONFIG, DO NOT CHANGE ANYTHING BELOW ==============// 103 104 105 106 107//===================== PUBLIC =============================================// 108function Tip() 109{ 110 tt_Tip(arguments, null); 111} 112function TagToTip() 113{ 114 var t2t = tt_GetElt(arguments[0]); 115 if(t2t) 116 tt_Tip(arguments, t2t); 117} 118function UnTip() 119{ 120 tt_OpReHref(); 121 if(tt_aV[DURATION] < 0) 122 tt_tDurt.Timer("tt_HideInit()", -tt_aV[DURATION], true); 123 else if(!(tt_aV[STICKY] && (tt_iState & 0x2))) 124 tt_HideInit(); 125} 126 127//================== PUBLIC PLUGIN API =====================================// 128// Extension eventhandlers currently supported: 129// OnLoadConfig, OnCreateContentString, OnSubDivsCreated, OnShow, OnMoveBefore, 130// OnMoveAfter, OnHideInit, OnHide, OnKill 131 132var 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 133tt_aV = new Array(), // Caches and enumerates config data for currently active tooltip 134tt_sContent, // Inner tooltip text or HTML 135tt_scrlX = 0, tt_scrlY = 0, 136tt_musX, tt_musY, 137tt_over, 138tt_x, tt_y, tt_w, tt_h; // Position, width and height of currently displayed tooltip 139 140function tt_Extension() 141{ 142 tt_ExtCmdEnum(); 143 tt_aExt[tt_aExt.length] = this; 144 return this; 145} 146function tt_SetTipPos(x, y) 147{ 148 var css = tt_aElt[0].style; 149 150 tt_x = x; 151 tt_y = y; 152 css.left = x + "px"; 153 css.top = y + "px"; 154 if(tt_ie56) 155 { 156 var ifrm = tt_aElt[tt_aElt.length - 1]; 157 if(ifrm) 158 { 159 ifrm.style.left = css.left; 160 ifrm.style.top = css.top; 161 } 162 } 163} 164function tt_HideInit() 165{ 166 if(tt_iState) 167 { 168 tt_ExtCallFncs(0, "HideInit"); 169 tt_iState &= ~0x4; 170 if(tt_flagOpa && tt_aV[FADEOUT]) 171 { 172 tt_tFade.EndTimer(); 173 if(tt_opa) 174 { 175 var n = Math.round(tt_aV[FADEOUT] / (tt_aV[FADEINTERVAL] * (tt_aV[OPACITY] / tt_opa))); 176 tt_Fade(tt_opa, tt_opa, 0, n); 177 return; 178 } 179 } 180 tt_tHide.Timer("tt_Hide();", 1, false); 181 } 182} 183function tt_Hide() 184{ 185 if(tt_db && tt_iState) 186 { 187 tt_OpReHref(); 188 if(tt_iState & 0x2) 189 { 190 tt_aElt[0].style.visibility = "hidden"; 191 tt_ExtCallFncs(0, "Hide"); 192 } 193 tt_tShow.EndTimer(); 194 tt_tHide.EndTimer(); 195 tt_tDurt.EndTimer(); 196 tt_tFade.EndTimer(); 197 if(!tt_op && !tt_ie) 198 { 199 tt_tWaitMov.EndTimer(); 200 tt_bWait = false;
201 } 202 if(tt_aV[CLICKCLOSE] || tt_aV[CLICKSTICKY]) 203 tt_RemEvtFnc(document, "mouseup", tt_OnLClick); 204 tt_ExtCallFncs(0, "Kill"); 205 // In case of a TagToTip tooltip, hide converted DOM node and 206 // re-insert it into document 207 if(tt_t2t && !tt_aV[COPYCONTENT]) 208 { 209 tt_t2t.style.display = "none"; 210 tt_MovDomNode(tt_t2t, tt_aElt[6], tt_t2tDad); 211 } 212 tt_iState = 0; 213 tt_over = null; 214 tt_ResetMainDiv(); 215 if(tt_aElt[tt_aElt.length - 1]) 216 tt_aElt[tt_aElt.length - 1].style.display = "none"; 217 } 218} 219function tt_GetElt(id) 220{ 221 return(document.getElementById ? document.getElementById(id) 222 : document.all ? document.all[id] 223 : null); 224} 225function tt_GetDivW(el) 226{ 227 return(el ? (el.offsetWidth || el.style.pixelWidth || 0) : 0); 228} 229function tt_GetDivH(el) 230{ 231 return(el ? (el.offsetHeight || el.style.pixelHeight || 0) : 0); 232} 233function tt_GetScrollX() 234{ 235 return(window.pageXOffset || (tt_db ? (tt_db.scrollLeft || 0) : 0)); 236} 237function tt_GetScrollY() 238{ 239 return(window.pageYOffset || (tt_db ? (tt_db.scrollTop || 0) : 0)); 240} 241function tt_GetClientW() 242{ 243 return(document.body && (typeof(document.body.clientWidth) != tt_u) ? document.body.clientWidth 244 : (typeof(window.innerWidth) != tt_u) ? window.innerWidth 245 : tt_db ? (tt_db.clientWidth || 0) 246 : 0); 247} 248function tt_GetClientH() 249{ 250 // Exactly this order seems to yield correct values in all major browsers 251 return(document.body && (typeof(document.body.clientHeight) != tt_u) ? document.body.clientHeight 252 : (typeof(window.innerHeight) != tt_u) ? window.innerHeight 253 : tt_db ? (tt_db.clientHeight || 0) 254 : 0); 255} 256function tt_GetEvtX(e) 257{ 258 return (e ? ((typeof(e.pageX) != tt_u) ? e.pageX : (e.clientX + tt_scrlX)) : 0); 259} 260function tt_GetEvtY(e) 261{ 262 return (e ? ((typeof(e.pageY) != tt_u) ? e.pageY : (e.clientY + tt_scrlY)) : 0); 263} 264function tt_AddEvtFnc(el, sEvt, PFnc) 265{ 266 if(el) 267 { 268 if(el.addEventListener) 269 el.addEventListener(sEvt, PFnc, false); 270 else 271 el.attachEvent("on" + sEvt, PFnc); 272 } 273} 274function tt_RemEvtFnc(el, sEvt, PFnc) 275{ 276 if(el) 277 { 278 if(el.removeEventListener) 279 el.removeEventListener(sEvt, PFnc, false); 280 else 281 el.detachEvent("on" + sEvt, PFnc); 282 } 283} 284 285//====================== PRIVATE ===========================================// 286var tt_aExt = new Array(), // Array of extension objects 287 288tt_db, tt_op, tt_ie, tt_ie56, tt_bBoxOld, // Browser flags 289tt_body, 290tt_ovr_, // HTML element the mouse is currently over 291tt_flagOpa, // Opacity support: 1=IE, 2=Khtml, 3=KHTML, 4=Moz, 5=W3C 292tt_maxPosX, tt_maxPosY, 293tt_iState = 0, // Tooltip active |= 1, shown |= 2, move with mouse |= 4 294tt_opa, // Currently applied opacity 295tt_bJmpVert, tt_bJmpHorz,// Tip temporarily on other side of mouse 296tt_t2t, tt_t2tDad, // Tag converted to tip, and its parent element in the document 297tt_elDeHref, // The tag from which we've removed the href attribute 298// Timer 299tt_tShow = new Number(0), tt_tHide = new Number(0), tt_tDurt = new Number(0), 300tt_tFade = new Number(0), tt_tWaitMov = new Number(0), 301tt_bWait = false, 302tt_u = "undefined"; 303 304 305function tt_Init() 306{ 307 tt_MkCmdEnum(); 308 // Send old browsers instantly to hell 309 if(!tt_Browser() || !tt_MkMainDiv()) 310 return; 311 tt_IsW3cBox(); 312 tt_OpaSupport(); 313 tt_AddEvtFnc(window, "scroll", tt_OnScrl); 314 // IE doesn't fire onscroll event when switching to fullscreen; 315 // fix suggested by Yoav Karpeles 14.2.2008 316 tt_AddEvtFnc(window, "resize", tt_OnScrl); 317 tt_AddEvtFnc(document, "mousemove", tt_Move); 318 // In Debug mode we search for TagToTip() calls in order to notify 319 // the user if they've forgotten to set the TagsToTip config flag 320 if(TagsToTip || tt_Debug) 321 tt_SetOnloadFnc(); 322 // Ensure the tip be hidden when the page unloads 323 tt_AddEvtFnc(window, "unload", tt_Hide); 324} 325// Creates command names by translating config variable names to upper case 326function tt_MkCmdEnum() 327{ 328 var n = 0; 329 for(var i in config) 330 eval("window." + i.toString().toUpperCase() + " = " + n++); 331 tt_aV.length = n; 332} 333function tt_Browser() 334{ 335 var n, nv, n6, w3c; 336 337 n = navigator.userAgent.toLowerCase(), 338 nv = navigator.appVersion; 339 tt_op = (document.defaultView && typeof(eval("w" + "indow" + "." + "o" + "p" + "er" + "a")) != tt_u); 340 tt_ie = n.indexOf("msie") != -1 && document.all && !tt_op; 341 if(tt_ie) 342 { 343 var ieOld = (!document.compatMode || document.compatMode == "BackCompat"); 344 tt_db = !ieOld ? document.documentElement : (document.body || null); 345 if(tt_db) 346 tt_ie56 = parseFloat(nv.substring(nv.indexOf("MSIE") + 5)) >= 5.5 347 && typeof document.body.style.maxHeight == tt_u; 348 } 349 else 350 { 351 tt_db = document.documentElement || document.body || 352 (document.getElementsByTagName ? document.getElementsByTagName("body")[0] 353 : null); 354 if(!tt_op) 355 { 356 n6 = document.defaultView && typeof document.defaultView.getComputedStyle != tt_u; 357 w3c = !n6 && document.getElementById; 358 } 359 } 360 tt_body = (document.getElementsByTagName ? document.getElementsByTagName("body")[0] 361 : (document.body || null)); 362 if(tt_ie || n6 || tt_op || w3c) 363 { 364 if(tt_body && tt_db) 365 { 366 if(document.attachEvent || document.addEventListener) 367 return true; 368 } 369 else 370 tt_Err("wz_tooltip.js must be included INSIDE the body section," 371 + " immediately after the opening <body> tag.", false); 372 } 373 tt_db = null; 374 return false;
375} 376function tt_MkMainDiv() 377{ 378 // Create the tooltip DIV 379 if(tt_body.insertAdjacentHTML) 380 tt_body.insertAdjacentHTML("afterBegin", tt_MkMainDivHtm()); 381 else if(typeof tt_body.innerHTML != tt_u && document.createElement && tt_body.appendChild) 382 tt_body.appendChild(tt_MkMainDivDom()); 383 if(window.tt_GetMainDivRefs /* FireFox Alzheimer */ && tt_GetMainDivRefs()) 384 return true; 385 tt_db = null; 386 return false; 387} 388function tt_MkMainDivHtm() 389{ 390 return('<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>') 392 : '')); 393} 394function tt_MkMainDivDom() 395{ 396 var el = document.createElement("div"); 397 if(el) 398 el.id = "WzTtDiV"; 399 return el; 400} 401function tt_GetMainDivRefs() 402{ 403 tt_aElt[0] = tt_GetElt("WzTtDiV"); 404 if(tt_ie56 && tt_aElt[0]) 405 { 406 tt_aElt[tt_aElt.length - 1] = tt_GetElt("WzTtIfRm"); 407 if(!tt_aElt[tt_aElt.length - 1]) 408 tt_aElt[0] = null; 409 } 410 if(tt_aElt[0]) 411 { 412 var css = tt_aElt[0].style; 413 414 css.visibility = "hidden"; 415 css.position = "absolute"; 416 css.overflow = "hidden"; 417 return true; 418 } 419 return false; 420} 421function tt_ResetMainDiv() 422{ 423 var w = (window.screen && screen.width) ? screen.width : 10000; 424 425 tt_SetTipPos(-w, 0); 426 tt_aElt[0].innerHTML = ""; 427 tt_aElt[0].style.width = (w - 1) + "px"; 428 tt_h = 0; 429} 430function tt_IsW3cBox() 431{ 432 var css = tt_aElt[0].style; 433 434 css.padding = "10px"; 435 css.width = "40px"; 436 tt_bBoxOld = (tt_GetDivW(tt_aElt[0]) == 40); 437 css.padding = "0px"; 438 tt_ResetMainDiv(); 439} 440function tt_OpaSupport() 441{ 442 var css = tt_body.style; 443 444 tt_flagOpa = (typeof(css.filter) != tt_u) ? 1 445 : (typeof(css.KhtmlOpacity) != tt_u) ? 2 446 : (typeof(css.KHTMLOpacity) != tt_u) ? 3 447 : (typeof(css.MozOpacity) != tt_u) ? 4 448 : (typeof(css.opacity) != tt_u) ? 5 449 : 0; 450} 451// Ported from http://dean.edwards.name/weblog/2006/06/again/ 452// (Dean Edwards et al.) 453function tt_SetOnloadFnc() 454{ 455 tt_AddEvtFnc(document, "DOMContentLoaded", tt_HideSrcTags); 456 tt_AddEvtFnc(window, "load", tt_HideSrcTags); 457 if(tt_body.attachEvent) 458 tt_body.attachEvent("onreadystatechange", 459 function() { 460 if(tt_body.readyState == "complete") 461 tt_HideSrcTags(); 462 } ); 463 if(/WebKit|KHTML/i.test(navigator.userAgent)) 464 { 465 var t = setInterval(function() { 466 if(/loaded|complete/.test(document.readyState)) 467 { 468 clearInterval(t); 469 tt_HideSrcTags(); 470 } 471 }, 10); 472 } 473} 474function tt_HideSrcTags() 475{ 476 if(!window.tt_HideSrcTags || window.tt_HideSrcTags.done) 477 return; 478 window.tt_HideSrcTags.done = true; 479 if(!tt_HideSrcTagsRecurs(tt_body)) 480 tt_Err("There are HTML elements to be converted to tooltips.\nIf you" 481 + " want these HTML elements to be automatically hidden, you" 482 + " must edit wz_tooltip.js, and set TagsToTip in the global" 483 + " tooltip configuration to true.", true); 484} 485function tt_HideSrcTagsRecurs(dad) 486{ 487 var ovr, asT2t; 488 // Walk the DOM tree for tags that have an onmouseover or onclick attribute 489 // containing a TagToTip('...') call. 490 // (.childNodes first since .children is bugous in Safari) 491 var a = dad.childNodes || dad.children || null; 492 493 for(var i = a ? a.length : 0; i;) 494 {--i; 495 if(!tt_HideSrcTagsRecurs(a[i])) 496 return false; 497 ovr = a[i].getAttribute ? (a[i].getAttribute("onmouseover") || a[i].getAttribute("onclick")) 498 : (typeof a[i].onmouseover == "function") ? (a[i].onmouseover || a[i].onclick) 499 : null; 500 if(ovr) 501 { 502 asT2t = ovr.toString().match(/TagToTip\s*\(\s*'[^'.]+'\s*[\),]/); 503 if(asT2t && asT2t.length) 504 { 505 if(!tt_HideSrcTag(asT2t[0])) 506 return false; 507 } 508 } 509 } 510 return true; 511} 512function tt_HideSrcTag(sT2t) 513{ 514 var id, el; 515 516 // The ID passed to the found TagToTip() call identifies an HTML element 517 // to be converted to a tooltip, so hide that element 518 id = sT2t.replace(/.+'([^'.]+)'.+/, "$1"); 519 el = tt_GetElt(id); 520 if(el) 521 { 522 if(tt_Debug && !TagsToTip) 523 return false; 524 else 525 el.style.display = "none"; 526 } 527 else 528 tt_Err("Invalid ID\n'" + id + "'\npassed to TagToTip()." 529 + " There exists no HTML element with that ID.", true); 530 return true; 531} 532function tt_Tip(arg, t2t) 533{ 534 if(!tt_db) 535 return; 536 if(tt_iState) 537 tt_Hide(); 538 if(!tt_Enabled) 539 return; 540 tt_t2t = t2t; 541 if(!tt_ReadCmds(arg)) 542 return; 543 tt_iState = 0x1 | 0x4; 544 tt_AdaptConfig1(); 545 tt_MkTipContent(arg); 546 tt_MkTipSubDivs(); 547 tt_FormatTip(); 548 tt_bJmpVert = false;
549 tt_bJmpHorz = false; 550 tt_maxPosX = tt_GetClientW() + tt_scrlX - tt_w - 1; 551 tt_maxPosY = tt_GetClientH() + tt_scrlY - tt_h - 1; 552 tt_AdaptConfig2(); 553 // Ensure the tip be shown and positioned before the first onmousemove 554 tt_OverInit(); 555 tt_ShowInit(); 556 tt_Move(); 557} 558function tt_ReadCmds(a) 559{ 560 var i; 561 562 // First load the global config values, to initialize also values 563 // for which no command has been passed 564 i = 0; 565 for(var j in config) 566 tt_aV[i++] = config[j]; 567 // Then replace each cached config value for which a command has been 568 // passed (ensure the # of command args plus value args be even) 569 if(a.length & 1) 570 { 571 for(i = a.length - 1; i > 0; i -= 2) 572 tt_aV[a[i - 1]] = a[i]; 573 return true; 574 } 575 tt_Err("Incorrect call of Tip() or TagToTip().\n" 576 + "Each command must be followed by a value.", true); 577 return false; 578} 579function tt_AdaptConfig1() 580{ 581 tt_ExtCallFncs(0, "LoadConfig"); 582 // Inherit unspecified title formattings from body 583 if(!tt_aV[TITLEBGCOLOR].length) 584 tt_aV[TITLEBGCOLOR] = tt_aV[BORDERCOLOR]; 585 if(!tt_aV[TITLEFONTCOLOR].length) 586 tt_aV[TITLEFONTCOLOR] = tt_aV[BGCOLOR]; 587 if(!tt_aV[TITLEFONTFACE].length) 588 tt_aV[TITLEFONTFACE] = tt_aV[FONTFACE]; 589 if(!tt_aV[TITLEFONTSIZE].length) 590 tt_aV[TITLEFONTSIZE] = tt_aV[FONTSIZE]; 591 if(tt_aV[CLOSEBTN]) 592 { 593 // Use title colours for non-specified closebutton colours 594 if(!tt_aV[CLOSEBTNCOLORS]) 595 tt_aV[CLOSEBTNCOLORS] = new Array("", "", "", ""); 596 for(var i = 4; i;) 597 {--i; 598 if(!tt_aV[CLOSEBTNCOLORS][i].length) 599 tt_aV[CLOSEBTNCOLORS][i] = (i & 1) ? tt_aV[TITLEFONTCOLOR] : tt_aV[TITLEBGCOLOR]; 600 } 601 // Enforce titlebar be shown 602 if(!tt_aV[TITLE].length) 603 tt_aV[TITLE] = " "; 604 } 605 // Circumvents broken display of images and fade-in flicker in Geckos < 1.8 606 if(tt_aV[OPACITY] == 100 && typeof tt_aElt[0].style.MozOpacity != tt_u && !Array.every) 607 tt_aV[OPACITY] = 99; 608 // Smartly shorten the delay for fade-in tooltips 609 if(tt_aV[FADEIN] && tt_flagOpa && tt_aV[DELAY] > 100) 610 tt_aV[DELAY] = Math.max(tt_aV[DELAY] - tt_aV[FADEIN], 100); 611} 612function tt_AdaptConfig2() 613{ 614 if(tt_aV[CENTERMOUSE]) 615 { 616 tt_aV[OFFSETX] -= ((tt_w - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0)) >> 1); 617 tt_aV[JUMPHORZ] = false; 618 } 619} 620// Expose content globally so extensions can modify it 621function tt_MkTipContent(a) 622{ 623 if(tt_t2t) 624 { 625 if(tt_aV[COPYCONTENT]) 626 tt_sContent = tt_t2t.innerHTML; 627 else 628 tt_sContent = ""; 629 } 630 else 631 tt_sContent = a[0]; 632 tt_ExtCallFncs(0, "CreateContentString"); 633} 634function tt_MkTipSubDivs() 635{ 636 var sCss = 'position:relative;margin:0px;padding:0px;border-width:0px;left:0px;top:0px;line-height:normal;width:auto;', 637 sTbTrTd = ' cellspacing=0 cellpadding=0 border=0 style="' + sCss + '"><tbody style="' + sCss + '"><tr><td '; 638 639 tt_aElt[0].innerHTML = 640 ('' 641 + (tt_aV[TITLE].length ? 642 ('<div id="WzTiTl" style="position:relative;z-index:1;">' 643 + '<table id="WzTiTlTb"' + sTbTrTd + 'id="WzTiTlI" style="' + sCss + '">' 644 + tt_aV[TITLE] 645 + '</td>' 646 + (tt_aV[CLOSEBTN] ? 647 ('<td align="right" style="' + sCss 648 + 'text-align:right;">' 649 + '<span id="WzClOsE" style="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] 653 + '</span></td>') 654 : '') 655 + '</tr></tbody></table></div>') 656 : '') 657 + '<div id="WzBoDy" style="position:relative;z-index:0;">' 658 + '<table' + sTbTrTd + 'id="WzBoDyI" style="' + sCss + '">' 659 + tt_sContent 660 + '</td></tr></tbody></table></div>' 661 + (tt_aV[SHADOW] 662 ? ('<div id="WzTtShDwR" style="position:absolute;overflow:hidden;"></div>' 663 + '<div id="WzTtShDwB" style="position:relative;overflow:hidden;"></div>') 664 : '') 665 ); 666 tt_GetSubDivRefs(); 667 // Convert DOM node to tip 668 if(tt_t2t && !tt_aV[COPYCONTENT]) 669 { 670 // Store the tag's parent element so we can restore that DOM branch 671 // once the tooltip is hidden 672 tt_t2tDad = tt_t2t.parentNode || tt_t2t.parentElement || tt_t2t.offsetParent || null; 673 if(tt_t2tDad) 674 { 675 tt_MovDomNode(tt_t2t, tt_t2tDad, tt_aElt[6]); 676 tt_t2t.style.display = "block"; 677 } 678 } 679 tt_ExtCallFncs(0, "SubDivsCreated"); 680} 681function tt_GetSubDivRefs() 682{ 683 var aId = new Array("WzTiTl", "WzTiTlTb", "WzTiTlI", "WzClOsE", "WzBoDy", "WzBoDyI", "WzTtShDwB", "WzTtShDwR"); 684 685 for(var i = aId.length; i; --i) 686 tt_aElt[i] = tt_GetElt(aId[i - 1]); 687} 688function tt_FormatTip() 689{ 690 var css, w, h, iOffY, iOffSh, 691 iAdd = (tt_aV[PADDING] + tt_aV[BORDERWIDTH]) << 1; 692 693 //--------- Title DIV ---------- 694 if(tt_aV[TITLE].length) 695 { 696 css = tt_aElt[1].style; 697 css.background = tt_aV[TITLEBGCOLOR]; 698 css.paddingTop = (tt_aV[CLOSEBTN] ? 2 : 0) + "px"; 699 css.paddingBottom = "1px"; 700 css.paddingLeft = css.paddingRight = tt_aV[PADDING] + "px"; 701 css = tt_aElt[3].style; 702 css.color = tt_aV[TITLEFONTCOLOR]; 703 css.whiteSpace = "nowrap"; 704 css.fontFamily = tt_aV[TITLEFONTFACE]; 705 css.fontSize = tt_aV[TITLEFONTSIZE]; 706 css.fontWeight = "bold"; 707 css.textAlign = tt_aV[TITLEALIGN]; 708 // Close button DIV 709 if(tt_aElt[4]) 710 { 711 css.paddingRight = (tt_aV[PADDING] << 1) + "px"; 712 css = tt_aElt[4].style; 713 css.background = tt_aV[CLOSEBTNCOLORS][0]; 714 css.color = tt_aV[CLOSEBTNCOLORS][1]; 715 css.fontFamily = tt_aV[TITLEFONTFACE]; 716 css.fontSize = tt_aV[TITLEFONTSIZE]; 717 css.fontWeight = "bold"; 718 } 719 if(tt_aV[WIDTH] > 0) 720 tt_w = tt_aV[WIDTH]; 721 else 722 { 723 tt_w = tt_GetDivW(tt_aElt[3]) + tt_GetDivW(tt_aElt[4]); 724 // Some spacing between title DIV and closebutton 725 if(tt_aElt[4]) 726 tt_w += tt_aV[PADDING]; 727 // Restrict auto width to max width 728 if(tt_aV[WIDTH] < -1 && tt_w > -tt_aV[WIDTH]) 729 tt_w = -tt_aV[WIDTH]; 730 } 731 // Ensure the top border of the body DIV be covered by the title DIV 732 iOffY = -tt_aV[BORDERWIDTH]; 733 } 734 else 735 { 736 tt_w = 0; 737 iOffY = 0; 738 } 739 740 //-------- Body DIV ------------ 741 css = tt_aElt[5].style; 742 css.top = iOffY + "px"; 743 if(tt_aV[BORDERWIDTH]) 744 { 745 css.borderColor = tt_aV[BORDERCOLOR]; 746 css.borderStyle = tt_aV[BORDERSTYLE]; 747 css.borderWidth = tt_aV[BORDERWIDTH] + "px"; 748 } 749 if(tt_aV[BGCOLOR].length) 750 css.background = tt_aV[BGCOLOR]; 751 if(tt_aV[BGIMG].length) 752 css.backgroundImage = "url(" + tt_aV[BGIMG] + ")"; 753 css.padding = tt_aV[PADDING] + "px"; 754 css.textAlign = tt_aV[TEXTALIGN]; 755 if(tt_aV[HEIGHT]) 756 { 757 css.overflow = "auto"; 758 if(tt_aV[HEIGHT] > 0) 759 css.height = (tt_aV[HEIGHT] + iAdd) + "px"; 760 else 761 tt_h = iAdd - tt_aV[HEIGHT]; 762 } 763 // TD inside body DIV 764 css = tt_aElt[6].style; 765 css.color = tt_aV[FONTCOLOR]; 766 css.fontFamily = tt_aV[FONTFACE]; 767 css.fontSize = tt_aV[FONTSIZE]; 768 css.fontWeight = tt_aV[FONTWEIGHT]; 769 css.background = ""; 770 css.textAlign = tt_aV[TEXTALIGN]; 771 if(tt_aV[WIDTH] > 0) 772 w = tt_aV[WIDTH]; 773 // Width like title (if existent) 774 else if(tt_aV[WIDTH] == -1 && tt_w) 775 w = tt_w; 776 else 777 { 778 // Measure width of the body's inner TD, as some browsers would expand 779 // the container and outer body DIV to 100% 780 w = tt_GetDivW(tt_aElt[6]); 781 // Restrict auto width to max width 782 if(tt_aV[WIDTH] < -1 && w > -tt_aV[WIDTH]) 783 w = -tt_aV[WIDTH]; 784 } 785 if(w > tt_w) 786 tt_w = w; 787 tt_w += iAdd; 788 789 //--------- Shadow DIVs ------------ 790 if(tt_aV[SHADOW]) 791 { 792 tt_w += tt_aV[SHADOWWIDTH]; 793 iOffSh = Math.floor((tt_aV[SHADOWWIDTH] * 4) / 3); 794 // Bottom shadow 795 css = tt_aElt[7].style; 796 css.top = iOffY + "px"; 797 css.left = iOffSh + "px"; 798 css.width = (tt_w - iOffSh - tt_aV[SHADOWWIDTH]) + "px"; 799 css.height = tt_aV[SHADOWWIDTH] + "px"; 800 css.background = tt_aV[SHADOWCOLOR]; 801 // Right shadow 802 css = tt_aElt[8].style; 803 css.top = iOffSh + "px"; 804 css.left = (tt_w - tt_aV[SHADOWWIDTH]) + "px"; 805 css.width = tt_aV[SHADOWWIDTH] + "px"; 806 css.background = tt_aV[SHADOWCOLOR]; 807 } 808 else 809 iOffSh = 0; 810 811 //-------- Container DIV ------- 812 tt_SetTipOpa(tt_aV[FADEIN] ? 0 : tt_aV[OPACITY]); 813 tt_FixSize(iOffY, iOffSh); 814} 815// Fixate the size so it can't dynamically change while the tooltip is moving. 816function tt_FixSize(iOffY, iOffSh) 817{ 818 var wIn, wOut, h, add, i; 819 820 tt_aElt[0].style.width = tt_w + "px"; 821 tt_aElt[0].style.pixelWidth = tt_w; 822 wOut = tt_w - ((tt_aV[SHADOW]) ? tt_aV[SHADOWWIDTH] : 0); 823 // Body
824 wIn = wOut; 825 if(!tt_bBoxOld) 826 wIn -= (tt_aV[PADDING] + tt_aV[BORDERWIDTH]) << 1; 827 tt_aElt[5].style.width = wIn + "px"; 828 // Title 829 if(tt_aElt[1]) 830 { 831 wIn = wOut - (tt_aV[PADDING] << 1); 832 if(!tt_bBoxOld) 833 wOut = wIn; 834 tt_aElt[1].style.width = wOut + "px"; 835 tt_aElt[2].style.width = wIn + "px"; 836 } 837 // Max height specified 838 if(tt_h) 839 { 840 h = tt_GetDivH(tt_aElt[5]); 841 if(h > tt_h) 842 { 843 if(!tt_bBoxOld) 844 tt_h -= (tt_aV[PADDING] + tt_aV[BORDERWIDTH]) << 1; 845 tt_aElt[5].style.height = tt_h + "px"; 846 } 847 } 848 tt_h = tt_GetDivH(tt_aElt[0]) + iOffY; 849 // Right shadow 850 if(tt_aElt[8]) 851 tt_aElt[8].style.height = (tt_h - iOffSh) + "px"; 852 i = tt_aElt.length - 1; 853 if(tt_aElt[i]) 854 { 855 tt_aElt[i].style.width = tt_w + "px"; 856 tt_aElt[i].style.height = tt_h + "px"; 857 } 858} 859function tt_DeAlt(el) 860{ 861 var aKid; 862 863 if(el) 864 { 865 if(el.alt) 866 el.alt = ""; 867 if(el.title) 868 el.title = ""; 869 aKid = el.childNodes || el.children || null; 870 if(aKid) 871 { 872 for(var i = aKid.length; i;) 873 tt_DeAlt(aKid[--i]); 874 } 875 } 876} 877// This hack removes the native tooltips over links in Opera 878function tt_OpDeHref(el) 879{ 880 if(!tt_op) 881 return; 882 if(tt_elDeHref) 883 tt_OpReHref(); 884 while(el) 885 { 886 if(el.hasAttribute("href")) 887 { 888 el.t_href = el.getAttribute("href"); 889 el.t_stats = window.status; 890 el.removeAttribute("href"); 891 el.style.cursor = "hand"; 892 tt_AddEvtFnc(el, "mousedown", tt_OpReHref); 893 window.status = el.t_href; 894 tt_elDeHref = el; 895 break; 896 } 897 el = el.parentElement; 898 } 899} 900function tt_OpReHref() 901{ 902 if(tt_elDeHref) 903 { 904 tt_elDeHref.setAttribute("href", tt_elDeHref.t_href); 905 tt_RemEvtFnc(tt_elDeHref, "mousedown", tt_OpReHref); 906 window.status = tt_elDeHref.t_stats; 907 tt_elDeHref = null; 908 } 909} 910function tt_OverInit() 911{ 912 if(window.event) 913 tt_over = window.event.target || window.event.srcElement; 914 else 915 tt_over = tt_ovr_; 916 tt_DeAlt(tt_over); 917 tt_OpDeHref(tt_over); 918} 919function tt_ShowInit() 920{ 921 tt_tShow.Timer("tt_Show()", tt_aV[DELAY], true); 922 if(tt_aV[CLICKCLOSE] || tt_aV[CLICKSTICKY]) 923 tt_AddEvtFnc(document, "mouseup", tt_OnLClick); 924} 925function tt_Show() 926{ 927 var css = tt_aElt[0].style; 928 929 // Override the z-index of the topmost wz_dragdrop.js D&D item 930 css.zIndex = Math.max((window.dd && dd.z) ? (dd.z + 2) : 0, 1010); 931 if(tt_aV[STICKY] || !tt_aV[FOLLOWMOUSE]) 932 tt_iState &= ~0x4; 933 if(tt_aV[DURATION] > 0) 934 tt_tDurt.Timer("tt_HideInit()", tt_aV[DURATION], true); 935 tt_ExtCallFncs(0, "Show") 936 css.visibility = "visible"; 937 tt_iState |= 0x2; 938 if(tt_aV[FADEIN]) 939 tt_Fade(0, 0, tt_aV[OPACITY], Math.round(tt_aV[FADEIN] / tt_aV[FADEINTERVAL])); 940 tt_ShowIfrm(); 941} 942function tt_ShowIfrm() 943{ 944 if(tt_ie56) 945 { 946 var ifrm = tt_aElt[tt_aElt.length - 1]; 947 if(ifrm) 948 { 949 var css = ifrm.style; 950 css.zIndex = tt_aElt[0].style.zIndex - 1; 951 css.display = "block"; 952 } 953 } 954} 955function tt_Move(e) 956{ 957 if(e) 958 tt_ovr_ = e.target || e.srcElement; 959 e = e || window.event; 960 if(e) 961 { 962 tt_musX = tt_GetEvtX(e); 963 tt_musY = tt_GetEvtY(e); 964 } 965 if(tt_iState & 0x04) 966 { 967 // Prevent jam of mousemove events 968 if(!tt_op && !tt_ie) 969 { 970 if(tt_bWait) 971 return; 972 tt_bWait = true; 973 tt_tWaitMov.Timer("tt_bWait = false;", 1, true); 974 } 975 if(tt_aV[FIX]) 976 { 977 var iY = tt_aV[FIX][1]; 978 // For a fixed tip to be positioned above the mouse, use the 979 // bottom edge as anchor 980 // (recommended by Christophe Rebeschini, 31.1.2008) 981 if(tt_aV[ABOVE]) 982 iY -= tt_h; 983 tt_iState &= ~0x4; 984 tt_SetTipPos(tt_aV[FIX][0], tt_aV[FIX][1]); 985 } 986 else if(!tt_ExtCallFncs(e, "MoveBefore")) 987 tt_SetTipPos(tt_Pos(0), tt_Pos(1)); 988 tt_ExtCallFncs([tt_musX, tt_musY], "MoveAfter") 989 } 990} 991function tt_Pos(iDim) 992{ 993 var iX, bJmpMode, cmdAlt, cmdOff, cx, iMax, iScrl, iMus, bJmp; 994 995 // Map values according to dimension to calculate 996 if(iDim) 997 { 998 bJmpMode = tt_aV[JUMPVERT]; 999 cmdAlt = ABOVE; 1000 cmdOff = OFFSETY; 1001 cx = tt_h; 1002 iMax = tt_maxPosY; 1003 iScrl = tt_scrlY; 1004 iMus = tt_musY; 1005 bJmp = tt_bJmpVert; 1006 } 1007 else 1008 { 1009 bJmpMode = tt_aV[JUMPHORZ]; 1010 cmdAlt = LEFT; 1011 cmdOff = OFFSETX; 1012 cx = tt_w; 1013 iMax = tt_maxPosX; 1014 iScrl = tt_scrlX; 1015 iMus = tt_musX; 1016 bJmp = tt_bJmpHorz; 1017 } 1018 if(bJmpMode) 1019 { 1020 if(tt_aV[cmdAlt] && (!bJmp || tt_CalcPosAlt(iDim) >= iScrl + 16)) 1021 iX = tt_PosAlt(iDim); 1022 else if(!tt_aV[cmdAlt] && bJmp && tt_CalcPosDef(iDim) > iMax - 16) 1023 iX = tt_PosAlt(iDim); 1024 else 1025 iX = tt_PosDef(iDim); 1026 } 1027 else 1028 { 1029 iX = iMus; 1030 if(tt_aV[cmdAlt]) 1031 iX -= cx + tt_aV[cmdOff] - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0); 1032 else 1033 iX += tt_aV[cmdOff]; 1034 } 1035 // Prevent tip from extending past clientarea boundary 1036 if(iX > iMax) 1037 iX = bJmpMode ? tt_PosAlt(iDim) : iMax; 1038 // In case of insufficient space on both sides, ensure the left/upper part 1039 // of the tip be visible 1040 if(iX < iScrl) 1041 iX = bJmpMode ? tt_PosDef(iDim) : iScrl; 1042 return iX; 1043} 1044function tt_PosDef(iDim) 1045{ 1046 if(iDim) 1047 tt_bJmpVert = tt_aV[ABOVE]; 1048 else 1049 tt_bJmpHorz = tt_aV[LEFT]; 1050 return tt_CalcPosDef(iDim); 1051} 1052function tt_PosAlt(iDim) 1053{ 1054 if(iDim) 1055 tt_bJmpVert = !tt_aV[ABOVE]; 1056 else 1057 tt_bJmpHorz = !tt_aV[LEFT]; 1058 return tt_CalcPosAlt(iDim); 1059} 1060function tt_CalcPosDef(iDim) 1061{ 1062 return iDim ? (tt_musY + tt_aV[OFFSETY]) : (tt_musX + tt_aV[OFFSETX]); 1063} 1064function tt_CalcPosAlt(iDim) 1065{ 1066 var cmdOff = iDim ? OFFSETY : OFFSETX; 1067 var dx = tt_aV[cmdOff] - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0); 1068 if(tt_aV[cmdOff] > 0 && dx <= 0) 1069 dx = 1; 1070 return((iDim ? (tt_musY - tt_h) : (tt_musX - tt_w)) - dx); 1071} 1072function tt_Fade(a, now, z, n) 1073{ 1074 if(n) 1075 { 1076 now += Math.round((z - now) / n); 1077 if((z > a) ? (now >= z) : (now <= z)) 1078 now = z; 1079 else 1080 tt_tFade.Timer("tt_Fade(" 1081 + a + "," + now + "," + z + "," + (n - 1) 1082 + ")", 1083 tt_aV[FADEINTERVAL], 1084 true); 1085 } 1086 now ? tt_SetTipOpa(now) : tt_Hide(); 1087} 1088function tt_SetTipOpa(opa) 1089{ 1090 // To circumvent the opacity nesting flaws of IE, we set the opacity
1091 // for each sub-DIV separately, rather than for the container DIV. 1092 tt_SetOpa(tt_aElt[5], opa); 1093 if(tt_aElt[1]) 1094 tt_SetOpa(tt_aElt[1], opa); 1095 if(tt_aV[SHADOW]) 1096 { 1097 opa = Math.round(opa * 0.8); 1098 tt_SetOpa(tt_aElt[7], opa); 1099 tt_SetOpa(tt_aElt[8], opa); 1100 } 1101} 1102function tt_OnScrl() 1103{ 1104 tt_scrlX = tt_GetScrollX(); 1105 tt_scrlY = tt_GetScrollY(); 1106} 1107function tt_OnCloseBtnOver(iOver) 1108{ 1109 var css = tt_aElt[4].style; 1110 1111 iOver <<= 1; 1112 css.background = tt_aV[CLOSEBTNCOLORS][iOver]; 1113 css.color = tt_aV[CLOSEBTNCOLORS][iOver + 1]; 1114} 1115function tt_OnLClick(e) 1116{ 1117 // Ignore right-clicks 1118 e = e || window.event; 1119 if(!((e.button && e.button & 2) || (e.which && e.which == 3))) 1120 { 1121 if(tt_aV[CLICKSTICKY] && (tt_iState & 0x4)) 1122 { 1123 tt_aV[STICKY] = true; 1124 tt_iState &= ~0x4; 1125 } 1126 else if(tt_aV[CLICKCLOSE]) 1127 tt_HideInit(); 1128 } 1129} 1130function tt_Int(x) 1131{ 1132 var y; 1133 1134 return(isNaN(y = parseInt(x)) ? 0 : y); 1135} 1136Number.prototype.Timer = function(s, iT, bUrge) 1137{ 1138 if(!this.value || bUrge) 1139 this.value = window.setTimeout(s, iT); 1140} 1141Number.prototype.EndTimer = function() 1142{ 1143 if(this.value) 1144 { 1145 window.clearTimeout(this.value); 1146 this.value = 0; 1147 } 1148} 1149function tt_SetOpa(el, opa) 1150{ 1151 var css = el.style; 1152 1153 tt_opa = opa; 1154 if(tt_flagOpa == 1) 1155 { 1156 if(opa < 100) 1157 { 1158 // Hacks for bugs of IE: 1159 // 1.) Once a CSS filter has been applied, fonts are no longer 1160 // anti-aliased, so we store the previous 'non-filter' to be 1161 // able to restore it 1162 if(typeof(el.filtNo) == tt_u) 1163 el.filtNo = css.filter; 1164 // 2.) A DIV cannot be made visible in a single step if an 1165 // opacity < 100 has been applied while the DIV was hidden 1166 var bVis = css.visibility != "hidden"; 1167 // 3.) In IE6, applying an opacity < 100 has no effect if the 1168 // element has no layout (position, size, zoom, ...) 1169 css.zoom = "100%"; 1170 if(!bVis) 1171 css.visibility = "visible"; 1172 css.filter = "alpha(opacity=" + opa + ")"; 1173 if(!bVis) 1174 css.visibility = "hidden"; 1175 } 1176 else if(typeof(el.filtNo) != tt_u) 1177 // Restore 'non-filter' 1178 css.filter = el.filtNo; 1179 } 1180 else 1181 { 1182 opa /= 100.0; 1183 switch(tt_flagOpa) 1184 { 1185 case 2: 1186 css.KhtmlOpacity = opa; break; 1187 case 3: 1188 css.KHTMLOpacity = opa; break; 1189 case 4: 1190 css.MozOpacity = opa; break; 1191 case 5: 1192 css.opacity = opa; break; 1193 } 1194 } 1195} 1196function tt_MovDomNode(el, dadFrom, dadTo) 1197{ 1198 if(dadFrom) 1199 dadFrom.removeChild(el); 1200 if(dadTo) 1201 dadTo.appendChild(el); 1202} 1203function tt_Err(sErr, bIfDebug) 1204{ 1205 if(tt_Debug || !bIfDebug) 1206 alert("Tooltip Script Error Message:\n\n" + sErr); 1207} 1208 1209//============ EXTENSION (PLUGIN) MANAGER ===============// 1210function tt_ExtCmdEnum() 1211{ 1212 var s; 1213 1214 // Add new command(s) to the commands enum 1215 for(var i in config) 1216 { 1217 s = "window." + i.toString().toUpperCase(); 1218 if(eval("typeof(" + s + ") == tt_u")) 1219 { 1220 eval(s + " = " + tt_aV.length); 1221 tt_aV[tt_aV.length] = null; 1222 } 1223 } 1224} 1225function tt_ExtCallFncs(arg, sFnc) 1226{ 1227 var b = false;
1228 for(var i = tt_aExt.length; i;) 1229 {--i; 1230 var fnc = tt_aExt[i]["On" + sFnc]; 1231 // Call the method the extension has defined for this event 1232 if(fnc && fnc(arg)) 1233 b = true; 1234 } 1235 return b; 1236} 1237 1238tt_Init();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.