Subversion Repositories svnkaklik

Rev

Details | Last modification | View Log

Rev Author Line No. Line
6 kaklik 1
// {{{ docs <-- this is a VIM (text editor) text fold
2
 
3
/**
4
 * DOM Tooltip 0.6.0
5
 *
6
 * Summary:
7
 * Allows developers to add custom tooltips to the webpages.  Tooltips are
8
 * controlled through three style class definitions.  This library also detects
9
 * collisions against native widgets in the browser that cannot handle the
10
 * zIndex property.  But this library is even more than that...with all the
11
 * features it has, it has the potential to replace the need for popups
12
 * entirely as it can embed just about any html inside the tooltip, leading to
13
 * the possibility of having whole forms or iframes right inside the tip...even
14
 * other programs!!!
15
 *
16
 * Maintainer: Dan Allen <dan@mojavelinux.com>
17
 *
18
 * License: LGPL
19
 * However, if you use this library, you become an official bug reporter :)
20
 * Please post to my forum where you use it so that I get a chance to see my
21
 * baby in action.  If you are doing this for commercial work perhaps you could
22
 * send me a few Starbucks Coffee gift dollars to encourage future developement
23
 * (NOT REQUIRED).  E-mail me for my address.
24
 *
25
 * Homepage: http://www.mojavelinux.com/forum/viewtopic.php?t=127
26
 *
27
 * Freshmeat Project: http://freshmeat.net/projects/domtt/?topic_id=92
28
 *
29
 * Updated: 2003/02/14
30
 *
31
 * Supported Browsers: Mozilla (Gecko), IE 5.0+, Konqueror, Opera 7
32
 *
33
 * Usage:
34
 * All this is required is to put the function call in the event tag for an
35
 * html element. The status option (for changing the status bar text) is only
36
 * available through all events, but when used with 'onmouseover' you have to
37
 * return true so that the browser does not display the link text in the status
38
 * bar.  To do this, wrap the domTT_activate call in the function makeTrue(),
39
 * which will just return true, and then prefix it with a 'return'
40
 *
41
 * Example: <a href="index.html" onmouseover="return makeTrue(domTT_activate(this, event, 'caption', 'Help', 'content', 'This is a link with a tooltip', 'statusText', 'Link', 'trial', true));">click me</a>
42
 *
43
 * Options:
44
 * Each option is followed by the value for that option.  The variable event
45
 * must be the first parameter, as shown above.  The options avaiable are:
46
 *
47
 *	predefined (optional, must be first item if used, loads default values)
48
 *	caption (optional)
49
 *	content (required)
50
 *	closeLink (optional, defaults to domTT_closeLink global setting variable)
51
 *	statusText (optional, if used with mouseover must wrap call in 'return domTT_true()')
52
 *	type (optional, defaults to 'greasy' but can be 'sticky' or 'velcro')
53
 *	classPrefix (optional, defaults to 'domTT', for changing style class)
54
 *	delay (optional, defaults to global delay value domTT_activateDelay)
55
 *	parent (optional, defaults to document.body)
56
 *	closeAction (optional, defaults to global domTT_closeAction, either 'hide' or 'remove')
57
 *	trail (optional, follow the mouse cursor while tooltip is active)
58
**/
59
 
60
// }}}
61
// {{{ Settings (editable)
62
 
63
/**
64
 * Settings (editable)
65
 */
66
var domTT_offsetX = 0;
67
var domTT_offsetY = 2;
68
var domTT_direction = 'southeast';
69
var domTT_mouseHeight = 20;
70
var domTT_closeLink = 'X';
71
var domTT_screenEdgePadding = 5;
72
var domTT_activateDelay = 500;
73
var domTT_maxWidth = 300;
74
var domTT_useGlobalMousePosition = true;
75
var domTT_classPrefix = 'domTT';
76
var domTT_fade = 'neither';
77
var domTT_lifetime = 0;
78
var domTT_grid = 0;
79
var domTT_closeAction = 'hide';
80
var domTT_dragStickyTips;
81
if (typeof(domTT_dragStickyTips) == 'undefined')
82
{
83
	var domTT_dragStickyTips = false;
84
}
85
 
86
// }}}
87
// {{{ Global constants
88
 
89
/**
90
 * Global constants (DO NOT EDIT)
91
 */
92
var domTT_predefined = new Hash();
93
var domTT_tooltips = new Hash();
94
 
95
// }}}
96
// {{{ document.onmousemove
97
 
98
if (domLib_useLibrary && domTT_useGlobalMousePosition)
99
{
100
	var domTT_mousePosition = new Hash();
101
	document.onmousemove = function(in_event)
102
	{
103
		if (typeof(in_event) == 'undefined')
104
		{
105
			in_event = event;
106
		}
107
 
108
		domTT_mousePosition = domLib_getEventPosition(in_event);
109
		if (domTT_dragStickyTips && domTT_dragMouseDown)
110
		{
111
			domTT_dragUpdate(in_event);
112
		}
113
	}
114
}
115
 
116
// }}}
117
// {{{ domTT_activate()
118
 
119
function domTT_activate(in_this, in_event)
120
{
121
	if (!domLib_useLibrary) { return false; }
122
 
123
	// make sure in_event is set (for IE, some cases we have to use window.event)
124
	if (typeof(in_event) == 'undefined')
125
	{
126
		in_event = window.event;
127
	}
128
 
129
	var owner = document.body;
130
	// we have an active event so get the owner
131
	if (in_event.type.match(/key|mouse|click|contextmenu/i))
132
	{
133
		// make sure we have nothing higher than the body element
134
		if (in_this.nodeType && in_this.nodeType != 9)
135
		{
136
			var owner = in_this;
137
		}
138
	}
139
	// non active event
140
	else
141
	{
142
		if (!(owner = document.getElementById(in_this)))
143
		{
144
			owner = document.body.appendChild(document.createElement('div'));
145
			owner.style.display = 'none';
146
			owner.id = in_this;
147
		}
148
	}
149
 
150
	// make sure the owner has a unique id
151
	if (!owner.id)
152
	{
153
		owner.id = '__autoId' + domLib_autoId++;
154
	}
155
 
156
	var tooltip = domTT_tooltips.get(owner.id);
157
	if (tooltip)
158
	{
159
		if (tooltip.get('eventType') != in_event.type)
160
		{
161
			if (tooltip.get('type') == 'greasy')
162
			{
163
				tooltip.set('closeAction', 'destroy');
164
				domTT_deactivate(owner.id);
165
			}
166
			else if (tooltip.get('status') != 'inactive')
167
			{
168
				return owner.id;
169
			}
170
		}
171
		else
172
		{
173
			if (tooltip.get('status') == 'inactive')
174
			{
175
				tooltip.set('status', 'pending');
176
				tooltip.set('activateTimeout', domLib_setTimeout(function(argv) { 
177
					domTT_show(argv[0], argv[1]); 
178
				}, tooltip.get('delay'), [owner.id, in_event]));
179
 
180
				return owner.id;
181
			}
182
			// either pending or active, let it be
183
			else
184
			{
185
				return owner.id;
186
			}
187
		}
188
	}
189
 
190
	// setup the default options hash
191
	var options = new Hash(
192
		'caption',		'',
193
		'content',		'',
194
		'closeLink',	domTT_closeLink,
195
		'parent',		document.body,
196
		'position',		'absolute',
197
		'type',			'greasy',
198
		'direction',	domTT_direction,
199
		'delay',		domTT_activateDelay,
200
		'classPrefix',	domTT_classPrefix,
201
		'closeAction',	domTT_closeAction,
202
		'lifetime',		domTT_lifetime,
203
		'grid',			domTT_grid,
204
		'fade',			domTT_fade,
205
		'trail',		false
206
	);
207
 
208
	// load in the options from the function call
209
	for (var i = 2; i < arguments.length; i += 2)
210
	{
211
		// load in predefined
212
		if (arguments[i] == 'predefined')
213
		{
214
			var predefinedOptions = domTT_predefined.get(arguments[i + 1]);
215
			for (var j in predefinedOptions.elementData)
216
			{
217
				options.set(j, predefinedOptions.get(j));
218
			}
219
		}
220
		// set option
221
		else
222
		{
223
			options.set(arguments[i], arguments[i + 1]);
224
		}
225
	}
226
 
227
	options.set('eventType', in_event.type);
228
 
229
	// immediately set the status text if provided
230
	if (options.has('statusText')) {
231
		try { window.status = options.get('statusText'); } catch(e) {}
232
	}
233
 
234
	// if we didn't give content...assume we just wanted to change the status and return
235
	if (!options.has('content') || options.get('content') == '')
236
	{
237
		if (typeof(owner.onmouseout) != 'function')
238
		{
239
			owner.onmouseout = function(in_event) { domTT_mouseout(this, in_event); };
240
		}
241
 
242
		return owner.id;
243
	}
244
 
245
	options.set('owner', owner);
246
	options.set('id', '[domTT]' + owner.id);
247
	domTT_create(options);
248
	// determine the show delay
249
	options.set('delay', in_event.type.match(/click|mousedown|contextmenu/i) ? 0 : parseInt(options.get('delay')));
250
	domTT_tooltips.set(owner.id, options);
251
	options.set('status', 'pending');
252
	options.set('activateTimeout', domLib_setTimeout(function(argv) { 
253
		domTT_show(argv[0], argv[1]); 
254
	}, options.get('delay'), [owner.id, in_event]));
255
 
256
	return owner.id;
257
}
258
 
259
// }}}
260
// {{{ domTT_create()
261
 
262
function domTT_create(in_options)
263
{
264
	var owner = in_options.get('owner');
265
 
266
	// create the tooltip and hide it
267
	var tipObj = document.body.appendChild(document.createElement('div'));
268
	tipObj.style.position = 'absolute';
269
	tipObj.style.left = '0px';
270
	tipObj.style.top = '0px';
271
	tipObj.style.visibility = 'hidden';
272
	tipObj.id = in_options.get('id');
273
	tipObj.className = in_options.get('classPrefix');
274
 
275
	if (in_options.get('caption') || (in_options.get('type') == 'sticky' && in_options.get('caption') !== false))
276
	{
277
 
278
		// layout the tip with a hidden formatting table
279
		var tipLayoutTable = tipObj.appendChild(document.createElement('table'));
280
		tipLayoutTable.style.borderCollapse = 'collapse';
281
		if (domLib_isKonq)
282
		{
283
			tipLayoutTable.cellSpacing = 0;
284
		}
285
 
286
		var tipLayoutTbody = tipLayoutTable.appendChild(document.createElement('tbody'));
287
 
288
		var numCaptionCells = 0;
289
		var captionRow = tipLayoutTbody.appendChild(document.createElement('tr'));
290
		var captionCell = captionRow.appendChild(document.createElement('td'));
291
		captionCell.style.padding = '0px';
292
		var caption = captionCell.appendChild(document.createElement('div'));
293
		caption.className = in_options.get('classPrefix') + 'Caption';
294
		caption.style.height = '100%';
295
		caption.appendChild(document.createTextNode(in_options.get('caption')));
296
 
297
		if (in_options.get('type') == 'sticky')
298
		{
299
			var numCaptionCells = 2;
300
			var closeLinkCell = captionRow.appendChild(document.createElement('td'));
301
			closeLinkCell.style.padding = '0px';
302
			var closeLink = closeLinkCell.appendChild(document.createElement('div'));
303
			closeLink.className = in_options.get('classPrefix') + 'Caption';
304
			closeLink.style.height = '100%';
305
			closeLink.style.textAlign = 'right';
306
			closeLink.style.cursor = domLib_stylePointer;
307
			// merge the styles of the two cells
308
			closeLink.style.borderLeftWidth = caption.style.borderRightWidth = '0px';
309
			closeLink.style.paddingLeft = caption.style.paddingRight = '0px';
310
			closeLink.style.marginLeft = caption.style.marginRight = '0px';
311
			if (in_options.get('closeLink').nodeType)
312
			{
313
				closeLink.appendChild(in_options.get('closeLink').cloneNode(1));
314
			}
315
			else
316
			{
317
				closeLink.innerHTML = in_options.get('closeLink');
318
			}
319
 
320
			closeLink.onclick = function() { domTT_deactivate(owner.id); };
321
			closeLink.onmousedown = function(in_event) { if (typeof(in_event) == 'undefined') { in_event = event; } in_event.cancelBubble = true; };
322
		}
323
 
324
		var contentRow = tipLayoutTbody.appendChild(document.createElement('tr'));
325
		var contentCell = contentRow.appendChild(document.createElement('td'));
326
		contentCell.style.padding = '0px';
327
		if (numCaptionCells)
328
		{
329
			if (domLib_isIE)
330
			{
331
				contentCell.colSpan = numCaptionCells;
332
			}
333
			else
334
			{
335
				contentCell.setAttribute('colspan', numCaptionCells);
336
			}
337
		}
338
 
339
		var content = contentCell.appendChild(document.createElement('div'));
340
		if (domLib_isIE50)
341
		{
342
			content.style.height = '100%';
343
		}
344
	}
345
	else
346
	{
347
		var content = tipObj.appendChild(document.createElement('div'));
348
	}
349
 
350
	content.className = in_options.get('classPrefix') + 'Content';
351
 
352
	if (in_options.get('content').nodeType)
353
	{
354
		content.appendChild(in_options.get('content').cloneNode(1));
355
	}
356
	else
357
	{
358
		content.innerHTML = in_options.get('content');
359
	}
360
 
361
	// adjust the width if specified
362
	if (in_options.has('width'))
363
	{
364
		tipObj.style.width = parseInt(in_options.get('width')) + 'px';
365
	}
366
 
367
	// check if we are overridding the maxWidth
368
	// if the browser supports maxWidth, the global setting will be ignored (assume stylesheet)
369
	var maxWidth = domTT_maxWidth;
370
	if (in_options.has('maxWidth'))
371
	{
372
		if ((maxWidth = in_options.get('maxWidth')) === false)
373
		{
374
			tipObj.style.maxWidth = domLib_styleNoMaxWidth;
375
		}
376
		else
377
		{
378
			maxWidth = parseInt(in_options.get('maxWidth'));
379
			tipObj.style.maxWidth = maxWidth + 'px';
380
		}
381
	}
382
 
383
	// :HACK: fix lack of maxWidth in CSS for Konq and IE
384
	if (maxWidth !== false && (domLib_isIE || domLib_isKonq) && tipObj.offsetWidth > maxWidth)
385
	{
386
		tipObj.style.width = maxWidth + 'px';
387
	}
388
 
389
	// tooltip floats
390
	if (in_options.get('position') == 'absolute' && !(in_options.has('x') && in_options.has('y')))
391
	{
392
		// determine the offset relative to the pointer
393
		switch (in_options.get('direction'))
394
		{
395
			case 'northeast':
396
				var offset_x = domTT_offsetX;
397
				var offset_y = 0 - tipObj.offsetHeight - domTT_offsetY;
398
			break;
399
			case 'northwest':
400
				var offset_x = 0 - tipObj.offsetWidth - domTT_offsetX;
401
				var offset_y = 0 - tipObj.offsetHeight - domTT_offsetY;
402
			break;
403
			case 'southwest':
404
				var offset_x = 0 - tipObj.offsetWidth - domTT_offsetX;
405
				var offset_y = domTT_mouseHeight + domTT_offsetY;
406
			break;
407
			case 'southeast':
408
				var offset_x = domTT_offsetX;
409
				var offset_y = domTT_mouseHeight + domTT_offsetY;
410
			break;
411
		}
412
	}
413
	// tooltip is fixed
414
	else
415
	{
416
		var offset_x = 0;
417
		var offset_y = 0;
418
		in_options.set('trail', false);
419
	}
420
 
421
	in_options.set('offsetX', offset_x);
422
	in_options.set('offsetY', offset_y);
423
	in_options.set('offsetWidth', tipObj.offsetWidth);
424
	in_options.set('offsetHeight', tipObj.offsetHeight);
425
	if (domLib_canFade && typeof(alphaAPI) == 'function')
426
	{
427
		if (in_options.get('fade') != 'neither')
428
		{
429
			var fadeHandler = new alphaAPI(tipObj, 50, 50, 100, 0, null, 10);
430
			fadeHandler.setAlpha(0);
431
			in_options.set('fadeHandler', fadeHandler);
432
		}
433
	}
434
	else
435
	{
436
		in_options.set('fade', 'neither');
437
	}
438
 
439
	// setup mouse events
440
	if (in_options.get('trail') && typeof(owner.onmousemove) != 'function')
441
	{
442
		owner.onmousemove = function(in_event) { domTT_mousemove(this, in_event); };
443
	}
444
 
445
	if (typeof(owner.onmouseout) != 'function')
446
	{
447
		owner.onmouseout = function(in_event) { domTT_mouseout(this, in_event); };
448
	}
449
 
450
	if (in_options.get('type') == 'sticky')
451
	{
452
		if (in_options.get('position') == 'absolute' && domTT_dragStickyTips)
453
		{
454
			if (domLib_isIE)
455
			{
456
				captionRow.onselectstart = function() { return false; };
457
			}
458
 
459
			// setup drag
460
			captionRow.onmousedown = function(in_event) { domTT_dragStart(tipObj, in_event);  };
461
			captionRow.onmousemove = function(in_event) { domTT_dragUpdate(in_event); };
462
			captionRow.onmouseup = function() { domTT_dragStop(); };
463
		}
464
	}
465
	else if (in_options.get('type') == 'velcro')
466
	{
467
		tipObj.onmouseout = function(in_event) { if (typeof(in_event) == 'undefined') { in_event = event; } if (!domLib_isDescendantOf(in_event[domLib_eventTo], tipObj)) { domTT_deactivate(owner.id); }};
468
	}
469
 
470
	if (in_options.get('position') == 'relative')
471
	{
472
		tipObj.style.position = 'relative';
473
	}
474
 
475
	if (in_options.get('parent') != document.body)
476
	{
477
		in_options.get('parent').appendChild(tipObj);
478
	}
479
 
480
	in_options.set('node', tipObj);
481
	in_options.set('status', 'inactive');
482
}
483
 
484
// }}}
485
// {{{ domTT_show()
486
 
487
function domTT_show(in_ownerId, in_event)
488
{
489
	// should always find one since this call would be cancelled if tip was killed
490
	var tooltip = domTT_tooltips.get(in_ownerId);
491
	var status = tooltip.get('status');
492
	var tipObj = tooltip.get('node');
493
 
494
	if (tooltip.get('position') == 'absolute')
495
	{
496
		if (tooltip.has('x') && tooltip.has('y'))
497
		{
498
			var mouse_x = tooltip.get('x');
499
			var mouse_y = tooltip.get('y');
500
		}
501
		else if (!domTT_useGlobalMousePosition || status == 'active' || tooltip.get('delay') == 0)
502
		{
503
			var eventPosition = domLib_getEventPosition(in_event);
504
			var mouse_x = eventPosition.get('x');
505
			var mouse_y = eventPosition.get('y');
506
		}
507
		else
508
		{
509
			var mouse_x = domTT_mousePosition.get('x');
510
			var mouse_y = domTT_mousePosition.get('y');
511
		}
512
 
513
		// we are using a grid for updates
514
		if (tooltip.get('grid'))
515
		{
516
			// if this is not a mousemove event or it is a mousemove event on an active tip and
517
			// the movement is bigger than the grid
518
			if (in_event.type != 'mousemove' || (status == 'active' && (Math.abs(tooltip.get('lastX') - mouse_x) > tooltip.get('grid') || Math.abs(tooltip.get('lastY') - mouse_y) > tooltip.get('grid'))))
519
			{
520
				tooltip.set('lastX', mouse_x);
521
				tooltip.set('lastY', mouse_y);
522
			}
523
			// did not satisfy the grid movement requirement
524
			else
525
			{
526
				return false;
527
			}
528
		}
529
 
530
		var coordinates = {'x' : mouse_x + tooltip.get('offsetX'), 'y' : mouse_y + tooltip.get('offsetY')};
531
		coordinates = domTT_correctEdgeBleed(tooltip.get('offsetWidth'), tooltip.get('offsetHeight'), coordinates.x, coordinates.y, domTT_offsetX, domTT_offsetY, tooltip.get('type'));
532
 
533
		// update the position
534
		tipObj.style.left = coordinates.x + 'px';
535
		tipObj.style.top = coordinates.y + 'px';
536
 
537
		// increase the tip zIndex so it goes over previously shown tips
538
		tipObj.style.zIndex = domLib_zIndex++;
539
	}
540
 
541
	// if tip is not active, active it now and check for a fade in
542
	if (status == 'pending')
543
	{
544
		// unhide the tooltip
545
		tooltip.set('status', 'active');
546
		tipObj.style.display = '';
547
		tipObj.style.visibility = 'visible';
548
 
549
		var fade = tooltip.get('fade');
550
		if (fade != 'neither')
551
		{
552
			var fadeHandler = tooltip.get('fadeHandler');
553
			if (fade == 'out' || fade == 'both')
554
			{
555
				fadeHandler.pause();
556
				if (fade == 'out')
557
				{
558
					fadeHandler.reset();
559
				}
560
			}
561
 
562
			if (fade == 'in' || fade == 'both')
563
			{
564
				fadeHandler.fadeIn();
565
			}
566
		}
567
 
568
		if (tooltip.get('type') == 'greasy' && tooltip.get('lifetime') != 0)
569
		{
570
			tooltip.set('lifetimeTimeout', domLib_setTimeout(function(argv) { domTT_deactivate(argv[0]); }, tooltip.get('lifetime'), [in_ownerId]));
571
		}
572
	}
573
 
574
	if (tooltip.get('position') == 'absolute')
575
	{
576
		domLib_detectCollisions(tipObj);
577
	}
578
}
579
 
580
// }}}
581
// {{{ domTT_deactivate()
582
 
583
function domTT_deactivate(in_ownerId)
584
{
585
	var tooltip = domTT_tooltips.get(in_ownerId);
586
	if (tooltip)
587
	{
588
		var status = tooltip.get('status');
589
		if (status == 'pending')
590
		{
591
			// cancel the creation of this tip if it is still pending
592
			domLib_clearTimeout(tooltip.get('activateTimeout'));
593
			tooltip.set('status', 'inactive');
594
		}
595
		else if (status == 'active')
596
		{
597
			if (tooltip.get('lifetime'))
598
			{
599
				domLib_clearTimeout(tooltip.get('lifetimeTimeout'));
600
			}
601
 
602
			var tipObj = tooltip.get('node');
603
			if (tooltip.get('closeAction') == 'hide')
604
			{
605
				var fade = tooltip.get('fade');
606
				if (fade != 'neither')
607
				{
608
					var fadeHandler = tooltip.get('fadeHandler');
609
					if (fade == 'out' || fade == 'both')
610
					{
611
						fadeHandler.pause();
612
						fadeHandler.fadeOut();
613
					}
614
					else
615
					{
616
						fadeHandler.stop();
617
					}
618
				}
619
				else
620
				{
621
					tipObj.style.display = 'none';
622
				}
623
			}
624
			else
625
			{
626
				tooltip.get('parent').removeChild(tipObj);
627
				domTT_tooltips.remove(in_ownerId);
628
			}
629
 
630
			tooltip.set('status', 'inactive');
631
			// unhide all of the selects that are owned by this object
632
			domLib_detectCollisions(tipObj, true); 
633
		}
634
	}
635
}
636
 
637
// }}}
638
// {{{ domTT_mouseout()
639
 
640
function domTT_mouseout(in_owner, in_event)
641
{
642
	if (!domLib_useLibrary) { return false; }
643
 
644
	if (typeof(in_event) == 'undefined')
645
	{
646
		in_event = event;
647
	}
648
 
649
	var toChild = domLib_isDescendantOf(in_event[domLib_eventTo], in_owner);
650
	var tooltip = domTT_tooltips.get(in_owner.id);
651
	if (tooltip && (tooltip.get('type') == 'greasy' || tooltip.get('status') != 'active'))
652
	{
653
		// deactivate tip if exists and we moved away from the owner
654
		if (!toChild)
655
		{
656
			domTT_deactivate(in_owner.id);
657
		}
658
	}
659
	else if (!toChild)
660
	{
661
		try { window.status = window.defaultStatus; } catch(e) {}
662
	}
663
}
664
 
665
// }}}
666
// {{{ domTT_mousemove()
667
 
668
function domTT_mousemove(in_owner, in_event)
669
{
670
	if (!domLib_useLibrary) { return false; }
671
 
672
	if (typeof(in_event) == 'undefined')
673
	{
674
		in_event = event;
675
	}
676
 
677
	var tooltip = domTT_tooltips.get(in_owner.id);
678
	if (tooltip && tooltip.get('trail') && tooltip.get('status') == 'active')
679
	{
680
		domTT_show(in_owner.id, in_event);
681
	}
682
}
683
 
684
// }}}
685
// {{{ domTT_addPredefined()
686
 
687
function domTT_addPredefined(in_id)
688
{
689
	var options = new Hash();
690
	for (var i = 1; i < arguments.length; i += 2)
691
	{
692
		options.set(arguments[i], arguments[i + 1]);
693
	}
694
 
695
	domTT_predefined.set(in_id, options);
696
}
697
 
698
// }}}
699
// {{{ domTT_correctEdgeBleed()
700
 
701
function domTT_correctEdgeBleed(in_width, in_height, in_x, in_y, in_offsetX, in_offsetY, in_type)
702
{
703
	var bleedRight;
704
	var bleedBottom;
705
	// for IE in compliance mode, maybe others
706
	if (document.documentElement.clientHeight)
707
	{
708
		var pageHeight = document.documentElement.clientHeight;
709
		var pageWidth = document.documentElement.clientWidth;
710
		var pageYOffset = document.documentElement.scrollTop;
711
		var pageXOffset = document.documentElement.scrollLeft;
712
	}
713
	else
714
	{
715
		var pageWidth = document.body.clientWidth;
716
		var pageYOffset = window.pageYOffset;
717
		var pageXOffset = window.pageXOffset;
718
		if (domLib_isKonq)
719
		{
720
			var pageHeight = window.innerHeight;
721
		}
722
		else
723
		{
724
			var pageHeight = document.body.clientHeight;
725
		}
726
	}
727
 
728
	// we are bleeding off the right, move tip over to stay on page
729
	if ((bleedRight = (in_x - pageXOffset) + in_width - (pageWidth - domTT_screenEdgePadding)) > 0)
730
	{
731
		in_x -= bleedRight;
732
	}
733
 
734
	// we are bleeding to the left, move tip over to stay on page
735
	// we don't want an 'else if' here, because if it doesn't fit we will bleed off the right
736
	if ((in_x - pageXOffset) < domTT_screenEdgePadding)
737
	{
738
		in_x = domTT_screenEdgePadding + pageXOffset;
739
	}
740
 
741
	// ** top/bottom corrections depends on type, because we can't end up with the mouse over
742
	// the tip if this is a greasy **
743
	// if we are bleeding off the bottom, flip to north
744
	if ((bleedBottom = (in_y - pageYOffset) + in_height - (pageHeight - domTT_screenEdgePadding)) > 0) {
745
		if (in_type == 'sticky') {
746
			in_y -= bleedBottom;
747
		}
748
		else
749
		{
750
			in_y -= in_height + (2 * in_offsetY) + domTT_mouseHeight;
751
		}
752
	}
753
 
754
	// if we are bleeding off the top, flip to south
755
	// we don't want an 'else if' here, because if we just can't fit it, bleed off the bottom
756
	if ((in_y - pageYOffset) < domTT_screenEdgePadding)
757
	{
758
		if (in_type == 'sticky')
759
		{
760
			in_y = domTT_screenEdgePadding + pageYOffset;
761
		}
762
		else
763
		{
764
			in_y += in_height + (2 * in_offsetY) + domTT_mouseHeight;
765
		}
766
	}
767
 
768
	return {'x' : in_x, 'y' : in_y};
769
}
770
 
771
// }}}
772
// {{{ domTT_isActive()
773
 
774
function domTT_isActive(in_ownerId)
775
{
776
	var tooltip = domTT_tooltips.get(in_ownerId);
777
	if (!tooltip || tooltip.get('status') != 'active')
778
	{
779
		return false;
780
	}
781
	else
782
	{
783
		return true;
784
	}
785
}
786
 
787
// }}}