Project

General

Profile

1
/* This notice must be untouched at all times.
2
Copyright (c) 2002-2008 Walter Zorn. All rights reserved.
3

    
4
wz_tooltip.js     v. 5.31
5

    
6
The latest version is available at
7
http://www.walterzorn.com
8
or http://www.devira.com
9
or http://www.walterzorn.de
10

    
11
Created 1.12.2002 by Walter Zorn (Web: http://www.walterzorn.com )
12
Last modified: 7.11.2008
13

    
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().
26

    
27
Tab Width: 4
28
LICENSE: LGPL
29

    
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.
34

    
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.
38

    
39
For more details on the GNU Lesser General Public License,
40
see http://www.gnu.org/copyleft/lesser.html
41
*/
42

    
43
var config = new Object();
44

    
45
//===================  GLOBAL TOOLTIP CONFIGURATION  =========================//
46
var tt_Debug    = true        // false or true - recommended: false once you release your page to the public
47
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
48
var 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

    
57
config. Above            = false        // false or true - tooltip above mousepointer
58
config. BgColor          = '#F8F6CC'    // Background colour (HTML colour value, in quotes)
59
config. BgImg            = ''        // Path to background image, none if empty string ''
60
config. BorderColor      = '#003099'
61
config. BorderStyle      = 'solid'    // Any permitted CSS value, but I recommend 'solid', 'dotted' or 'dashed'
62
config. BorderWidth      = 1
63
config. CenterMouse      = false        // false or true - center the tip horizontally below (or above) the mousepointer
64
config. ClickClose       = false        // false or true - close tooltip if the user clicks somewhere
65
config. ClickSticky      = false        // false or true - make tooltip sticky if user left-clicks on the hovered element while the tooltip is active
66
config. CloseBtn         = false        // false or true - closebutton in titlebar
67
config. CloseBtnColors   = ['#990000', '#FFFFFF', '#DD3333', '#FFFFFF']    // [Background, text, hovered background, hovered text] - use empty strings '' to inherit title colours
68
config. CloseBtnText     = '&nbsp;X&nbsp;'    // Close button text (may also be an image tag)
69
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
70
config. Delay            = 400        // Time span in ms until tooltip shows up
71
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
72
config. Exclusive        = false        // false or true - no other tooltip can appear until the current one has actively been closed
73
config. FadeIn           = 100        // Fade-in duration in ms, e.g. 400; 0 for no animation
74
config. FadeOut          = 100
75
config. FadeInterval     = 30        // Duration of each fade step in ms (recommended: 30) - shorter is smoother but causes more CPU-load
76
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.
77
config. FollowMouse      = true        // false or true - tooltip follows the mouse
78
config. FontColor        = '#000044'
79
config. FontFace         = 'Verdana,Geneva,sans-serif'
80
config. FontSize         = '8pt'        // E.g. '9pt' or '12px' - unit is mandatory
81
config. FontWeight       = 'normal'    // 'normal' or 'bold';
82
config. Height           = 0            // Tooltip height; 0 for automatic adaption to tooltip content, < 0 (e.g. -100) for a maximum for automatic adaption
83
config. JumpHorz         = false        // false or true - jump horizontally to other side of mouse if tooltip would extend past clientarea boundary
84
config. JumpVert         = true        // false or true - jump vertically        "
85
config. Left             = false        // false or true - tooltip on the left of the mouse
86
config. OffsetX          = 14        // Horizontal offset of left-top corner from mousepointer
87
config. OffsetY          = 8            // Vertical offset
88
config. Opacity          = 100        // Integer between 0 and 100 - opacity of tooltip in percent
89
config. Padding          = 3            // Spacing between border and content
90
config. Shadow           = false        // false or true
91
config. ShadowColor      = '#C0C0C0'
92
config. ShadowWidth      = 5
93
config. Sticky           = false        // false or true - fixate tip, ie. don't follow the mouse and don't hide on mouseout
94
config. TextAlign        = 'left'    // 'left', 'right' or 'justify'
95
config. Title            = ''        // Default title text applied to all tips (no default title: empty string '')
96
config. TitleAlign       = 'left'    // 'left' or 'right' - text alignment inside the title bar
97
config. TitleBgColor     = ''        // If empty string '', BorderColor will be used
98
config. TitleFontColor   = '#FFFFFF'    // Color of title text - if '', BgColor (of tooltip body) will be used
99
config. TitleFontFace    = ''        // If '' use FontFace (boldified)
100
config. TitleFontSize    = ''        // If '' use FontSize
101
config. TitlePadding     = 2
102
config. Width            = 0            // Tooltip width; 0 for automatic adaption to tooltip content; < -1 (e.g. -240) for a maximum width for that automatic adaption;
103
                                    // -1: tooltip width confined to the width required for the titlebar
104
//=======  END OF TOOLTIP CONFIG, DO NOT CHANGE ANYTHING BELOW  ==============//
105

    
106
//=====================  PUBLIC  =============================================//
107
function Tip()
108
{
109
    tt_Tip(arguments, null);
110
}
111
function TagToTip()
112
{
113
    var t2t = tt_GetElt(arguments[0]);
114
    if(t2t)
115
        tt_Tip(arguments, t2t);
116
}
117
function UnTip()
118
{
119
    tt_OpReHref();
120
    if(tt_aV[DURATION] < 0 && (tt_iState & 0x2))
121
        tt_tDurt.Timer("tt_HideInit()", -tt_aV[DURATION], true);
122
    else if(!(tt_aV[STICKY] && (tt_iState & 0x2)))
123
        tt_HideInit();
124
}
125

    
126
//==================  PUBLIC PLUGIN API     =====================================//
127
// Extension eventhandlers currently supported:
128
// OnLoadConfig, OnCreateContentString, OnSubDivsCreated, OnShow, OnMoveBefore,
129
// OnMoveAfter, OnHideInit, OnHide, OnKill
130

    
131
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
132
tt_aV = new Array(),    // Caches and enumerates config data for currently active tooltip
133
tt_sContent,            // Inner tooltip text or HTML
134
tt_t2t, tt_t2tDad,        // Tag converted to tip, and its DOM parent element
135
tt_musX, tt_musY,
136
tt_over,
137
tt_x, tt_y, tt_w, tt_h; // Position, width and height of currently displayed tooltip
138

    
139
function tt_Extension()
140
{
141
    tt_ExtCmdEnum();
142
    tt_aExt[tt_aExt.length] = this;
143
    return this;
144
}
145
function tt_SetTipPos(x, y)
146
{
147
    var css = tt_aElt[0].style;
148

    
149
    tt_x = x;
150
    tt_y = y;
151
    css.left = x + "px";
152
    css.top = y + "px";
153
    if(tt_ie56)
154
    {
155
        var ifrm = tt_aElt[tt_aElt.length - 1];
156
        if(ifrm)
157
        {
158
            ifrm.style.left = css.left;
159
            ifrm.style.top = css.top;
160
        }
161
    }
162
}
163
function tt_HideInit()
164
{
165
    if(tt_iState)
166
    {
167
        tt_ExtCallFncs(0, "HideInit");
168
        tt_iState &= ~(0x4 | 0x8);
169
        if(tt_flagOpa && tt_aV[FADEOUT])
170
        {
171
            tt_tFade.EndTimer();
172
            if(tt_opa)
173
            {
174
                var n = Math.round(tt_aV[FADEOUT] / (tt_aV[FADEINTERVAL] * (tt_aV[OPACITY] / tt_opa)));
175
                tt_Fade(tt_opa, tt_opa, 0, n);
176
                return;
177
            }
178
        }
179
        tt_tHide.Timer("tt_Hide();", 1, false);
180
    }
181
}
182
function tt_Hide()
183
{
184
    if(tt_db && tt_iState)
185
    {
186
        tt_OpReHref();
187
        if(tt_iState & 0x2)
188
        {
189
            tt_aElt[0].style.visibility = "hidden";
190
            tt_ExtCallFncs(0, "Hide");
191
        }
192
        tt_tShow.EndTimer();
193
        tt_tHide.EndTimer();
194
        tt_tDurt.EndTimer();
195
        tt_tFade.EndTimer();
196
        if(!tt_op && !tt_ie)
197
        {
198
            tt_tWaitMov.EndTimer();
199
            tt_bWait = false;
200
        }
201
        if(tt_aV[CLICKCLOSE] || tt_aV[CLICKSTICKY])
202
            tt_RemEvtFnc(document, "mouseup", tt_OnLClick);
203
        tt_ExtCallFncs(0, "Kill");
204
        // In case of a TagToTip tip, hide converted DOM node and
205
        // re-insert it into DOM
206
        if(tt_t2t && !tt_aV[COPYCONTENT])
207
            tt_UnEl2Tip();
208
        tt_iState = 0;
209
        tt_over = null;
210
        tt_ResetMainDiv();
211
        if(tt_aElt[tt_aElt.length - 1])
212
            tt_aElt[tt_aElt.length - 1].style.display = "none";
213
    }
214
}
215
function tt_GetElt(id)
216
{
217
    return(document.getElementById ? document.getElementById(id)
218
            : document.all ? document.all[id]
219
            : null);
220
}
221
function tt_GetDivW(el)
222
{
223
    return(el ? (el.offsetWidth || el.style.pixelWidth || 0) : 0);
224
}
225
function tt_GetDivH(el)
226
{
227
    return(el ? (el.offsetHeight || el.style.pixelHeight || 0) : 0);
228
}
229
function tt_GetScrollX()
230
{
231
    return(window.pageXOffset || (tt_db ? (tt_db.scrollLeft || 0) : 0));
232
}
233
function tt_GetScrollY()
234
{
235
    return(window.pageYOffset || (tt_db ? (tt_db.scrollTop || 0) : 0));
236
}
237
function tt_GetClientW()
238
{
239
    return tt_GetWndCliSiz("Width");
240
}
241
function tt_GetClientH()
242
{
243
    return tt_GetWndCliSiz("Height");
244
}
245
function tt_GetEvtX(e)
246
{
247
    return (e ? ((typeof(e.pageX) != tt_u) ? e.pageX : (e.clientX + tt_GetScrollX())) : 0);
248
}
249
function tt_GetEvtY(e)
250
{
251
    return (e ? ((typeof(e.pageY) != tt_u) ? e.pageY : (e.clientY + tt_GetScrollY())) : 0);
252
}
253
function tt_AddEvtFnc(el, sEvt, PFnc)
254
{
255
    if(el)
256
    {
257
        if(el.addEventListener)
258
            el.addEventListener(sEvt, PFnc, false);
259
        else
260
            el.attachEvent("on" + sEvt, PFnc);
261
    }
262
}
263
function tt_RemEvtFnc(el, sEvt, PFnc)
264
{
265
    if(el)
266
    {
267
        if(el.removeEventListener)
268
            el.removeEventListener(sEvt, PFnc, false);
269
        else
270
            el.detachEvent("on" + sEvt, PFnc);
271
    }
272
}
273
function tt_GetDad(el)
274
{
275
    return(el.parentNode || el.parentElement || el.offsetParent);
276
}
277
function tt_MovDomNode(el, dadFrom, dadTo)
278
{
279
    if(dadFrom)
280
        dadFrom.removeChild(el);
281
    if(dadTo)
282
        dadTo.appendChild(el);
283
}
284

    
285
//======================  PRIVATE  ===========================================//
286
var tt_aExt = new Array(),    // Array of extension objects
287

    
288
tt_db, tt_op, tt_ie, tt_ie56, tt_bBoxOld,    // Browser flags
289
tt_body,
290
tt_ovr_,                // HTML element the mouse is currently over
291
tt_flagOpa,                // Opacity support: 1=IE, 2=Khtml, 3=KHTML, 4=Moz, 5=W3C
292
tt_maxPosX, tt_maxPosY,
293
tt_iState = 0,            // Tooltip active |= 1, shown |= 2, move with mouse |= 4, exclusive |= 8
294
tt_opa,                    // Currently applied opacity
295
tt_bJmpVert, tt_bJmpHorz,// Tip temporarily on other side of mouse
296
tt_elDeHref,            // The tag from which we've removed the href attribute
297
// Timer
298
tt_tShow = new Number(0), tt_tHide = new Number(0), tt_tDurt = new Number(0),
299
tt_tFade = new Number(0), tt_tWaitMov = new Number(0),
300
tt_bWait = false,
301
tt_u = "undefined";
302

    
303

    
304
function tt_Init()
305
{
306
    tt_MkCmdEnum();
307
    // Send old browsers instantly to hell
308
    if(!tt_Browser() || !tt_MkMainDiv())
309
        return;
310
    tt_IsW3cBox();
311
    tt_OpaSupport();
312
    tt_AddEvtFnc(document, "mousemove", tt_Move);
313
    // In Debug mode we search for TagToTip() calls in order to notify
314
    // the user if they've forgotten to set the TagsToTip config flag
315
    if(TagsToTip || tt_Debug)
316
        tt_SetOnloadFnc();
317
    // Ensure the tip be hidden when the page unloads
318
    tt_AddEvtFnc(window, "unload", tt_Hide);
319
}
320
// Creates command names by translating config variable names to upper case
321
function tt_MkCmdEnum()
322
{
323
    var n = 0;
324
    for(var i in config)
325
        eval("window." + i.toString().toUpperCase() + " = " + n++);
326
    tt_aV.length = n;
327
}
328
function tt_Browser()
329
{
330
    var n, nv, n6, w3c;
331

    
332
    n = navigator.userAgent.toLowerCase(),
333
    nv = navigator.appVersion;
334
    tt_op = (document.defaultView && typeof(eval("w" + "indow" + "." + "o" + "p" + "er" + "a")) != tt_u);
335
    tt_ie = n.indexOf("msie") != -1 && document.all && !tt_op;
336
    if(tt_ie)
337
    {
338
        var ieOld = (!document.compatMode || document.compatMode == "BackCompat");
339
        tt_db = !ieOld ? document.documentElement : (document.body || null);
340
        if(tt_db)
341
            tt_ie56 = parseFloat(nv.substring(nv.indexOf("MSIE") + 5)) >= 5.5
342
                    && typeof document.body.style.maxHeight == tt_u;
343
    }
344
    else
345
    {
346
        tt_db = document.documentElement || document.body ||
347
                (document.getElementsByTagName ? document.getElementsByTagName("body")[0]
348
                : null);
349
        if(!tt_op)
350
        {
351
            n6 = document.defaultView && typeof document.defaultView.getComputedStyle != tt_u;
352
            w3c = !n6 && document.getElementById;
353
        }
354
    }
355
    tt_body = (document.getElementsByTagName ? document.getElementsByTagName("body")[0]
356
                : (document.body || null));
357
    if(tt_ie || n6 || tt_op || w3c)
358
    {
359
        if(tt_body && tt_db)
360
        {
361
            if(document.attachEvent || document.addEventListener)
362
                return true;
363
        }
364
        else
365
            tt_Err("wz_tooltip.js must be included INSIDE the body section,"
366
                    + " immediately after the opening <body> tag.", false);
367
    }
368
    tt_db = null;
369
    return false;
370
}
371
function tt_MkMainDiv()
372
{
373
    // Create the tooltip DIV
374
    if(tt_body.insertAdjacentHTML)
375
        tt_body.insertAdjacentHTML("afterBegin", tt_MkMainDivHtm());
376
    else if(typeof tt_body.innerHTML != tt_u && document.createElement && tt_body.appendChild)
377
        tt_body.appendChild(tt_MkMainDivDom());
378
    if(window.tt_GetMainDivRefs /* FireFox Alzheimer */ && tt_GetMainDivRefs())
379
        return true;
380
    tt_db = null;
381
    return false;
382
}
383
function tt_MkMainDivHtm()
384
{
385
    return(
386
        '<div id="WzTtDiV"></div>' +
387
        (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>')
388
        : '')
389
    );
390
}
391
function tt_MkMainDivDom()
392
{
393
    var el = document.createElement("div");
394
    if(el)
395
        el.id = "WzTtDiV";
396
    return el;
397
}
398
function tt_GetMainDivRefs()
399
{
400
    tt_aElt[0] = tt_GetElt("WzTtDiV");
401
    if(tt_ie56 && tt_aElt[0])
402
    {
403
        tt_aElt[tt_aElt.length - 1] = tt_GetElt("WzTtIfRm");
404
        if(!tt_aElt[tt_aElt.length - 1])
405
            tt_aElt[0] = null;
406
    }
407
    if(tt_aElt[0])
408
    {
409
        var css = tt_aElt[0].style;
410

    
411
        css.visibility = "hidden";
412
        css.position = "absolute";
413
        css.overflow = "hidden";
414
        return true;
415
    }
416
    return false;
417
}
418
function tt_ResetMainDiv()
419
{
420
    tt_SetTipPos(0, 0);
421
    tt_aElt[0].innerHTML = "";
422
    tt_aElt[0].style.width = "0px";
423
    tt_h = 0;
424
}
425
function tt_IsW3cBox()
426
{
427
    var css = tt_aElt[0].style;
428

    
429
    css.padding = "10px";
430
    css.width = "40px";
431
    tt_bBoxOld = (tt_GetDivW(tt_aElt[0]) == 40);
432
    css.padding = "0px";
433
    tt_ResetMainDiv();
434
}
435
function tt_OpaSupport()
436
{
437
    var css = tt_body.style;
438

    
439
    tt_flagOpa = (typeof(css.KhtmlOpacity) != tt_u) ? 2
440
                : (typeof(css.KHTMLOpacity) != tt_u) ? 3
441
                : (typeof(css.MozOpacity) != tt_u) ? 4
442
                : (typeof(css.opacity) != tt_u) ? 5
443
                : (typeof(css.filter) != tt_u) ? 1
444
                : 0;
445
}
446
// Ported from http://dean.edwards.name/weblog/2006/06/again/
447
// (Dean Edwards et al.)
448
function tt_SetOnloadFnc()
449
{
450
    tt_AddEvtFnc(document, "DOMContentLoaded", tt_HideSrcTags);
451
    tt_AddEvtFnc(window, "load", tt_HideSrcTags);
452
    if(tt_body.attachEvent)
453
        tt_body.attachEvent("onreadystatechange",
454
            function() {
455
                if(tt_body.readyState == "complete")
456
                    tt_HideSrcTags();
457
            } );
458
    if(/WebKit|KHTML/i.test(navigator.userAgent))
459
    {
460
        var t = setInterval(function() {
461
                    if(/loaded|complete/.test(document.readyState))
462
                    {
463
                        clearInterval(t);
464
                        tt_HideSrcTags();
465
                    }
466
                }, 10);
467
    }
468
}
469
function tt_HideSrcTags()
470
{
471
    if(!window.tt_HideSrcTags || window.tt_HideSrcTags.done)
472
        return;
473
    window.tt_HideSrcTags.done = true;
474
    if(!tt_HideSrcTagsRecurs(tt_body))
475
        tt_Err("There are HTML elements to be converted to tooltips.\nIf you"
476
                + " want these HTML elements to be automatically hidden, you"
477
                + " must edit wz_tooltip.js, and set TagsToTip in the global"
478
                + " tooltip configuration to true.", true);
479
}
480
function tt_HideSrcTagsRecurs(dad)
481
{
482
    var ovr, asT2t;
483
    // Walk the DOM tree for tags that have an onmouseover or onclick attribute
484
    // containing a TagToTip('...') call.
485
    // (.childNodes first since .children is bugous in Safari)
486
    var a = dad.childNodes || dad.children || null;
487

    
488
    for(var i = a ? a.length : 0; i;)
489
    {--i;
490
        if(!tt_HideSrcTagsRecurs(a[i]))
491
            return false;
492
        ovr = a[i].getAttribute ? (a[i].getAttribute("onmouseover") || a[i].getAttribute("onclick"))
493
                : (typeof a[i].onmouseover == "function") ? (a[i].onmouseover || a[i].onclick)
494
                : null;
495
        if(ovr)
496
        {
497
            asT2t = ovr.toString().match(/TagToTip\s*\(\s*'[^'.]+'\s*[\),]/);
498
            if(asT2t && asT2t.length)
499
            {
500
                if(!tt_HideSrcTag(asT2t[0]))
501
                    return false;
502
            }
503
        }
504
    }
505
    return true;
506
}
507
function tt_HideSrcTag(sT2t)
508
{
509
    var id, el;
510

    
511
    // The ID passed to the found TagToTip() call identifies an HTML element
512
    // to be converted to a tooltip, so hide that element
513
    id = sT2t.replace(/.+'([^'.]+)'.+/, "$1");
514
    el = tt_GetElt(id);
515
    if(el)
516
    {
517
        if(tt_Debug && !TagsToTip)
518
            return false;
519
        else
520
            el.style.display = "none";
521
    }
522
    else
523
        tt_Err("Invalid ID\n'" + id + "'\npassed to TagToTip()."
524
                + " There exists no HTML element with that ID.", true);
525
    return true;
526
}
527
function tt_Tip(arg, t2t)
528
{
529
    if(!tt_db || (tt_iState & 0x8))
530
        return;
531
    if(tt_iState)
532
        tt_Hide();
533
    if(!tt_Enabled)
534
        return;
535
    tt_t2t = t2t;
536
    if(!tt_ReadCmds(arg))
537
        return;
538
    tt_iState = 0x1 | 0x4;
539
    tt_AdaptConfig1();
540
    tt_MkTipContent(arg);
541
    tt_MkTipSubDivs();
542
    tt_FormatTip();
543
    tt_bJmpVert = false;
544
    tt_bJmpHorz = false;
545
    tt_maxPosX = tt_GetClientW() + tt_GetScrollX() - tt_w - 1;
546
    tt_maxPosY = tt_GetClientH() + tt_GetScrollY() - tt_h - 1;
547
    tt_AdaptConfig2();
548
    // Ensure the tip be shown and positioned before the first onmousemove
549
    tt_OverInit();
550
    tt_ShowInit();
551
    tt_Move();
552
}
553
function tt_ReadCmds(a)
554
{
555
    var i;
556

    
557
    // First load the global config values, to initialize also values
558
    // for which no command is passed
559
    i = 0;
560
    for(var j in config)
561
        tt_aV[i++] = config[j];
562
    // Then replace each cached config value for which a command is
563
    // passed (ensure the # of command args plus value args be even)
564
    if(a.length & 1)
565
    {
566
        for(i = a.length - 1; i > 0; i -= 2)
567
            tt_aV[a[i - 1]] = a[i];
568
        return true;
569
    }
570
    tt_Err("Incorrect call of Tip() or TagToTip().\n"
571
            + "Each command must be followed by a value.", true);
572
    return false;
573
}
574
function tt_AdaptConfig1()
575
{
576
    tt_ExtCallFncs(0, "LoadConfig");
577
    // Inherit unspecified title formattings from body
578
    if(!tt_aV[TITLEBGCOLOR].length)
579
        tt_aV[TITLEBGCOLOR] = tt_aV[BORDERCOLOR];
580
    if(!tt_aV[TITLEFONTCOLOR].length)
581
        tt_aV[TITLEFONTCOLOR] = tt_aV[BGCOLOR];
582
    if(!tt_aV[TITLEFONTFACE].length)
583
        tt_aV[TITLEFONTFACE] = tt_aV[FONTFACE];
584
    if(!tt_aV[TITLEFONTSIZE].length)
585
        tt_aV[TITLEFONTSIZE] = tt_aV[FONTSIZE];
586
    if(tt_aV[CLOSEBTN])
587
    {
588
        // Use title colours for non-specified closebutton colours
589
        if(!tt_aV[CLOSEBTNCOLORS])
590
            tt_aV[CLOSEBTNCOLORS] = new Array("", "", "", "");
591
        for(var i = 4; i;)
592
        {--i;
593
            if(!tt_aV[CLOSEBTNCOLORS][i].length)
594
                tt_aV[CLOSEBTNCOLORS][i] = (i & 1) ? tt_aV[TITLEFONTCOLOR] : tt_aV[TITLEBGCOLOR];
595
        }
596
        // Enforce titlebar be shown
597
        if(!tt_aV[TITLE].length)
598
            tt_aV[TITLE] = " ";
599
    }
600
    // Circumvents broken display of images and fade-in flicker in Geckos < 1.8
601
    if(tt_aV[OPACITY] == 100 && typeof tt_aElt[0].style.MozOpacity != tt_u && !Array.every)
602
        tt_aV[OPACITY] = 99;
603
    // Smartly shorten the delay for fade-in tooltips
604
    if(tt_aV[FADEIN] && tt_flagOpa && tt_aV[DELAY] > 100)
605
        tt_aV[DELAY] = Math.max(tt_aV[DELAY] - tt_aV[FADEIN], 100);
606
}
607
function tt_AdaptConfig2()
608
{
609
    if(tt_aV[CENTERMOUSE])
610
    {
611
        tt_aV[OFFSETX] -= ((tt_w - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0)) >> 1);
612
        tt_aV[JUMPHORZ] = false;
613
    }
614
}
615
// Expose content globally so extensions can modify it
616
function tt_MkTipContent(a)
617
{
618
    if(tt_t2t)
619
    {
620
        if(tt_aV[COPYCONTENT])
621
            tt_sContent = tt_t2t.innerHTML;
622
        else
623
            tt_sContent = "";
624
    }
625
    else
626
        tt_sContent = a[0];
627
    tt_ExtCallFncs(0, "CreateContentString");
628
}
629
function tt_MkTipSubDivs()
630
{
631
    var sCss = 'position:relative;margin:0px;padding:0px;border-width:0px;left:0px;top:0px;line-height:normal;width:auto;',
632
    sTbTrTd = ' cellspacing="0" cellpadding="0" border="0" style="' + sCss + '"><tbody style="' + sCss + '"><tr><td ';
633

    
634
    tt_aElt[0].style.width = tt_GetClientW() + "px";
635
    tt_aElt[0].innerHTML =
636
        (''
637
        + (tt_aV[TITLE].length ?
638
            ('<div id="WzTiTl" style="position:relative;z-index:1;">'
639
            + '<table id="WzTiTlTb"' + sTbTrTd + 'id="WzTiTlI" style="' + sCss + '">'
640
            + tt_aV[TITLE]
641
            + '</td>'
642
            + (tt_aV[CLOSEBTN] ?
643
                ('<td align="right" style="' + sCss
644
                + 'text-align:right;">'
645
                + '<span id="WzClOsE" style="position:relative;left:2px;padding-left:2px;padding-right:2px;'
646
                + 'cursor:' + (tt_ie ? 'hand' : 'pointer')
647
                + ';" onmouseover="tt_OnCloseBtnOver(1)" onmouseout="tt_OnCloseBtnOver(0)" onclick="tt_HideInit()">'
648
                + tt_aV[CLOSEBTNTEXT]
649
                + '</span></td>')
650
                : '')
651
            + '</tr></tbody></table></div>')
652
            : '')
653
        + '<div id="WzBoDy" style="position:relative;z-index:0;">'
654
        + '<table' + sTbTrTd + 'id="WzBoDyI" style="' + sCss + '">'
655
        + tt_sContent
656
        + '</td></tr></tbody></table></div>'
657
        + (tt_aV[SHADOW]
658
            ? ('<div id="WzTtShDwR" style="position:absolute;overflow:hidden;"></div>'
659
                + '<div id="WzTtShDwB" style="position:relative;overflow:hidden;"></div>')
660
            : '')
661
        );
662
    tt_GetSubDivRefs();
663
    // Convert DOM node to tip
664
    if(tt_t2t && !tt_aV[COPYCONTENT])
665
        tt_El2Tip();
666
    tt_ExtCallFncs(0, "SubDivsCreated");
667
}
668
function tt_GetSubDivRefs()
669
{
670
    var aId = new Array("WzTiTl", "WzTiTlTb", "WzTiTlI", "WzClOsE", "WzBoDy", "WzBoDyI", "WzTtShDwB", "WzTtShDwR");
671

    
672
    for(var i = aId.length; i; --i)
673
        tt_aElt[i] = tt_GetElt(aId[i - 1]);
674
}
675
function tt_FormatTip()
676
{
677
    var css, w, h, pad = tt_aV[PADDING], padT, wBrd = tt_aV[BORDERWIDTH],
678
    iOffY, iOffSh, iAdd = (pad + wBrd) << 1;
679

    
680
    //--------- Title DIV ----------
681
    if(tt_aV[TITLE].length)
682
    {
683
        padT = tt_aV[TITLEPADDING];
684
        css = tt_aElt[1].style;
685
        css.background = tt_aV[TITLEBGCOLOR];
686
        css.paddingTop = css.paddingBottom = padT + "px";
687
        css.paddingLeft = css.paddingRight = (padT + 2) + "px";
688
        css = tt_aElt[3].style;
689
        css.color = tt_aV[TITLEFONTCOLOR];
690
        if(tt_aV[WIDTH] == -1)
691
            css.whiteSpace = "nowrap";
692
        css.fontFamily = tt_aV[TITLEFONTFACE];
693
        css.fontSize = tt_aV[TITLEFONTSIZE];
694
        css.fontWeight = "bold";
695
        css.textAlign = tt_aV[TITLEALIGN];
696
        // Close button DIV
697
        if(tt_aElt[4])
698
        {
699
            css = tt_aElt[4].style;
700
            css.background = tt_aV[CLOSEBTNCOLORS][0];
701
            css.color = tt_aV[CLOSEBTNCOLORS][1];
702
            css.fontFamily = tt_aV[TITLEFONTFACE];
703
            css.fontSize = tt_aV[TITLEFONTSIZE];
704
            css.fontWeight = "bold";
705
        }
706
        if(tt_aV[WIDTH] > 0)
707
            tt_w = tt_aV[WIDTH];
708
        else
709
        {
710
            tt_w = tt_GetDivW(tt_aElt[3]) + tt_GetDivW(tt_aElt[4]);
711
            // Some spacing between title DIV and closebutton
712
            if(tt_aElt[4])
713
                tt_w += pad;
714
            // Restrict auto width to max width
715
            if(tt_aV[WIDTH] < -1 && tt_w > -tt_aV[WIDTH])
716
                tt_w = -tt_aV[WIDTH];
717
        }
718
        // Ensure the top border of the body DIV be covered by the title DIV
719
        iOffY = -wBrd;
720
    }
721
    else
722
    {
723
        tt_w = 0;
724
        iOffY = 0;
725
    }
726

    
727
    //-------- Body DIV ------------
728
    css = tt_aElt[5].style;
729
    css.top = iOffY + "px";
730
    if(wBrd)
731
    {
732
        css.borderColor = tt_aV[BORDERCOLOR];
733
        css.borderStyle = tt_aV[BORDERSTYLE];
734
        css.borderWidth = wBrd + "px";
735
    }
736
    if(tt_aV[BGCOLOR].length)
737
        css.background = tt_aV[BGCOLOR];
738
    if(tt_aV[BGIMG].length)
739
        css.backgroundImage = "url(" + tt_aV[BGIMG] + ")";
740
    css.padding = pad + "px";
741
    css.textAlign = tt_aV[TEXTALIGN];
742
    if(tt_aV[HEIGHT])
743
    {
744
        css.overflow = "auto";
745
        if(tt_aV[HEIGHT] > 0)
746
            css.height = (tt_aV[HEIGHT] + iAdd) + "px";
747
        else
748
            tt_h = iAdd - tt_aV[HEIGHT];
749
    }
750
    // TD inside body DIV
751
    css = tt_aElt[6].style;
752
    css.color = tt_aV[FONTCOLOR];
753
    css.fontFamily = tt_aV[FONTFACE];
754
    css.fontSize = tt_aV[FONTSIZE];
755
    css.fontWeight = tt_aV[FONTWEIGHT];
756
    css.textAlign = tt_aV[TEXTALIGN];
757
    if(tt_aV[WIDTH] > 0)
758
        w = tt_aV[WIDTH];
759
    // Width like title (if existent)
760
    else if(tt_aV[WIDTH] == -1 && tt_w)
761
        w = tt_w;
762
    else
763
    {
764
        // Measure width of the body's inner TD, as some browsers would expand
765
        // the container and outer body DIV to 100%
766
        w = tt_GetDivW(tt_aElt[6]);
767
        // Restrict auto width to max width
768
        if(tt_aV[WIDTH] < -1 && w > -tt_aV[WIDTH])
769
            w = -tt_aV[WIDTH];
770
    }
771
    if(w > tt_w)
772
        tt_w = w;
773
    tt_w += iAdd;
774

    
775
    //--------- Shadow DIVs ------------
776
    if(tt_aV[SHADOW])
777
    {
778
        tt_w += tt_aV[SHADOWWIDTH];
779
        iOffSh = Math.floor((tt_aV[SHADOWWIDTH] * 4) / 3);
780
        // Bottom shadow
781
        css = tt_aElt[7].style;
782
        css.top = iOffY + "px";
783
        css.left = iOffSh + "px";
784
        css.width = (tt_w - iOffSh - tt_aV[SHADOWWIDTH]) + "px";
785
        css.height = tt_aV[SHADOWWIDTH] + "px";
786
        css.background = tt_aV[SHADOWCOLOR];
787
        // Right shadow
788
        css = tt_aElt[8].style;
789
        css.top = iOffSh + "px";
790
        css.left = (tt_w - tt_aV[SHADOWWIDTH]) + "px";
791
        css.width = tt_aV[SHADOWWIDTH] + "px";
792
        css.background = tt_aV[SHADOWCOLOR];
793
    }
794
    else
795
        iOffSh = 0;
796

    
797
    //-------- Container DIV -------
798
    tt_SetTipOpa(tt_aV[FADEIN] ? 0 : tt_aV[OPACITY]);
799
    tt_FixSize(iOffY, iOffSh);
800
}
801
// Fixate the size so it can't dynamically change while the tooltip is moving.
802
function tt_FixSize(iOffY, iOffSh)
803
{
804
    var wIn, wOut, h, add, pad = tt_aV[PADDING], wBrd = tt_aV[BORDERWIDTH], i;
805

    
806
    tt_aElt[0].style.width = tt_w + "px";
807
    tt_aElt[0].style.pixelWidth = tt_w;
808
    wOut = tt_w - ((tt_aV[SHADOW]) ? tt_aV[SHADOWWIDTH] : 0);
809
    // Body
810
    wIn = wOut;
811
    if(!tt_bBoxOld)
812
        wIn -= (pad + wBrd) << 1;
813
    tt_aElt[5].style.width = wIn + "px";
814
    // Title
815
    if(tt_aElt[1])
816
    {
817
        wIn = wOut - ((tt_aV[TITLEPADDING] + 2) << 1);
818
        if(!tt_bBoxOld)
819
            wOut = wIn;
820
        tt_aElt[1].style.width = wOut + "px";
821
        tt_aElt[2].style.width = wIn + "px";
822
    }
823
    // Max height specified
824
    if(tt_h)
825
    {
826
        h = tt_GetDivH(tt_aElt[5]);
827
        if(h > tt_h)
828
        {
829
            if(!tt_bBoxOld)
830
                tt_h -= (pad + wBrd) << 1;
831
            tt_aElt[5].style.height = tt_h + "px";
832
        }
833
    }
834
    tt_h = tt_GetDivH(tt_aElt[0]) + iOffY;
835
    // Right shadow
836
    if(tt_aElt[8])
837
        tt_aElt[8].style.height = (tt_h - iOffSh) + "px";
838
    i = tt_aElt.length - 1;
839
    if(tt_aElt[i])
840
    {
841
        tt_aElt[i].style.width = tt_w + "px";
842
        tt_aElt[i].style.height = tt_h + "px";
843
    }
844
}
845
function tt_DeAlt(el)
846
{
847
    var aKid;
848

    
849
    if(el)
850
    {
851
        if(el.alt)
852
            el.alt = "";
853
        if(el.title)
854
            el.title = "";
855
        aKid = el.childNodes || el.children || null;
856
        if(aKid)
857
        {
858
            for(var i = aKid.length; i;)
859
                tt_DeAlt(aKid[--i]);
860
        }
861
    }
862
}
863
// This hack removes the native tooltips over links in Opera
864
function tt_OpDeHref(el)
865
{
866
    if(!tt_op)
867
        return;
868
    if(tt_elDeHref)
869
        tt_OpReHref();
870
    while(el)
871
    {
872
        if(el.hasAttribute && el.hasAttribute("href"))
873
        {
874
            el.t_href = el.getAttribute("href");
875
            el.t_stats = window.status;
876
            el.removeAttribute("href");
877
            el.style.cursor = "hand";
878
            tt_AddEvtFnc(el, "mousedown", tt_OpReHref);
879
            window.status = el.t_href;
880
            tt_elDeHref = el;
881
            break;
882
        }
883
        el = tt_GetDad(el);
884
    }
885
}
886
function tt_OpReHref()
887
{
888
    if(tt_elDeHref)
889
    {
890
        tt_elDeHref.setAttribute("href", tt_elDeHref.t_href);
891
        tt_RemEvtFnc(tt_elDeHref, "mousedown", tt_OpReHref);
892
        window.status = tt_elDeHref.t_stats;
893
        tt_elDeHref = null;
894
    }
895
}
896
function tt_El2Tip()
897
{
898
    var css = tt_t2t.style;
899

    
900
    // Store previous positioning
901
    tt_t2t.t_cp = css.position;
902
    tt_t2t.t_cl = css.left;
903
    tt_t2t.t_ct = css.top;
904
    tt_t2t.t_cd = css.display;
905
    // Store the tag's parent element so we can restore that DOM branch
906
    // when the tooltip is being hidden
907
    tt_t2tDad = tt_GetDad(tt_t2t);
908
    tt_MovDomNode(tt_t2t, tt_t2tDad, tt_aElt[6]);
909
    css.display = "block";
910
    css.position = "static";
911
    css.left = css.top = css.marginLeft = css.marginTop = "0px";
912
}
913
function tt_UnEl2Tip()
914
{
915
    // Restore positioning and display
916
    var css = tt_t2t.style;
917

    
918
    css.display = tt_t2t.t_cd;
919
    tt_MovDomNode(tt_t2t, tt_GetDad(tt_t2t), tt_t2tDad);
920
    css.position = tt_t2t.t_cp;
921
    css.left = tt_t2t.t_cl;
922
    css.top = tt_t2t.t_ct;
923
    tt_t2tDad = null;
924
}
925
function tt_OverInit()
926
{
927
    if(window.event)
928
        tt_over = window.event.target || window.event.srcElement;
929
    else
930
        tt_over = tt_ovr_;
931
    tt_DeAlt(tt_over);
932
    tt_OpDeHref(tt_over);
933
}
934
function tt_ShowInit()
935
{
936
    tt_tShow.Timer("tt_Show()", tt_aV[DELAY], true);
937
    if(tt_aV[CLICKCLOSE] || tt_aV[CLICKSTICKY])
938
        tt_AddEvtFnc(document, "mouseup", tt_OnLClick);
939
}
940
function tt_Show()
941
{
942
    var css = tt_aElt[0].style;
943

    
944
    // Override the z-index of the topmost wz_dragdrop.js D&D item
945
    css.zIndex = Math.max((window.dd && dd.z) ? (dd.z + 2) : 0, 1010);
946
    if(tt_aV[STICKY] || !tt_aV[FOLLOWMOUSE])
947
        tt_iState &= ~0x4;
948
    if(tt_aV[EXCLUSIVE])
949
        tt_iState |= 0x8;
950
    if(tt_aV[DURATION] > 0)
951
        tt_tDurt.Timer("tt_HideInit()", tt_aV[DURATION], true);
952
    tt_ExtCallFncs(0, "Show")
953
    css.visibility = "visible";
954
    tt_iState |= 0x2;
955
    if(tt_aV[FADEIN])
956
        tt_Fade(0, 0, tt_aV[OPACITY], Math.round(tt_aV[FADEIN] / tt_aV[FADEINTERVAL]));
957
    tt_ShowIfrm();
958
}
959
function tt_ShowIfrm()
960
{
961
    if(tt_ie56)
962
    {
963
        var ifrm = tt_aElt[tt_aElt.length - 1];
964
        if(ifrm)
965
        {
966
            var css = ifrm.style;
967
            css.zIndex = tt_aElt[0].style.zIndex - 1;
968
            css.display = "block";
969
        }
970
    }
971
}
972
function tt_Move(e)
973
{
974
    if(e)
975
        tt_ovr_ = e.target || e.srcElement;
976
    e = e || window.event;
977
    if(e)
978
    {
979
        tt_musX = tt_GetEvtX(e);
980
        tt_musY = tt_GetEvtY(e);
981
    }
982
    if(tt_iState & 0x4)
983
    {
984
        // Prevent jam of mousemove events
985
        if(!tt_op && !tt_ie)
986
        {
987
            if(tt_bWait)
988
                return;
989
            tt_bWait = true;
990
            tt_tWaitMov.Timer("tt_bWait = false;", 1, true);
991
        }
992
        if(tt_aV[FIX])
993
        {
994
            tt_iState &= ~0x4;
995
            tt_PosFix();
996
        }
997
        else if(!tt_ExtCallFncs(e, "MoveBefore"))
998
            tt_SetTipPos(tt_Pos(0), tt_Pos(1));
999
        tt_ExtCallFncs([tt_musX, tt_musY], "MoveAfter")
1000
    }
1001
}
1002
function tt_Pos(iDim)
1003
{
1004
    var iX, bJmpMod, cmdAlt, cmdOff, cx, iMax, iScrl, iMus, bJmp;
1005

    
1006
    // Map values according to dimension to calculate
1007
    if(iDim)
1008
    {
1009
        bJmpMod = tt_aV[JUMPVERT];
1010
        cmdAlt = ABOVE;
1011
        cmdOff = OFFSETY;
1012
        cx = tt_h;
1013
        iMax = tt_maxPosY;
1014
        iScrl = tt_GetScrollY();
1015
        iMus = tt_musY;
1016
        bJmp = tt_bJmpVert;
1017
    }
1018
    else
1019
    {
1020
        bJmpMod = tt_aV[JUMPHORZ];
1021
        cmdAlt = LEFT;
1022
        cmdOff = OFFSETX;
1023
        cx = tt_w;
1024
        iMax = tt_maxPosX;
1025
        iScrl = tt_GetScrollX();
1026
        iMus = tt_musX;
1027
        bJmp = tt_bJmpHorz;
1028
    }
1029
    if(bJmpMod)
1030
    {
1031
        if(tt_aV[cmdAlt] && (!bJmp || tt_CalcPosAlt(iDim) >= iScrl + 16))
1032
            iX = tt_PosAlt(iDim);
1033
        else if(!tt_aV[cmdAlt] && bJmp && tt_CalcPosDef(iDim) > iMax - 16)
1034
            iX = tt_PosAlt(iDim);
1035
        else
1036
            iX = tt_PosDef(iDim);
1037
    }
1038
    else
1039
    {
1040
        iX = iMus;
1041
        if(tt_aV[cmdAlt])
1042
            iX -= cx + tt_aV[cmdOff] - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0);
1043
        else
1044
            iX += tt_aV[cmdOff];
1045
    }
1046
    // Prevent tip from extending past clientarea boundary
1047
    if(iX > iMax)
1048
        iX = bJmpMod ? tt_PosAlt(iDim) : iMax;
1049
    // In case of insufficient space on both sides, ensure the left/upper part
1050
    // of the tip be visible
1051
    if(iX < iScrl)
1052
        iX = bJmpMod ? tt_PosDef(iDim) : iScrl;
1053
    return iX;
1054
}
1055
function tt_PosDef(iDim)
1056
{
1057
    if(iDim)
1058
        tt_bJmpVert = tt_aV[ABOVE];
1059
    else
1060
        tt_bJmpHorz = tt_aV[LEFT];
1061
    return tt_CalcPosDef(iDim);
1062
}
1063
function tt_PosAlt(iDim)
1064
{
1065
    if(iDim)
1066
        tt_bJmpVert = !tt_aV[ABOVE];
1067
    else
1068
        tt_bJmpHorz = !tt_aV[LEFT];
1069
    return tt_CalcPosAlt(iDim);
1070
}
1071
function tt_CalcPosDef(iDim)
1072
{
1073
    return iDim ? (tt_musY + tt_aV[OFFSETY]) : (tt_musX + tt_aV[OFFSETX]);
1074
}
1075
function tt_CalcPosAlt(iDim)
1076
{
1077
    var cmdOff = iDim ? OFFSETY : OFFSETX;
1078
    var dx = tt_aV[cmdOff] - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0);
1079
    if(tt_aV[cmdOff] > 0 && dx <= 0)
1080
        dx = 1;
1081
    return((iDim ? (tt_musY - tt_h) : (tt_musX - tt_w)) - dx);
1082
}
1083
function tt_PosFix()
1084
{
1085
    var iX, iY;
1086

    
1087
    if(typeof(tt_aV[FIX][0]) == "number")
1088
    {
1089
        iX = tt_aV[FIX][0];
1090
        iY = tt_aV[FIX][1];
1091
    }
1092
    else
1093
    {
1094
        if(typeof(tt_aV[FIX][0]) == "string")
1095
            el = tt_GetElt(tt_aV[FIX][0]);
1096
        // First slot in array is direct reference to HTML element
1097
        else
1098
            el = tt_aV[FIX][0];
1099
        iX = tt_aV[FIX][1];
1100
        iY = tt_aV[FIX][2];
1101
        // By default, vert pos is related to bottom edge of HTML element
1102
        if(!tt_aV[ABOVE] && el)
1103
            iY += tt_GetDivH(el);
1104
        for(; el; el = el.offsetParent)
1105
        {
1106
            iX += el.offsetLeft || 0;
1107
            iY += el.offsetTop || 0;
1108
        }
1109
    }
1110
    // For a fixed tip positioned above the mouse, use the bottom edge as anchor
1111
    // (recommended by Christophe Rebeschini, 31.1.2008)
1112
    if(tt_aV[ABOVE])
1113
        iY -= tt_h;
1114
    tt_SetTipPos(iX, iY);
1115
}
1116
function tt_Fade(a, now, z, n)
1117
{
1118
    if(n)
1119
    {
1120
        now += Math.round((z - now) / n);
1121
        if((z > a) ? (now >= z) : (now <= z))
1122
            now = z;
1123
        else
1124
            tt_tFade.Timer(
1125
                "tt_Fade("
1126
                + a + "," + now + "," + z + "," + (n - 1)
1127
                + ")",
1128
                tt_aV[FADEINTERVAL],
1129
                true
1130
            );
1131
    }
1132
    now ? tt_SetTipOpa(now) : tt_Hide();
1133
}
1134
function tt_SetTipOpa(opa)
1135
{
1136
    // To circumvent the opacity nesting flaws of IE, we set the opacity
1137
    // for each sub-DIV separately, rather than for the container DIV.
1138
    tt_SetOpa(tt_aElt[5], opa);
1139
    if(tt_aElt[1])
1140
        tt_SetOpa(tt_aElt[1], opa);
1141
    if(tt_aV[SHADOW])
1142
    {
1143
        opa = Math.round(opa * 0.8);
1144
        tt_SetOpa(tt_aElt[7], opa);
1145
        tt_SetOpa(tt_aElt[8], opa);
1146
    }
1147
}
1148
function tt_OnCloseBtnOver(iOver)
1149
{
1150
    var css = tt_aElt[4].style;
1151

    
1152
    iOver <<= 1;
1153
    css.background = tt_aV[CLOSEBTNCOLORS][iOver];
1154
    css.color = tt_aV[CLOSEBTNCOLORS][iOver + 1];
1155
}
1156
function tt_OnLClick(e)
1157
{
1158
    //  Ignore right-clicks
1159
    e = e || window.event;
1160
    if(!((e.button && e.button & 2) || (e.which && e.which == 3)))
1161
    {
1162
        if(tt_aV[CLICKSTICKY] && (tt_iState & 0x4))
1163
        {
1164
            tt_aV[STICKY] = true;
1165
            tt_iState &= ~0x4;
1166
        }
1167
        else if(tt_aV[CLICKCLOSE])
1168
            tt_HideInit();
1169
    }
1170
}
1171
function tt_Int(x)
1172
{
1173
    var y;
1174

    
1175
    return(isNaN(y = parseInt(x)) ? 0 : y);
1176
}
1177
Number.prototype.Timer = function(s, iT, bUrge)
1178
{
1179
    if(!this.value || bUrge)
1180
        this.value = window.setTimeout(s, iT);
1181
}
1182
Number.prototype.EndTimer = function()
1183
{
1184
    if(this.value)
1185
    {
1186
        window.clearTimeout(this.value);
1187
        this.value = 0;
1188
    }
1189
}
1190
function tt_GetWndCliSiz(s)
1191
{
1192
    var db, y = window["inner" + s], sC = "client" + s, sN = "number";
1193
    if(typeof y == sN)
1194
    {
1195
        var y2;
1196
        return(
1197
            // Gecko or Opera with scrollbar
1198
            // ... quirks mode
1199
            ((db = document.body) && typeof(y2 = db[sC]) == sN && y2 &&  y2 <= y) ? y2 
1200
            // ... strict mode
1201
            : ((db = document.documentElement) && typeof(y2 = db[sC]) == sN && y2 && y2 <= y) ? y2
1202
            // No scrollbar, or clientarea size == 0, or other browser (KHTML etc.)
1203
            : y
1204
        );
1205
    }
1206
    // IE
1207
    return(
1208
        // document.documentElement.client+s functional, returns > 0
1209
        ((db = document.documentElement) && (y = db[sC])) ? y
1210
        // ... not functional, in which case document.body.client+s 
1211
        // is the clientarea size, fortunately
1212
        : document.body[sC]
1213
    );
1214
}
1215
function tt_SetOpa(el, opa)
1216
{
1217
    var css = el.style;
1218

    
1219
    tt_opa = opa;
1220
    if(tt_flagOpa == 1)
1221
    {
1222
        if(opa < 100)
1223
        {
1224
            // Hacks for bugs of IE:
1225
            // 1.) Once a CSS filter has been applied, fonts are no longer
1226
            // anti-aliased, so we store the previous 'non-filter' to be
1227
            // able to restore it
1228
            if(typeof(el.filtNo) == tt_u)
1229
                el.filtNo = css.filter;
1230
            // 2.) A DIV cannot be made visible in a single step if an
1231
            // opacity < 100 has been applied while the DIV was hidden
1232
            var bVis = css.visibility != "hidden";
1233
            // 3.) In IE6, applying an opacity < 100 has no effect if the
1234
            //       element has no layout (position, size, zoom, ...)
1235
            css.zoom = "100%";
1236
            if(!bVis)
1237
                css.visibility = "visible";
1238
            css.filter = "alpha(opacity=" + opa + ")";
1239
            if(!bVis)
1240
                css.visibility = "hidden";
1241
        }
1242
        else if(typeof(el.filtNo) != tt_u)
1243
            // Restore 'non-filter'
1244
            css.filter = el.filtNo;
1245
    }
1246
    else
1247
    {
1248
        opa /= 100.0;
1249
        switch(tt_flagOpa)
1250
        {
1251
        case 2:
1252
            css.KhtmlOpacity = opa; break;
1253
        case 3:
1254
            css.KHTMLOpacity = opa; break;
1255
        case 4:
1256
            css.MozOpacity = opa; break;
1257
        case 5:
1258
            css.opacity = opa; break;
1259
        }
1260
    }
1261
}
1262
function tt_Err(sErr, bIfDebug)
1263
{
1264
    if(tt_Debug || !bIfDebug)
1265
        alert("Tooltip Script Error Message:\n\n" + sErr);
1266
}
1267

    
1268
//============  EXTENSION (PLUGIN) MANAGER  ===============//
1269
function tt_ExtCmdEnum()
1270
{
1271
    var s;
1272

    
1273
    // Add new command(s) to the commands enum
1274
    for(var i in config)
1275
    {
1276
        s = "window." + i.toString().toUpperCase();
1277
        if(eval("typeof(" + s + ") == tt_u"))
1278
        {
1279
            eval(s + " = " + tt_aV.length);
1280
            tt_aV[tt_aV.length] = null;
1281
        }
1282
    }
1283
}
1284
function tt_ExtCallFncs(arg, sFnc)
1285
{
1286
    var b = false;
1287
    for(var i = tt_aExt.length; i;)
1288
    {--i;
1289
        var fnc = tt_aExt[i]["On" + sFnc];
1290
        // Call the method the extension has defined for this event
1291
        if(fnc && fnc(arg))
1292
            b = true;
1293
    }
1294
    return b;
1295
}
1296

    
1297
tt_Init();
(14-14/14)