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

    
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
51

    
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)"
57

    
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    = '&nbsp;X&nbsp;'    // 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
75
config. FadeOut            = 100
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  ==============//
106

    
107

    
108

    
109

    
110
//=====================  PUBLIC  =============================================//
111
function Tip()
112
{
113
    tt_Tip(arguments, null);
114
}
115
function TagToTip()
116
{
117
    var t2t = tt_GetElt(arguments[0]);
118
    if(t2t)
119
        tt_Tip(arguments, t2t);
120
}
121
function UnTip()
122
{
123
    tt_OpReHref();
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)))
127
        tt_HideInit();
128
}
129

    
130
//==================  PUBLIC PLUGIN API     =====================================//
131
// Extension eventhandlers currently supported:
132
// OnLoadConfig, OnCreateContentString, OnSubDivsCreated, OnShow, OnMoveBefore,
133
// OnMoveAfter, OnHideInit, OnHide, OnKill
134

    
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
139
tt_musX, tt_musY,
140
tt_over,
141
tt_x, tt_y, tt_w, tt_h; // Position, width and height of currently displayed tooltip
142

    
143
function tt_Extension()
144
{
145
    tt_ExtCmdEnum();
146
    tt_aExt[tt_aExt.length] = this;
147
    return this;
148
}
149
function tt_SetTipPos(x, y)
150
{
151
    var css = tt_aElt[0].style;
152

    
153
    tt_x = x;
154
    tt_y = y;
155
    css.left = x + "px";
156
    css.top = y + "px";
157
    if(tt_ie56)
158
    {
159
        var ifrm = tt_aElt[tt_aElt.length - 1];
160
        if(ifrm)
161
        {
162
            ifrm.style.left = css.left;
163
            ifrm.style.top = css.top;
164
        }
165
    }
166
}
167
function tt_HideInit()
168
{
169
    if(tt_iState)
170
    {
171
        tt_ExtCallFncs(0, "HideInit");
172
        tt_iState &= ~(0x4 | 0x8);
173
        if(tt_flagOpa && tt_aV[FADEOUT])
174
        {
175
            tt_tFade.EndTimer();
176
            if(tt_opa)
177
            {
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);
180
                return;
181
            }
182
        }
183
        tt_tHide.Timer("tt_Hide();", 1, false);
184
    }
185
}
186
function tt_Hide()
187
{
188
    if(tt_db && tt_iState)
189
    {
190
        tt_OpReHref();
191
        if(tt_iState & 0x2)
192
        {
193
            tt_aElt[0].style.visibility = "hidden";
194
            tt_ExtCallFncs(0, "Hide");
195
        }
196
        tt_tShow.EndTimer();
197
        tt_tHide.EndTimer();
198
        tt_tDurt.EndTimer();
199
        tt_tFade.EndTimer();
200
        if(!tt_op && !tt_ie)
201
        {
202
            tt_tWaitMov.EndTimer();
203
            tt_bWait = false;
204
        }
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])
211
            tt_UnEl2Tip();
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
}
219
function tt_GetElt(id)
220
{
221
    return(document.getElementById ? document.getElementById(id)
222
            : document.all ? document.all[id]
223
            : null);
224
}
225
function tt_GetDivW(el)
226
{
227
    return(el ? (el.offsetWidth || el.style.pixelWidth || 0) : 0);
228
}
229
function tt_GetDivH(el)
230
{
231
    return(el ? (el.offsetHeight || el.style.pixelHeight || 0) : 0);
232
}
233
function tt_GetScrollX()
234
{
235
    return(window.pageXOffset || (tt_db ? (tt_db.scrollLeft || 0) : 0));
236
}
237
function tt_GetScrollY()
238
{
239
    return(window.pageYOffset || (tt_db ? (tt_db.scrollTop || 0) : 0));
240
}
241
function tt_GetClientW()
242
{
243
    return tt_GetWndCliSiz("Width");
244
}
245
function tt_GetClientH()
246
{
247
    return tt_GetWndCliSiz("Height");
248
}
249
function tt_GetEvtX(e)
250
{
251
    return (e ? ((typeof(e.pageX) != tt_u) ? e.pageX : (e.clientX + tt_GetScrollX())) : 0);
252
}
253
function tt_GetEvtY(e)
254
{
255
    return (e ? ((typeof(e.pageY) != tt_u) ? e.pageY : (e.clientY + tt_GetScrollY())) : 0);
256
}
257
function tt_AddEvtFnc(el, sEvt, PFnc)
258
{
259
    if(el)
260
    {
261
        if(el.addEventListener)
262
            el.addEventListener(sEvt, PFnc, false);
263
        else
264
            el.attachEvent("on" + sEvt, PFnc);
265
    }
266
}
267
function tt_RemEvtFnc(el, sEvt, PFnc)
268
{
269
    if(el)
270
    {
271
        if(el.removeEventListener)
272
            el.removeEventListener(sEvt, PFnc, false);
273
        else
274
            el.detachEvent("on" + sEvt, PFnc);
275
    }
276
}
277
function tt_GetDad(el)
278
{
279
    return(el.parentNode || el.parentElement || el.offsetParent);
280
}
281
function tt_MovDomNode(el, dadFrom, dadTo)
282
{
283
    if(dadFrom)
284
        dadFrom.removeChild(el);
285
    if(dadTo)
286
        dadTo.appendChild(el);
287
}
288

    
289
//======================  PRIVATE  ===========================================//
290
var tt_aExt = new Array(),    // Array of extension objects
291

    
292
tt_db, tt_op, tt_ie, tt_ie56, tt_bBoxOld,    // Browser flags
293
tt_body,
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
301
// Timer
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),
304
tt_bWait = false,
305
tt_u = "undefined";
306

    
307

    
308
function tt_Init()
309
{
310
    tt_MkCmdEnum();
311
    // Send old browsers instantly to hell
312
    if(!tt_Browser() || !tt_MkMainDiv())
313
        return;
314
    tt_IsW3cBox();
315
    tt_OpaSupport();
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)
320
        tt_SetOnloadFnc();
321
    // Ensure the tip be hidden when the page unloads
322
    tt_AddEvtFnc(window, "unload", tt_Hide);
323
}
324
// Creates command names by translating config variable names to upper case
325
function tt_MkCmdEnum()
326
{
327
    var n = 0;
328
    for(var i in config)
329
        eval("window." + i.toString().toUpperCase() + " = " + n++);
330
    tt_aV.length = n;
331
}
332
function tt_Browser()
333
{
334
    var n, nv, n6, w3c;
335

    
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;
340
    if(tt_ie)
341
    {
342
        var ieOld = (!document.compatMode || document.compatMode == "BackCompat");
343
        tt_db = !ieOld ? document.documentElement : (document.body || null);
344
        if(tt_db)
345
            tt_ie56 = parseFloat(nv.substring(nv.indexOf("MSIE") + 5)) >= 5.5
346
                    && typeof document.body.style.maxHeight == tt_u;
347
    }
348
    else
349
    {
350
        tt_db = document.documentElement || document.body ||
351
                (document.getElementsByTagName ? document.getElementsByTagName("body")[0]
352
                : null);
353
        if(!tt_op)
354
        {
355
            n6 = document.defaultView && typeof document.defaultView.getComputedStyle != tt_u;
356
            w3c = !n6 && document.getElementById;
357
        }
358
    }
359
    tt_body = (document.getElementsByTagName ? document.getElementsByTagName("body")[0]
360
                : (document.body || null));
361
    if(tt_ie || n6 || tt_op || w3c)
362
    {
363
        if(tt_body && tt_db)
364
        {
365
            if(document.attachEvent || document.addEventListener)
366
                return true;
367
        }
368
        else
369
            tt_Err("wz_tooltip.js must be included INSIDE the body section,"
370
                    + " immediately after the opening <body> tag.", false);
371
    }
372
    tt_db = null;
373
    return false;
374
}
375
function tt_MkMainDiv()
376
{
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())
383
        return true;
384
    tt_db = null;
385
    return false;
386
}
387
function tt_MkMainDivHtm()
388
{
389
    return(
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>')
392
        : '')
393
    );
394
}
395
function tt_MkMainDivDom()
396
{
397
    var el = document.createElement("div");
398
    if(el)
399
        el.id = "WzTtDiV";
400
    return el;
401
}
402
function tt_GetMainDivRefs()
403
{
404
    tt_aElt[0] = tt_GetElt("WzTtDiV");
405
    if(tt_ie56 && tt_aElt[0])
406
    {
407
        tt_aElt[tt_aElt.length - 1] = tt_GetElt("WzTtIfRm");
408
        if(!tt_aElt[tt_aElt.length - 1])
409
            tt_aElt[0] = null;
410
    }
411
    if(tt_aElt[0])
412
    {
413
        var css = tt_aElt[0].style;
414

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

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

    
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
448
                : 0;
449
}
450
// Ported from http://dean.edwards.name/weblog/2006/06/again/
451
// (Dean Edwards et al.)
452
function tt_SetOnloadFnc()
453
{
454
    tt_AddEvtFnc(document, "DOMContentLoaded", tt_HideSrcTags);
455
    tt_AddEvtFnc(window, "load", tt_HideSrcTags);
456
    if(tt_body.attachEvent)
457
        tt_body.attachEvent("onreadystatechange",
458
            function() {
459
                if(tt_body.readyState == "complete")
460
                    tt_HideSrcTags();
461
            } );
462
    if(/WebKit|KHTML/i.test(navigator.userAgent))
463
    {
464
        var t = setInterval(function() {
465
                    if(/loaded|complete/.test(document.readyState))
466
                    {
467
                        clearInterval(t);
468
                        tt_HideSrcTags();
469
                    }
470
                }, 10);
471
    }
472
}
473
function tt_HideSrcTags()
474
{
475
    if(!window.tt_HideSrcTags || window.tt_HideSrcTags.done)
476
        return;
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);
483
}
484
function tt_HideSrcTagsRecurs(dad)
485
{
486
    var ovr, asT2t;
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;
491

    
492
    for(var i = a ? a.length : 0; i;)
493
    {--i;
494
        if(!tt_HideSrcTagsRecurs(a[i]))
495
            return false;
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)
498
                : null;
499
        if(ovr)
500
        {
501
            asT2t = ovr.toString().match(/TagToTip\s*\(\s*'[^'.]+'\s*[\),]/);
502
            if(asT2t && asT2t.length)
503
            {
504
                if(!tt_HideSrcTag(asT2t[0]))
505
                    return false;
506
            }
507
        }
508
    }
509
    return true;
510
}
511
function tt_HideSrcTag(sT2t)
512
{
513
    var id, el;
514

    
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");
518
    el = tt_GetElt(id);
519
    if(el)
520
    {
521
        if(tt_Debug && !TagsToTip)
522
            return false;
523
        else
524
            el.style.display = "none";
525
    }
526
    else
527
        tt_Err("Invalid ID\n'" + id + "'\npassed to TagToTip()."
528
                + " There exists no HTML element with that ID.", true);
529
    return true;
530
}
531
function tt_Tip(arg, t2t)
532
{
533
    if(!tt_db || (tt_iState & 0x8))
534
        return;
535
    if(tt_iState)
536
        tt_Hide();
537
    if(!tt_Enabled)
538
        return;
539
    tt_t2t = t2t;
540
    if(!tt_ReadCmds(arg))
541
        return;
542
    tt_iState = 0x1 | 0x4;
543
    tt_AdaptConfig1();
544
    tt_MkTipContent(arg);
545
    tt_MkTipSubDivs();
546
    tt_FormatTip();
547
    tt_bJmpVert = false;
548
    tt_bJmpHorz = false;
549
    tt_maxPosX = tt_GetClientW() + tt_GetScrollX() - tt_w - 1;
550
    tt_maxPosY = tt_GetClientH() + tt_GetScrollY() - tt_h - 1;
551
    tt_AdaptConfig2();
552
    // Ensure the tip be shown and positioned before the first onmousemove
553
    tt_OverInit();
554
    tt_ShowInit();
555
    tt_Move();
556
}
557
function tt_ReadCmds(a)
558
{
559
    var i;
560

    
561
    // First load the global config values, to initialize also values
562
    // for which no command is passed
563
    i = 0;
564
    for(var j in config)
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)
568
    if(a.length & 1)
569
    {
570
        for(i = a.length - 1; i > 0; i -= 2)
571
            tt_aV[a[i - 1]] = a[i];
572
        return true;
573
    }
574
    tt_Err("Incorrect call of Tip() or TagToTip().\n"
575
            + "Each command must be followed by a value.", true);
576
    return false;
577
}
578
function tt_AdaptConfig1()
579
{
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];
590
    if(tt_aV[CLOSEBTN])
591
    {
592
        // Use title colours for non-specified closebutton colours
593
        if(!tt_aV[CLOSEBTNCOLORS])
594
            tt_aV[CLOSEBTNCOLORS] = new Array("", "", "", "");
595
        for(var i = 4; i;)
596
        {--i;
597
            if(!tt_aV[CLOSEBTNCOLORS][i].length)
598
                tt_aV[CLOSEBTNCOLORS][i] = (i & 1) ? tt_aV[TITLEFONTCOLOR] : tt_aV[TITLEBGCOLOR];
599
        }
600
        // Enforce titlebar be shown
601
        if(!tt_aV[TITLE].length)
602
            tt_aV[TITLE] = " ";
603
    }
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)
606
        tt_aV[OPACITY] = 99;
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);
610
}
611
function tt_AdaptConfig2()
612
{
613
    if(tt_aV[CENTERMOUSE])
614
    {
615
        tt_aV[OFFSETX] -= ((tt_w - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0)) >> 1);
616
        tt_aV[JUMPHORZ] = false;
617
    }
618
}
619
// Expose content globally so extensions can modify it
620
function tt_MkTipContent(a)
621
{
622
    if(tt_t2t)
623
    {
624
        if(tt_aV[COPYCONTENT])
625
            tt_sContent = tt_t2t.innerHTML;
626
        else
627
            tt_sContent = "";
628
    }
629
    else
630
        tt_sContent = a[0];
631
    tt_ExtCallFncs(0, "CreateContentString");
632
}
633
function tt_MkTipSubDivs()
634
{
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 ';
637

    
638
    tt_aElt[0].style.width = tt_GetClientW() + "px";
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="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]
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
        tt_El2Tip();
670
    tt_ExtCallFncs(0, "SubDivsCreated");
671
}
672
function tt_GetSubDivRefs()
673
{
674
    var aId = new Array("WzTiTl", "WzTiTlTb", "WzTiTlI", "WzClOsE", "WzBoDy", "WzBoDyI", "WzTtShDwB", "WzTtShDwR");
675

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

    
684
    //--------- Title DIV ----------
685
    if(tt_aV[TITLE].length)
686
    {
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];
700
        // Close button DIV
701
        if(tt_aElt[4])
702
        {
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";
709
        }
710
        if(tt_aV[WIDTH] > 0)
711
            tt_w = tt_aV[WIDTH];
712
        else
713
        {
714
            tt_w = tt_GetDivW(tt_aElt[3]) + tt_GetDivW(tt_aElt[4]);
715
            // Some spacing between title DIV and closebutton
716
            if(tt_aElt[4])
717
                tt_w += pad;
718
            // Restrict auto width to max width
719
            if(tt_aV[WIDTH] < -1 && tt_w > -tt_aV[WIDTH])
720
                tt_w = -tt_aV[WIDTH];
721
        }
722
        // Ensure the top border of the body DIV be covered by the title DIV
723
        iOffY = -wBrd;
724
    }
725
    else
726
    {
727
        tt_w = 0;
728
        iOffY = 0;
729
    }
730

    
731
    //-------- Body DIV ------------
732
    css = tt_aElt[5].style;
733
    css.top = iOffY + "px";
734
    if(wBrd)
735
    {
736
        css.borderColor = tt_aV[BORDERCOLOR];
737
        css.borderStyle = tt_aV[BORDERSTYLE];
738
        css.borderWidth = wBrd + "px";
739
    }
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];
746
    if(tt_aV[HEIGHT])
747
    {
748
        css.overflow = "auto";
749
        if(tt_aV[HEIGHT] > 0)
750
            css.height = (tt_aV[HEIGHT] + iAdd) + "px";
751
        else
752
            tt_h = iAdd - tt_aV[HEIGHT];
753
    }
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];
761
    if(tt_aV[WIDTH] > 0)
762
        w = tt_aV[WIDTH];
763
    // Width like title (if existent)
764
    else if(tt_aV[WIDTH] == -1 && tt_w)
765
        w = tt_w;
766
    else
767
    {
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])
773
            w = -tt_aV[WIDTH];
774
    }
775
    if(w > tt_w)
776
        tt_w = w;
777
    tt_w += iAdd;
778

    
779
    //--------- Shadow DIVs ------------
780
    if(tt_aV[SHADOW])
781
    {
782
        tt_w += tt_aV[SHADOWWIDTH];
783
        iOffSh = Math.floor((tt_aV[SHADOWWIDTH] * 4) / 3);
784
        // Bottom shadow
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];
791
        // Right shadow
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];
797
    }
798
    else
799
        iOffSh = 0;
800

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

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

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

    
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";
916
}
917
function tt_UnEl2Tip()
918
{
919
    // Restore positioning and display
920
    var css = tt_t2t.style;
921

    
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;
927
    tt_t2tDad = null;
928
}
929
function tt_OverInit()
930
{
931
    if(window.event)
932
        tt_over = window.event.target || window.event.srcElement;
933
    else
934
        tt_over = tt_ovr_;
935
    tt_DeAlt(tt_over);
936
    tt_OpDeHref(tt_over);
937
}
938
function tt_ShowInit()
939
{
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);
943
}
944
function tt_Show()
945
{
946
    var css = tt_aElt[0].style;
947

    
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])
951
        tt_iState &= ~0x4;
952
    if(tt_aV[EXCLUSIVE])
953
        tt_iState |= 0x8;
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";
958
    tt_iState |= 0x2;
959
    if(tt_aV[FADEIN])
960
        tt_Fade(0, 0, tt_aV[OPACITY], Math.round(tt_aV[FADEIN] / tt_aV[FADEINTERVAL]));
961
    tt_ShowIfrm();
962
}
963
function tt_ShowIfrm()
964
{
965
    if(tt_ie56)
966
    {
967
        var ifrm = tt_aElt[tt_aElt.length - 1];
968
        if(ifrm)
969
        {
970
            var css = ifrm.style;
971
            css.zIndex = tt_aElt[0].style.zIndex - 1;
972
            css.display = "block";
973
        }
974
    }
975
}
976
function tt_Move(e)
977
{
978
    if(e)
979
        tt_ovr_ = e.target || e.srcElement;
980
    e = e || window.event;
981
    if(e)
982
    {
983
        tt_musX = tt_GetEvtX(e);
984
        tt_musY = tt_GetEvtY(e);
985
    }
986
    if(tt_iState & 0x4)
987
    {
988
        // Prevent jam of mousemove events
989
        if(!tt_op && !tt_ie)
990
        {
991
            if(tt_bWait)
992
                return;
993
            tt_bWait = true;
994
            tt_tWaitMov.Timer("tt_bWait = false;", 1, true);
995
        }
996
        if(tt_aV[FIX])
997
        {
998
            tt_iState &= ~0x4;
999
            tt_PosFix();
1000
        }
1001
        else if(!tt_ExtCallFncs(e, "MoveBefore"))
1002
            tt_SetTipPos(tt_Pos(0), tt_Pos(1));
1003
        tt_ExtCallFncs([tt_musX, tt_musY], "MoveAfter")
1004
    }
1005
}
1006
function tt_Pos(iDim)
1007
{
1008
    var iX, bJmpMod, cmdAlt, cmdOff, cx, iMax, iScrl, iMus, bJmp;
1009

    
1010
    // Map values according to dimension to calculate
1011
    if(iDim)
1012
    {
1013
        bJmpMod = tt_aV[JUMPVERT];
1014
        cmdAlt = ABOVE;
1015
        cmdOff = OFFSETY;
1016
        cx = tt_h;
1017
        iMax = tt_maxPosY;
1018
        iScrl = tt_GetScrollY();
1019
        iMus = tt_musY;
1020
        bJmp = tt_bJmpVert;
1021
    }
1022
    else
1023
    {
1024
        bJmpMod = tt_aV[JUMPHORZ];
1025
        cmdAlt = LEFT;
1026
        cmdOff = OFFSETX;
1027
        cx = tt_w;
1028
        iMax = tt_maxPosX;
1029
        iScrl = tt_GetScrollX();
1030
        iMus = tt_musX;
1031
        bJmp = tt_bJmpHorz;
1032
    }
1033
    if(bJmpMod)
1034
    {
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);
1039
        else
1040
            iX = tt_PosDef(iDim);
1041
    }
1042
    else
1043
    {
1044
        iX = iMus;
1045
        if(tt_aV[cmdAlt])
1046
            iX -= cx + tt_aV[cmdOff] - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0);
1047
        else
1048
            iX += tt_aV[cmdOff];
1049
    }
1050
    // Prevent tip from extending past clientarea boundary
1051
    if(iX > iMax)
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
1055
    if(iX < iScrl)
1056
        iX = bJmpMod ? tt_PosDef(iDim) : iScrl;
1057
    return iX;
1058
}
1059
function tt_PosDef(iDim)
1060
{
1061
    if(iDim)
1062
        tt_bJmpVert = tt_aV[ABOVE];
1063
    else
1064
        tt_bJmpHorz = tt_aV[LEFT];
1065
    return tt_CalcPosDef(iDim);
1066
}
1067
function tt_PosAlt(iDim)
1068
{
1069
    if(iDim)
1070
        tt_bJmpVert = !tt_aV[ABOVE];
1071
    else
1072
        tt_bJmpHorz = !tt_aV[LEFT];
1073
    return tt_CalcPosAlt(iDim);
1074
}
1075
function tt_CalcPosDef(iDim)
1076
{
1077
    return iDim ? (tt_musY + tt_aV[OFFSETY]) : (tt_musX + tt_aV[OFFSETX]);
1078
}
1079
function tt_CalcPosAlt(iDim)
1080
{
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)
1084
        dx = 1;
1085
    return((iDim ? (tt_musY - tt_h) : (tt_musX - tt_w)) - dx);
1086
}
1087
function tt_PosFix()
1088
{
1089
    var iX, iY;
1090

    
1091
    if(typeof(tt_aV[FIX][0]) == "number")
1092
    {
1093
        iX = tt_aV[FIX][0];
1094
        iY = tt_aV[FIX][1];
1095
    }
1096
    else
1097
    {
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
1101
        else
1102
            el = tt_aV[FIX][0];
1103
        iX = tt_aV[FIX][1];
1104
        iY = tt_aV[FIX][2];
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)
1109
        {
1110
            iX += el.offsetLeft || 0;
1111
            iY += el.offsetTop || 0;
1112
        }
1113
    }
1114
    // For a fixed tip positioned above the mouse, use the bottom edge as anchor
1115
    // (recommended by Christophe Rebeschini, 31.1.2008)
1116
    if(tt_aV[ABOVE])
1117
        iY -= tt_h;
1118
    tt_SetTipPos(iX, iY);
1119
}
1120
function tt_Fade(a, now, z, n)
1121
{
1122
    if(n)
1123
    {
1124
        now += Math.round((z - now) / n);
1125
        if((z > a) ? (now >= z) : (now <= z))
1126
            now = z;
1127
        else
1128
            tt_tFade.Timer(
1129
                "tt_Fade("
1130
                + a + "," + now + "," + z + "," + (n - 1)
1131
                + ")",
1132
                tt_aV[FADEINTERVAL],
1133
                true
1134
            );
1135
    }
1136
    now ? tt_SetTipOpa(now) : tt_Hide();
1137
}
1138
function tt_SetTipOpa(opa)
1139
{
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);
1143
    if(tt_aElt[1])
1144
        tt_SetOpa(tt_aElt[1], opa);
1145
    if(tt_aV[SHADOW])
1146
    {
1147
        opa = Math.round(opa * 0.8);
1148
        tt_SetOpa(tt_aElt[7], opa);
1149
        tt_SetOpa(tt_aElt[8], opa);
1150
    }
1151
}
1152
function tt_OnCloseBtnOver(iOver)
1153
{
1154
    var css = tt_aElt[4].style;
1155

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

    
1179
    return(isNaN(y = parseInt(x)) ? 0 : y);
1180
}
1181
Number.prototype.Timer = function(s, iT, bUrge)
1182
{
1183
    if(!this.value || bUrge)
1184
        this.value = window.setTimeout(s, iT);
1185
}
1186
Number.prototype.EndTimer = function()
1187
{
1188
    if(this.value)
1189
    {
1190
        window.clearTimeout(this.value);
1191
        this.value = 0;
1192
    }
1193
}
1194
function tt_GetWndCliSiz(s)
1195
{
1196
    var db, y = window["inner" + s], sC = "client" + s, sN = "number";
1197
    if(typeof y == sN)
1198
    {
1199
        var y2;
1200
        return(
1201
            // Gecko or Opera with scrollbar
1202
            // ... quirks mode
1203
            ((db = document.body) && typeof(y2 = db[sC]) == sN && y2 &&  y2 <= y) ? y2 
1204
            // ... strict mode
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.)
1207
            : y
1208
        );
1209
    }
1210
    // IE
1211
    return(
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
1216
        : document.body[sC]
1217
    );
1218
}
1219
function tt_SetOpa(el, opa)
1220
{
1221
    var css = el.style;
1222

    
1223
    tt_opa = opa;
1224
    if(tt_flagOpa == 1)
1225
    {
1226
        if(opa < 100)
1227
        {
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, ...)
1239
            css.zoom = "100%";
1240
            if(!bVis)
1241
                css.visibility = "visible";
1242
            css.filter = "alpha(opacity=" + opa + ")";
1243
            if(!bVis)
1244
                css.visibility = "hidden";
1245
        }
1246
        else if(typeof(el.filtNo) != tt_u)
1247
            // Restore 'non-filter'
1248
            css.filter = el.filtNo;
1249
    }
1250
    else
1251
    {
1252
        opa /= 100.0;
1253
        switch(tt_flagOpa)
1254
        {
1255
        case 2:
1256
            css.KhtmlOpacity = opa; break;
1257
        case 3:
1258
            css.KHTMLOpacity = opa; break;
1259
        case 4:
1260
            css.MozOpacity = opa; break;
1261
        case 5:
1262
            css.opacity = opa; break;
1263
        }
1264
    }
1265
}
1266
function tt_Err(sErr, bIfDebug)
1267
{
1268
    if(tt_Debug || !bIfDebug)
1269
        alert("Tooltip Script Error Message:\n\n" + sErr);
1270
}
1271

    
1272
//============  EXTENSION (PLUGIN) MANAGER  ===============//
1273
function tt_ExtCmdEnum()
1274
{
1275
    var s;
1276

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

    
1301
tt_Init();
(13-13/13)