Subversion Repositories Applications.papyrus

Compare Revisions

Ignore whitespace Rev 1264 → Rev 1265

/trunk/api/js/domtooltip/BUGS
New file
0,0 → 1,16
$Id: BUGS,v 1.1 2007-03-16 12:39:35 jp_milcent Exp $
These are the known bugs/issues in the DOM Tooltip library:
 
- Opera7 popups up a native tooltip title for the link, which goes over the custom tooltip
(all you need to do is disable tooltips in the opera preferences)
 
- you cannot use the margin style on the body in Opera7, you have to use padding instead
you can read over at opera.com why they don't support this...apparently not a legit style
 
- offset* properties do not account for margins, so styles with margins could lead to issues
 
- fading in and fading out in mozilla is somewhat flaky...it works but has flickering...this
flickering is NOT the tooltip code, it is the rendering of the styles in mozilla...only time
will help us here (this seems to be resolved in Firefox 1.0)
 
- inframe tips do not appear over top of the iframe in Opera and Konqueror
/trunk/api/js/domtooltip/domLib.js
New file
0,0 → 1,706
/** $Id: domLib.js,v 1.1 2007-03-16 12:39:35 jp_milcent Exp $ */
// {{{ license
 
/*
* Copyright 2002-2005 Dan Allen, Mojavelinux.com (dan.allen@mojavelinux.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
 
// }}}
// {{{ intro
 
/**
* Title: DOM Library Core
* Version: 0.70
*
* Summary:
* A set of commonly used functions that make it easier to create javascript
* applications that rely on the DOM.
*
* Updated: 2005/05/17
*
* Maintainer: Dan Allen <dan.allen@mojavelinux.com>
* Maintainer: Jason Rust <jrust@rustyparts.com>
*
* License: Apache 2.0
*/
 
// }}}
// {{{ global constants (DO NOT EDIT)
 
// -- Browser Detection --
var domLib_userAgent = navigator.userAgent.toLowerCase();
var domLib_isMac = navigator.appVersion.indexOf('Mac') != -1;
var domLib_isWin = domLib_userAgent.indexOf('windows') != -1;
// NOTE: could use window.opera for detecting Opera
var domLib_isOpera = domLib_userAgent.indexOf('opera') != -1;
var domLib_isOpera7up = domLib_userAgent.match(/opera.(7|8)/i);
var domLib_isSafari = domLib_userAgent.indexOf('safari') != -1;
var domLib_isKonq = domLib_userAgent.indexOf('konqueror') != -1;
// Both konqueror and safari use the khtml rendering engine
var domLib_isKHTML = (domLib_isKonq || domLib_isSafari || domLib_userAgent.indexOf('khtml') != -1);
var domLib_isIE = (!domLib_isKHTML && !domLib_isOpera && (domLib_userAgent.indexOf('msie 5') != -1 || domLib_userAgent.indexOf('msie 6') != -1 || domLib_userAgent.indexOf('msie 7') != -1));
var domLib_isIE5up = domLib_isIE;
var domLib_isIE50 = (domLib_isIE && domLib_userAgent.indexOf('msie 5.0') != -1);
var domLib_isIE55 = (domLib_isIE && domLib_userAgent.indexOf('msie 5.5') != -1);
var domLib_isIE5 = (domLib_isIE50 || domLib_isIE55);
// safari and konq may use string "khtml, like gecko", so check for destinctive /
var domLib_isGecko = domLib_userAgent.indexOf('gecko/') != -1;
var domLib_isMacIE = (domLib_isIE && domLib_isMac);
var domLib_isIE55up = domLib_isIE5up && !domLib_isIE50 && !domLib_isMacIE;
var domLib_isIE6up = domLib_isIE55up && !domLib_isIE55;
 
// -- Browser Abilities --
var domLib_standardsMode = (document.compatMode && document.compatMode == 'CSS1Compat');
var domLib_useLibrary = (domLib_isOpera7up || domLib_isKHTML || domLib_isIE5up || domLib_isGecko || domLib_isMacIE || document.defaultView);
// fixed in Konq3.2
var domLib_hasBrokenTimeout = (domLib_isMacIE || (domLib_isKonq && domLib_userAgent.match(/konqueror\/3.([2-9])/) == null));
var domLib_canFade = (domLib_isGecko || domLib_isIE || domLib_isSafari || domLib_isOpera);
var domLib_canDrawOverSelect = (domLib_isMac || domLib_isOpera || domLib_isGecko);
var domLib_canDrawOverFlash = (domLib_isMac || domLib_isWin);
 
// -- Event Variables --
var domLib_eventTarget = domLib_isIE ? 'srcElement' : 'currentTarget';
var domLib_eventButton = domLib_isIE ? 'button' : 'which';
var domLib_eventTo = domLib_isIE ? 'toElement' : 'relatedTarget';
var domLib_stylePointer = domLib_isIE ? 'hand' : 'pointer';
// NOTE: a bug exists in Opera that prevents maxWidth from being set to 'none', so we make it huge
var domLib_styleNoMaxWidth = domLib_isOpera ? '10000px' : 'none';
var domLib_hidePosition = '-1000px';
var domLib_scrollbarWidth = 14;
var domLib_autoId = 1;
var domLib_zIndex = 100;
 
// -- Detection --
var domLib_collisionElements;
var domLib_collisionsCached = false;
 
var domLib_timeoutStateId = 0;
var domLib_timeoutStates = new Hash();
 
// }}}
// {{{ DOM enhancements
 
if (!document.ELEMENT_NODE)
{
document.ELEMENT_NODE = 1;
document.ATTRIBUTE_NODE = 2;
document.TEXT_NODE = 3;
document.DOCUMENT_NODE = 9;
document.DOCUMENT_FRAGMENT_NODE = 11;
}
 
function domLib_clone(obj)
{
var copy = {};
for (var i in obj)
{
var value = obj[i];
try
{
if (value != null && typeof(value) == 'object' && value != window && !value.nodeType)
{
copy[i] = domLib_clone(value);
}
else
{
copy[i] = value;
}
}
catch(e)
{
copy[i] = value;
}
}
 
return copy;
}
 
// }}}
// {{{ class Hash()
 
function Hash()
{
this.length = 0;
this.numericLength = 0;
this.elementData = [];
for (var i = 0; i < arguments.length; i += 2)
{
if (typeof(arguments[i + 1]) != 'undefined')
{
this.elementData[arguments[i]] = arguments[i + 1];
this.length++;
if (arguments[i] == parseInt(arguments[i]))
{
this.numericLength++;
}
}
}
}
 
// using prototype as opposed to inner functions saves on memory
Hash.prototype.get = function(in_key)
{
if (typeof(this.elementData[in_key]) != 'undefined') {
return this.elementData[in_key];
}
 
return null;
}
 
Hash.prototype.set = function(in_key, in_value)
{
if (typeof(in_value) != 'undefined')
{
if (typeof(this.elementData[in_key]) == 'undefined')
{
this.length++;
if (in_key == parseInt(in_key))
{
this.numericLength++;
}
}
 
return this.elementData[in_key] = in_value;
}
 
return false;
}
 
Hash.prototype.remove = function(in_key)
{
var tmp_value;
if (typeof(this.elementData[in_key]) != 'undefined')
{
this.length--;
if (in_key == parseInt(in_key))
{
this.numericLength--;
}
 
tmp_value = this.elementData[in_key];
delete this.elementData[in_key];
}
 
return tmp_value;
}
 
Hash.prototype.size = function()
{
return this.length;
}
 
Hash.prototype.has = function(in_key)
{
return typeof(this.elementData[in_key]) != 'undefined';
}
 
Hash.prototype.find = function(in_obj)
{
for (var tmp_key in this.elementData)
{
if (this.elementData[tmp_key] == in_obj)
{
return tmp_key;
}
}
 
return null;
}
 
Hash.prototype.merge = function(in_hash)
{
for (var tmp_key in in_hash.elementData)
{
if (typeof(this.elementData[tmp_key]) == 'undefined')
{
this.length++;
if (tmp_key == parseInt(tmp_key))
{
this.numericLength++;
}
}
 
this.elementData[tmp_key] = in_hash.elementData[tmp_key];
}
}
 
Hash.prototype.compare = function(in_hash)
{
if (this.length != in_hash.length)
{
return false;
}
 
for (var tmp_key in this.elementData)
{
if (this.elementData[tmp_key] != in_hash.elementData[tmp_key])
{
return false;
}
}
return true;
}
 
// }}}
// {{{ domLib_isDescendantOf()
 
function domLib_isDescendantOf(in_object, in_ancestor, in_bannedTags)
{
if (in_object == null)
{
return false;
}
 
if (in_object == in_ancestor)
{
return true;
}
 
if (typeof(in_bannedTags) != 'undefined' &&
(',' + in_bannedTags.join(',') + ',').indexOf(',' + in_object.tagName + ',') != -1)
{
return false;
}
 
while (in_object != document.documentElement)
{
try
{
if ((tmp_object = in_object.offsetParent) && tmp_object == in_ancestor)
{
return true;
}
else if ((tmp_object = in_object.parentNode) == in_ancestor)
{
return true;
}
else
{
in_object = tmp_object;
}
}
// in case we get some wierd error, assume we left the building
catch(e)
{
return false;
}
}
 
return false;
}
 
// }}}
// {{{ domLib_detectCollisions()
 
/**
* For any given target element, determine if elements on the page
* are colliding with it that do not obey the rules of z-index.
*/
function domLib_detectCollisions(in_object, in_recover, in_useCache)
{
// the reason for the cache is that if the root menu is built before
// the page is done loading, then it might not find all the elements.
// so really the only time you don't use cache is when building the
// menu as part of the page load
if (!domLib_collisionsCached)
{
var tags = [];
 
if (!domLib_canDrawOverFlash)
{
tags[tags.length] = 'object';
}
 
if (!domLib_canDrawOverSelect)
{
tags[tags.length] = 'select';
}
 
domLib_collisionElements = domLib_getElementsByTagNames(tags, true);
domLib_collisionsCached = in_useCache;
}
 
// if we don't have a tip, then unhide selects
if (in_recover)
{
for (var cnt = 0; cnt < domLib_collisionElements.length; cnt++)
{
var thisElement = domLib_collisionElements[cnt];
 
if (!thisElement.hideList)
{
thisElement.hideList = new Hash();
}
 
thisElement.hideList.remove(in_object.id);
if (!thisElement.hideList.length)
{
domLib_collisionElements[cnt].style.visibility = 'visible';
if (domLib_isKonq)
{
domLib_collisionElements[cnt].style.display = '';
}
}
}
 
return;
}
else if (domLib_collisionElements.length == 0)
{
return;
}
 
// okay, we have a tip, so hunt and destroy
var objectOffsets = domLib_getOffsets(in_object);
 
for (var cnt = 0; cnt < domLib_collisionElements.length; cnt++)
{
var thisElement = domLib_collisionElements[cnt];
 
// if collision element is in active element, move on
// WARNING: is this too costly?
if (domLib_isDescendantOf(thisElement, in_object))
{
continue;
}
 
// konqueror only has trouble with multirow selects
if (domLib_isKonq &&
thisElement.tagName == 'SELECT' &&
(thisElement.size <= 1 && !thisElement.multiple))
{
continue;
}
 
if (!thisElement.hideList)
{
thisElement.hideList = new Hash();
}
 
var selectOffsets = domLib_getOffsets(thisElement);
var center2centerDistance = Math.sqrt(Math.pow(selectOffsets.get('leftCenter') - objectOffsets.get('leftCenter'), 2) + Math.pow(selectOffsets.get('topCenter') - objectOffsets.get('topCenter'), 2));
var radiusSum = selectOffsets.get('radius') + objectOffsets.get('radius');
// the encompassing circles are overlapping, get in for a closer look
if (center2centerDistance < radiusSum)
{
// tip is left of select
if ((objectOffsets.get('leftCenter') <= selectOffsets.get('leftCenter') && objectOffsets.get('right') < selectOffsets.get('left')) ||
// tip is right of select
(objectOffsets.get('leftCenter') > selectOffsets.get('leftCenter') && objectOffsets.get('left') > selectOffsets.get('right')) ||
// tip is above select
(objectOffsets.get('topCenter') <= selectOffsets.get('topCenter') && objectOffsets.get('bottom') < selectOffsets.get('top')) ||
// tip is below select
(objectOffsets.get('topCenter') > selectOffsets.get('topCenter') && objectOffsets.get('top') > selectOffsets.get('bottom')))
{
thisElement.hideList.remove(in_object.id);
if (!thisElement.hideList.length)
{
thisElement.style.visibility = 'visible';
if (domLib_isKonq)
{
thisElement.style.display = '';
}
}
}
else
{
thisElement.hideList.set(in_object.id, true);
thisElement.style.visibility = 'hidden';
if (domLib_isKonq)
{
thisElement.style.display = 'none';
}
}
}
}
}
 
// }}}
// {{{ domLib_getOffsets()
 
function domLib_getOffsets(in_object, in_preserveScroll)
{
if (typeof(in_preserveScroll) == 'undefined') {
in_preserveScroll = false;
}
 
var originalObject = in_object;
var originalWidth = in_object.offsetWidth;
var originalHeight = in_object.offsetHeight;
var offsetLeft = 0;
var offsetTop = 0;
 
while (in_object)
{
offsetLeft += in_object.offsetLeft;
offsetTop += in_object.offsetTop;
in_object = in_object.offsetParent;
// consider scroll offset of parent elements
if (in_object && !in_preserveScroll)
{
offsetLeft -= in_object.scrollLeft;
offsetTop -= in_object.scrollTop;
}
}
 
// MacIE misreports the offsets (even with margin: 0 in body{}), still not perfect
if (domLib_isMacIE) {
offsetLeft += 10;
offsetTop += 10;
}
 
return new Hash(
'left', offsetLeft,
'top', offsetTop,
'right', offsetLeft + originalWidth,
'bottom', offsetTop + originalHeight,
'leftCenter', offsetLeft + originalWidth/2,
'topCenter', offsetTop + originalHeight/2,
'radius', Math.max(originalWidth, originalHeight)
);
}
 
// }}}
// {{{ domLib_setTimeout()
 
function domLib_setTimeout(in_function, in_timeout, in_args)
{
if (typeof(in_args) == 'undefined')
{
in_args = [];
}
 
if (in_timeout == -1)
{
// timeout event is disabled
return 0;
}
else if (in_timeout == 0)
{
in_function(in_args);
return 0;
}
 
// must make a copy of the arguments so that we release the reference
var args = domLib_clone(in_args);
 
if (!domLib_hasBrokenTimeout)
{
return setTimeout(function() { in_function(args); }, in_timeout);
}
else
{
var id = domLib_timeoutStateId++;
var data = new Hash();
data.set('function', in_function);
data.set('args', args);
domLib_timeoutStates.set(id, data);
 
data.set('timeoutId', setTimeout('domLib_timeoutStates.get(' + id + ').get(\'function\')(domLib_timeoutStates.get(' + id + ').get(\'args\')); domLib_timeoutStates.remove(' + id + ');', in_timeout));
return id;
}
}
 
// }}}
// {{{ domLib_clearTimeout()
 
function domLib_clearTimeout(in_id)
{
if (!domLib_hasBrokenTimeout)
{
if (in_id > 0) {
clearTimeout(in_id);
}
}
else
{
if (domLib_timeoutStates.has(in_id))
{
clearTimeout(domLib_timeoutStates.get(in_id).get('timeoutId'))
domLib_timeoutStates.remove(in_id);
}
}
}
 
// }}}
// {{{ domLib_getEventPosition()
 
function domLib_getEventPosition(in_eventObj)
{
var eventPosition = new Hash('x', 0, 'y', 0, 'scrollX', 0, 'scrollY', 0);
 
// IE varies depending on standard compliance mode
if (domLib_isIE)
{
var doc = (domLib_standardsMode ? document.documentElement : document.body);
// NOTE: events may fire before the body has been loaded
if (doc)
{
eventPosition.set('x', in_eventObj.clientX + doc.scrollLeft);
eventPosition.set('y', in_eventObj.clientY + doc.scrollTop);
eventPosition.set('scrollX', doc.scrollLeft);
eventPosition.set('scrollY', doc.scrollTop);
}
}
else
{
eventPosition.set('x', in_eventObj.pageX);
eventPosition.set('y', in_eventObj.pageY);
eventPosition.set('scrollX', in_eventObj.pageX - in_eventObj.clientX);
eventPosition.set('scrollY', in_eventObj.pageY - in_eventObj.clientY);
}
 
return eventPosition;
}
 
// }}}
// {{{ domLib_cancelBubble()
 
function domLib_cancelBubble(in_event)
{
var eventObj = in_event ? in_event : window.event;
eventObj.cancelBubble = true;
}
 
// }}}
// {{{ domLib_getIFrameReference()
 
function domLib_getIFrameReference(in_frame)
{
if (domLib_isGecko || domLib_isIE)
{
return in_frame.frameElement;
}
else
{
// we could either do it this way or require an id on the frame
// equivalent to the name
var name = in_frame.name;
if (!name || !in_frame.parent)
{
return null;
}
 
var candidates = in_frame.parent.document.getElementsByTagName('iframe');
for (var i = 0; i < candidates.length; i++)
{
if (candidates[i].name == name)
{
return candidates[i];
}
}
 
return null;
}
}
 
// }}}
// {{{ domLib_getElementsByClass()
 
function domLib_getElementsByClass(in_class)
{
var elements = domLib_isIE5 ? document.all : document.getElementsByTagName('*');
var matches = [];
var cnt = 0;
for (var i = 0; i < elements.length; i++)
{
if ((" " + elements[i].className + " ").indexOf(" " + in_class + " ") != -1)
{
matches[cnt++] = elements[i];
}
}
 
return matches;
}
 
// }}}
// {{{ domLib_getElementsByTagNames()
 
function domLib_getElementsByTagNames(in_list, in_excludeHidden)
{
var elements = [];
for (var i = 0; i < in_list.length; i++)
{
var matches = document.getElementsByTagName(in_list[i]);
for (var j = 0; j < matches.length; j++)
{
// skip objects that have nested embeds, or else we get "flashing"
if (matches[j].tagName == 'OBJECT' && domLib_isGecko)
{
var kids = matches[j].childNodes;
var skip = false;
for (var k = 0; k < kids.length; k++)
{
if (kids[k].tagName == 'EMBED')
{
skip = true;
break;
}
}
if (skip) continue;
}
 
if (in_excludeHidden && domLib_getComputedStyle(matches[j], 'visibility') == 'hidden')
{
continue;
}
 
elements[elements.length] = matches[j];
}
}
 
return elements;
}
 
// }}}
// {{{ domLib_getComputedStyle()
 
function domLib_getComputedStyle(in_obj, in_property)
{
if (domLib_isIE)
{
var humpBackProp = in_property.replace(/-(.)/, function (a, b) { return b.toUpperCase(); });
return eval('in_obj.currentStyle.' + humpBackProp);
}
// getComputedStyle() is broken in konqueror, so let's go for the style object
else if (domLib_isKonq)
{
//var humpBackProp = in_property.replace(/-(.)/, function (a, b) { return b.toUpperCase(); });
return eval('in_obj.style.' + in_property);
}
else
{
return document.defaultView.getComputedStyle(in_obj, null).getPropertyValue(in_property);
}
}
 
// }}}
// {{{ makeTrue()
 
function makeTrue()
{
return true;
}
 
// }}}
// {{{ makeFalse()
 
function makeFalse()
{
return false;
}
 
// }}}
/trunk/api/js/domtooltip/LICENSE
New file
0,0 → 1,202
 
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
 
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 
1. Definitions.
 
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
 
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
 
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
 
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
 
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
 
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
 
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
 
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
 
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
 
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
 
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
 
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
 
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
 
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
 
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
 
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
 
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
 
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
 
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
 
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
 
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
 
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
 
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
 
END OF TERMS AND CONDITIONS
 
APPENDIX: How to apply the Apache License to your work.
 
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
 
Copyright [yyyy] [name of copyright owner]
 
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
 
http://www.apache.org/licenses/LICENSE-2.0
 
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
/trunk/api/js/domtooltip/domTT.js
New file
0,0 → 1,1132
/** $Id: domTT.js,v 1.1 2007-03-16 12:39:35 jp_milcent Exp $ */
// {{{ license
 
/*
* Copyright 2002-2005 Dan Allen, Mojavelinux.com (dan.allen@mojavelinux.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
 
// }}}
// {{{ intro
 
/**
* Title: DOM Tooltip Library
* Version: 0.7.3
*
* Summary:
* Allows developers to add custom tooltips to the webpages. Tooltips are
* generated using the domTT_activate() function and customized by setting
* a handful of options.
*
* Maintainer: Dan Allen <dan.allen@mojavelinux.com>
* Contributors:
* Josh Gross <josh@jportalhome.com>
* Jason Rust <jason@rustyparts.com>
*
* License: Apache 2.0
* However, if you use this library, you earn the position of official bug
* reporter :) Please post questions or problem reports to the newsgroup:
*
* http://groups-beta.google.com/group/dom-tooltip
*
* If you are doing this for commercial work, perhaps you could send me a few
* Starbucks Coffee gift dollars or PayPal bucks to encourage future
* developement (NOT REQUIRED). E-mail me for my snail mail address.
 
*
* Homepage: http://www.mojavelinux.com/projects/domtooltip/
*
* Newsgroup: http://groups-beta.google.com/group/dom-tooltip
*
* Freshmeat Project: http://freshmeat.net/projects/domtt/?topic_id=92
*
* Updated: 2005/07/16
*
* Supported Browsers:
* Mozilla (Gecko), IE 5.5+, IE on Mac, Safari, Konqueror, Opera 7
*
* Usage:
* Please see the HOWTO documentation.
**/
 
// }}}
// {{{ settings (editable)
 
// IE mouse events seem to be off by 2 pixels
var domTT_offsetX = (domLib_isIE ? -2 : 0);
var domTT_offsetY = (domLib_isIE ? 4 : 2);
var domTT_direction = 'southeast';
var domTT_mouseHeight = domLib_isIE ? 13 : 19;
var domTT_closeLink = 'X';
var domTT_closeAction = 'hide';
var domTT_activateDelay = 500;
var domTT_maxWidth = false;
var domTT_styleClass = 'domTT';
var domTT_fade = 'neither';
var domTT_lifetime = 0;
var domTT_grid = 0;
var domTT_trailDelay = 200;
var domTT_useGlobalMousePosition = true;
var domTT_postponeActivation = false;
var domTT_tooltipIdPrefix = '[domTT]';
var domTT_screenEdgeDetection = true;
var domTT_screenEdgePadding = 4;
var domTT_oneOnly = false;
var domTT_cloneNodes = false;
var domTT_detectCollisions = true;
var domTT_bannedTags = ['OPTION'];
var domTT_draggable = false;
if (typeof(domTT_dragEnabled) == 'undefined')
{
domTT_dragEnabled = false;
}
 
// }}}
// {{{ globals (DO NOT EDIT)
 
var domTT_predefined = new Hash();
// tooltips are keyed on both the tip id and the owner id,
// since events can originate on either object
var domTT_tooltips = new Hash();
var domTT_lastOpened = 0;
var domTT_documentLoaded = false;
var domTT_mousePosition = null;
 
// }}}
// {{{ document.onmousemove
 
if (domLib_useLibrary && domTT_useGlobalMousePosition)
{
document.onmousemove = function(in_event)
{
if (typeof(in_event) == 'undefined') { in_event = window.event; }
 
domTT_mousePosition = domLib_getEventPosition(in_event);
if (domTT_dragEnabled && domTT_dragMouseDown)
{
domTT_dragUpdate(in_event);
}
}
}
 
// }}}
// {{{ domTT_activate()
 
function domTT_activate(in_this, in_event)
{
if (!domLib_useLibrary || (domTT_postponeActivation && !domTT_documentLoaded)) { return false; }
 
// make sure in_event is set (for IE, some cases we have to use window.event)
if (typeof(in_event) == 'undefined') { in_event = window.event; }
 
// don't allow tooltips on banned tags (such as OPTION)
if (in_event != null) {
var target = in_event.srcElement ? in_event.srcElement : in_event.target;
if (target != null && (',' + domTT_bannedTags.join(',') + ',').indexOf(',' + target.tagName + ',') != -1)
{
return false;
}
}
 
var owner = document.body;
// we have an active event so get the owner
if (in_event != null && in_event.type.match(/key|mouse|click|contextmenu/i))
{
// make sure we have nothing higher than the body element
if (in_this.nodeType && in_this.nodeType != document.DOCUMENT_NODE)
{
owner = in_this;
}
}
// non active event (make sure we were passed a string id)
else
{
if (typeof(in_this) != 'object' && !(owner = domTT_tooltips.get(in_this)))
{
// NOTE: two steps to avoid "flashing" in gecko
var embryo = document.createElement('div');
owner = document.body.appendChild(embryo);
owner.style.display = 'none';
owner.id = in_this;
}
}
 
// make sure the owner has a unique id
if (!owner.id)
{
owner.id = '__autoId' + domLib_autoId++;
}
 
// see if we should only be opening one tip at a time
// NOTE: this is not "perfect" yet since it really steps on any other
// tip working on fade out or delayed close, but it get's the job done
if (domTT_oneOnly && domTT_lastOpened)
{
domTT_deactivate(domTT_lastOpened);
}
 
domTT_lastOpened = owner.id;
 
var tooltip = domTT_tooltips.get(owner.id);
if (tooltip)
{
if (tooltip.get('eventType') != in_event.type)
{
if (tooltip.get('type') == 'greasy')
{
tooltip.set('closeAction', 'destroy');
domTT_deactivate(owner.id);
}
else if (tooltip.get('status') != 'inactive')
{
return owner.id;
}
}
else
{
if (tooltip.get('status') == 'inactive')
{
tooltip.set('status', 'pending');
tooltip.set('activateTimeout', domLib_setTimeout(domTT_runShow, tooltip.get('delay'), [owner.id, in_event]));
 
return owner.id;
}
// either pending or active, let it be
else
{
return owner.id;
}
}
}
 
// setup the default options hash
var options = new Hash(
'caption', '',
'content', '',
'clearMouse', true,
'closeAction', domTT_closeAction,
'closeLink', domTT_closeLink,
'delay', domTT_activateDelay,
'direction', domTT_direction,
'draggable', domTT_draggable,
'fade', domTT_fade,
'fadeMax', 100,
'grid', domTT_grid,
'id', domTT_tooltipIdPrefix + owner.id,
'inframe', false,
'lifetime', domTT_lifetime,
'offsetX', domTT_offsetX,
'offsetY', domTT_offsetY,
'parent', document.body,
'position', 'absolute',
'styleClass', domTT_styleClass,
'type', 'greasy',
'trail', false,
'lazy', false
);
 
// load in the options from the function call
for (var i = 2; i < arguments.length; i += 2)
{
// load in predefined
if (arguments[i] == 'predefined')
{
var predefinedOptions = domTT_predefined.get(arguments[i + 1]);
for (var j in predefinedOptions.elementData)
{
options.set(j, predefinedOptions.get(j));
}
}
// set option
else
{
options.set(arguments[i], arguments[i + 1]);
}
}
 
options.set('eventType', in_event != null ? in_event.type : null);
 
// immediately set the status text if provided
if (options.has('statusText'))
{
try { window.status = options.get('statusText'); } catch(e) {}
}
 
// if we didn't give content...assume we just wanted to change the status and return
if (!options.has('content') || options.get('content') == '' || options.get('content') == null)
{
if (typeof(owner.onmouseout) != 'function')
{
owner.onmouseout = function(in_event) { domTT_mouseout(this, in_event); };
}
 
return owner.id;
}
 
options.set('owner', owner);
 
domTT_create(options);
 
// determine the show delay
options.set('delay', (in_event != null && in_event.type.match(/click|mousedown|contextmenu/i)) ? 0 : parseInt(options.get('delay')));
domTT_tooltips.set(owner.id, options);
domTT_tooltips.set(options.get('id'), options);
options.set('status', 'pending');
options.set('activateTimeout', domLib_setTimeout(domTT_runShow, options.get('delay'), [owner.id, in_event]));
 
return owner.id;
}
 
// }}}
// {{{ domTT_create()
 
function domTT_create(in_options)
{
var tipOwner = in_options.get('owner');
var parentObj = in_options.get('parent');
var parentDoc = parentObj.ownerDocument || parentObj.document;
 
// create the tooltip and hide it
// NOTE: two steps to avoid "flashing" in gecko
var embryo = parentDoc.createElement('div');
var tipObj = parentObj.appendChild(embryo);
tipObj.style.position = 'absolute';
tipObj.style.left = '0px';
tipObj.style.top = '0px';
tipObj.style.visibility = 'hidden';
tipObj.id = in_options.get('id');
tipObj.className = in_options.get('styleClass');
 
var contentBlock;
var tableLayout = false;
 
if (in_options.get('caption') || (in_options.get('type') == 'sticky' && in_options.get('caption') !== false))
{
tableLayout = true;
// layout the tip with a hidden formatting table
var tipLayoutTable = tipObj.appendChild(parentDoc.createElement('table'));
tipLayoutTable.style.borderCollapse = 'collapse';
if (domLib_isKHTML)
{
tipLayoutTable.cellSpacing = 0;
}
 
var tipLayoutTbody = tipLayoutTable.appendChild(parentDoc.createElement('tbody'));
 
var numCaptionCells = 0;
var captionRow = tipLayoutTbody.appendChild(parentDoc.createElement('tr'));
var captionCell = captionRow.appendChild(parentDoc.createElement('td'));
captionCell.style.padding = '0px';
var caption = captionCell.appendChild(parentDoc.createElement('div'));
caption.className = 'caption';
if (domLib_isIE50)
{
caption.style.height = '100%';
}
 
if (in_options.get('caption').nodeType)
{
caption.appendChild(domTT_cloneNodes ? in_options.get('caption').cloneNode(1) : in_options.get('caption'));
}
else
{
caption.innerHTML = in_options.get('caption');
}
 
if (in_options.get('type') == 'sticky')
{
var numCaptionCells = 2;
var closeLinkCell = captionRow.appendChild(parentDoc.createElement('td'));
closeLinkCell.style.padding = '0px';
var closeLink = closeLinkCell.appendChild(parentDoc.createElement('div'));
closeLink.className = 'caption';
if (domLib_isIE50)
{
closeLink.style.height = '100%';
}
 
closeLink.style.textAlign = 'right';
closeLink.style.cursor = domLib_stylePointer;
// merge the styles of the two cells
closeLink.style.borderLeftWidth = caption.style.borderRightWidth = '0px';
closeLink.style.paddingLeft = caption.style.paddingRight = '0px';
closeLink.style.marginLeft = caption.style.marginRight = '0px';
if (in_options.get('closeLink').nodeType)
{
closeLink.appendChild(in_options.get('closeLink').cloneNode(1));
}
else
{
closeLink.innerHTML = in_options.get('closeLink');
}
 
closeLink.onclick = function()
{
domTT_deactivate(tipOwner.id);
};
closeLink.onmousedown = function(in_event)
{
if (typeof(in_event) == 'undefined') { in_event = window.event; }
in_event.cancelBubble = true;
};
// MacIE has to have a newline at the end and must be made with createTextNode()
if (domLib_isMacIE)
{
closeLinkCell.appendChild(parentDoc.createTextNode("\n"));
}
}
 
// MacIE has to have a newline at the end and must be made with createTextNode()
if (domLib_isMacIE)
{
captionCell.appendChild(parentDoc.createTextNode("\n"));
}
 
var contentRow = tipLayoutTbody.appendChild(parentDoc.createElement('tr'));
var contentCell = contentRow.appendChild(parentDoc.createElement('td'));
contentCell.style.padding = '0px';
if (numCaptionCells)
{
if (domLib_isIE || domLib_isOpera)
{
contentCell.colSpan = numCaptionCells;
}
else
{
contentCell.setAttribute('colspan', numCaptionCells);
}
}
 
contentBlock = contentCell.appendChild(parentDoc.createElement('div'));
if (domLib_isIE50)
{
contentBlock.style.height = '100%';
}
}
else
{
contentBlock = tipObj.appendChild(parentDoc.createElement('div'));
}
 
contentBlock.className = 'contents';
 
var content = in_options.get('content');
// allow content has a function to return the actual content
if (typeof(content) == 'function') {
content = content(in_options.get('id'));
}
 
if (content != null && content.nodeType)
{
contentBlock.appendChild(domTT_cloneNodes ? content.cloneNode(1) : content);
}
else
{
contentBlock.innerHTML = content;
}
 
// adjust the width if specified
if (in_options.has('width'))
{
tipObj.style.width = parseInt(in_options.get('width')) + 'px';
}
 
// check if we are overridding the maxWidth
// if the browser supports maxWidth, the global setting will be ignored (assume stylesheet)
var maxWidth = domTT_maxWidth;
if (in_options.has('maxWidth'))
{
if ((maxWidth = in_options.get('maxWidth')) === false)
{
tipObj.style.maxWidth = domLib_styleNoMaxWidth;
}
else
{
maxWidth = parseInt(in_options.get('maxWidth'));
tipObj.style.maxWidth = maxWidth + 'px';
}
}
 
// HACK: fix lack of maxWidth in CSS for KHTML and IE
if (maxWidth !== false && (domLib_isIE || domLib_isKHTML) && tipObj.offsetWidth > maxWidth)
{
tipObj.style.width = maxWidth + 'px';
}
 
in_options.set('offsetWidth', tipObj.offsetWidth);
in_options.set('offsetHeight', tipObj.offsetHeight);
 
// konqueror miscalcuates the width of the containing div when using the layout table based on the
// border size of the containing div
if (domLib_isKonq && tableLayout && !tipObj.style.width)
{
var left = document.defaultView.getComputedStyle(tipObj, '').getPropertyValue('border-left-width');
var right = document.defaultView.getComputedStyle(tipObj, '').getPropertyValue('border-right-width');
left = left.substring(left.indexOf(':') + 2, left.indexOf(';'));
right = right.substring(right.indexOf(':') + 2, right.indexOf(';'));
var correction = 2 * ((left ? parseInt(left) : 0) + (right ? parseInt(right) : 0));
tipObj.style.width = (tipObj.offsetWidth - correction) + 'px';
}
 
// if a width is not set on an absolutely positioned object, both IE and Opera
// will attempt to wrap when it spills outside of body...we cannot have that
if (domLib_isIE || domLib_isOpera)
{
if (!tipObj.style.width)
{
// HACK: the correction here is for a border
tipObj.style.width = (tipObj.offsetWidth - 2) + 'px';
}
 
// HACK: the correction here is for a border
tipObj.style.height = (tipObj.offsetHeight - 2) + 'px';
}
 
// store placement offsets from event position
var offsetX, offsetY;
 
// tooltip floats
if (in_options.get('position') == 'absolute' && !(in_options.has('x') && in_options.has('y')))
{
// determine the offset relative to the pointer
switch (in_options.get('direction'))
{
case 'northeast':
offsetX = in_options.get('offsetX');
offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY');
break;
case 'northwest':
offsetX = 0 - tipObj.offsetWidth - in_options.get('offsetX');
offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY');
break;
case 'north':
offsetX = 0 - parseInt(tipObj.offsetWidth/2);
offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY');
break;
case 'southwest':
offsetX = 0 - tipObj.offsetWidth - in_options.get('offsetX');
offsetY = in_options.get('offsetY');
break;
case 'southeast':
offsetX = in_options.get('offsetX');
offsetY = in_options.get('offsetY');
break;
case 'south':
offsetX = 0 - parseInt(tipObj.offsetWidth/2);
offsetY = in_options.get('offsetY');
break;
}
 
// if we are in an iframe, get the offsets of the iframe in the parent document
if (in_options.get('inframe'))
{
var iframeObj = domLib_getIFrameReference(window);
if (iframeObj)
{
var frameOffsets = domLib_getOffsets(iframeObj);
offsetX += frameOffsets.get('left');
offsetY += frameOffsets.get('top');
}
}
}
// tooltip is fixed
else
{
offsetX = 0;
offsetY = 0;
in_options.set('trail', false);
}
 
// set the direction-specific offsetX/Y
in_options.set('offsetX', offsetX);
in_options.set('offsetY', offsetY);
if (in_options.get('clearMouse') && in_options.get('direction').indexOf('south') != -1)
{
in_options.set('mouseOffset', domTT_mouseHeight);
}
else
{
in_options.set('mouseOffset', 0);
}
 
if (domLib_canFade && typeof(Fadomatic) == 'function')
{
if (in_options.get('fade') != 'neither')
{
var fadeHandler = new Fadomatic(tipObj, 10, 0, 0, in_options.get('fadeMax'));
in_options.set('fadeHandler', fadeHandler);
}
}
else
{
in_options.set('fade', 'neither');
}
 
// setup mouse events
if (in_options.get('trail') && typeof(tipOwner.onmousemove) != 'function')
{
tipOwner.onmousemove = function(in_event) { domTT_mousemove(this, in_event); };
}
 
if (typeof(tipOwner.onmouseout) != 'function')
{
tipOwner.onmouseout = function(in_event) { domTT_mouseout(this, in_event); };
}
 
if (in_options.get('type') == 'sticky')
{
if (in_options.get('position') == 'absolute' && domTT_dragEnabled && in_options.get('draggable'))
{
if (domLib_isIE)
{
captionRow.onselectstart = function() { return false; };
}
 
// setup drag
captionRow.onmousedown = function(in_event) { domTT_dragStart(tipObj, in_event); };
captionRow.onmousemove = function(in_event) { domTT_dragUpdate(in_event); };
captionRow.onmouseup = function() { domTT_dragStop(); };
}
}
else if (in_options.get('type') == 'velcro')
{
/* can use once we have deactivateDelay
tipObj.onmouseover = function(in_event)
{
if (typeof(in_event) == 'undefined') { in_event = window.event; }
var tooltip = domTT_tooltips.get(tipObj.id);
if (in_options.get('lifetime')) {
domLib_clearTimeout(in_options.get('lifetimeTimeout');
}
};
*/
tipObj.onmouseout = function(in_event)
{
if (typeof(in_event) == 'undefined') { in_event = window.event; }
if (!domLib_isDescendantOf(in_event[domLib_eventTo], tipObj, domTT_bannedTags)) {
domTT_deactivate(tipOwner.id);
}
};
// NOTE: this might interfere with links in the tip
tipObj.onclick = function(in_event)
{
domTT_deactivate(tipOwner.id);
};
}
 
if (in_options.get('position') == 'relative')
{
tipObj.style.position = 'relative';
}
 
in_options.set('node', tipObj);
in_options.set('status', 'inactive');
}
 
// }}}
// {{{ domTT_show()
 
// in_id is either tip id or the owner id
function domTT_show(in_id, in_event)
{
 
// should always find one since this call would be cancelled if tip was killed
var tooltip = domTT_tooltips.get(in_id);
var status = tooltip.get('status');
var tipObj = tooltip.get('node');
 
if (tooltip.get('position') == 'absolute')
{
var mouseX, mouseY;
 
if (tooltip.has('x') && tooltip.has('y'))
{
mouseX = tooltip.get('x');
mouseY = tooltip.get('y');
}
else if (!domTT_useGlobalMousePosition || domTT_mousePosition == null || status == 'active' || tooltip.get('delay') == 0)
{
var eventPosition = domLib_getEventPosition(in_event);
var eventX = eventPosition.get('x');
var eventY = eventPosition.get('y');
if (tooltip.get('inframe'))
{
eventX -= eventPosition.get('scrollX');
eventY -= eventPosition.get('scrollY');
}
 
// only move tip along requested trail axis when updating position
if (status == 'active' && tooltip.get('trail') !== true)
{
var trail = tooltip.get('trail');
if (trail == 'x')
{
mouseX = eventX;
mouseY = tooltip.get('mouseY');
}
else if (trail == 'y')
{
mouseX = tooltip.get('mouseX');
mouseY = eventY;
}
}
else
{
mouseX = eventX;
mouseY = eventY;
}
}
else
{
mouseX = domTT_mousePosition.get('x');
mouseY = domTT_mousePosition.get('y');
if (tooltip.get('inframe'))
{
mouseX -= domTT_mousePosition.get('scrollX');
mouseY -= domTT_mousePosition.get('scrollY');
}
}
 
// we are using a grid for updates
if (tooltip.get('grid'))
{
// if this is not a mousemove event or it is a mousemove event on an active tip and
// the movement is bigger than the grid
if (in_event.type != 'mousemove' || (status == 'active' && (Math.abs(tooltip.get('lastX') - mouseX) > tooltip.get('grid') || Math.abs(tooltip.get('lastY') - mouseY) > tooltip.get('grid'))))
{
tooltip.set('lastX', mouseX);
tooltip.set('lastY', mouseY);
}
// did not satisfy the grid movement requirement
else
{
return false;
}
}
 
// mouseX and mouseY store the last acknowleged mouse position,
// good for trailing on one axis
tooltip.set('mouseX', mouseX);
tooltip.set('mouseY', mouseY);
 
var coordinates;
if (domTT_screenEdgeDetection)
{
coordinates = domTT_correctEdgeBleed(
tooltip.get('offsetWidth'),
tooltip.get('offsetHeight'),
mouseX,
mouseY,
tooltip.get('offsetX'),
tooltip.get('offsetY'),
tooltip.get('mouseOffset'),
tooltip.get('inframe') ? window.parent : window
);
}
else
{
coordinates = {
'x' : mouseX + tooltip.get('offsetX'),
'y' : mouseY + tooltip.get('offsetY') + tooltip.get('mouseOffset')
};
}
 
// update the position
tipObj.style.left = coordinates.x + 'px';
tipObj.style.top = coordinates.y + 'px';
 
// increase the tip zIndex so it goes over previously shown tips
tipObj.style.zIndex = domLib_zIndex++;
}
 
// if tip is not active, active it now and check for a fade in
if (status == 'pending')
{
// unhide the tooltip
tooltip.set('status', 'active');
tipObj.style.display = '';
tipObj.style.visibility = 'visible';
 
var fade = tooltip.get('fade');
if (fade != 'neither')
{
var fadeHandler = tooltip.get('fadeHandler');
if (fade == 'out' || fade == 'both')
{
fadeHandler.haltFade();
if (fade == 'out')
{
fadeHandler.halt();
}
}
 
if (fade == 'in' || fade == 'both')
{
fadeHandler.fadeIn();
}
}
 
if (tooltip.get('type') == 'greasy' && tooltip.get('lifetime') != 0)
{
tooltip.set('lifetimeTimeout', domLib_setTimeout(domTT_runDeactivate, tooltip.get('lifetime'), [tipObj.id]));
}
}
 
if (tooltip.get('position') == 'absolute' && domTT_detectCollisions)
{
// utilize original collision element cache
domLib_detectCollisions(tipObj, false, true);
}
}
 
// }}}
// {{{ domTT_close()
 
// in_handle can either be an child object of the tip, the tip id or the owner id
function domTT_close(in_handle)
{
var id;
if (typeof(in_handle) == 'object' && in_handle.nodeType)
{
var obj = in_handle;
while (!obj.id || !domTT_tooltips.get(obj.id))
{
obj = obj.parentNode;
if (obj.nodeType != document.ELEMENT_NODE) { return; }
}
 
id = obj.id;
}
else
{
id = in_handle;
}
 
domTT_deactivate(id);
}
 
// }}}
// {{{ domTT_closeAll()
 
// run through the tooltips and close them all
function domTT_closeAll()
{
// NOTE: this will iterate 2x # of tooltips
for (var id in domTT_tooltips.elementData) {
domTT_close(id);
}
}
 
// }}}
// {{{ domTT_deactivate()
 
// in_id is either the tip id or the owner id
function domTT_deactivate(in_id)
{
var tooltip = domTT_tooltips.get(in_id);
if (tooltip)
{
var status = tooltip.get('status');
if (status == 'pending')
{
// cancel the creation of this tip if it is still pending
domLib_clearTimeout(tooltip.get('activateTimeout'));
tooltip.set('status', 'inactive');
}
else if (status == 'active')
{
if (tooltip.get('lifetime'))
{
domLib_clearTimeout(tooltip.get('lifetimeTimeout'));
}
 
var tipObj = tooltip.get('node');
if (tooltip.get('closeAction') == 'hide')
{
var fade = tooltip.get('fade');
if (fade != 'neither')
{
var fadeHandler = tooltip.get('fadeHandler');
if (fade == 'out' || fade == 'both')
{
fadeHandler.fadeOut();
}
else
{
fadeHandler.hide();
}
}
else
{
tipObj.style.display = 'none';
}
}
else
{
tooltip.get('parent').removeChild(tipObj);
domTT_tooltips.remove(tooltip.get('owner').id);
domTT_tooltips.remove(tooltip.get('id'));
}
 
tooltip.set('status', 'inactive');
if (domTT_detectCollisions) {
// unhide all of the selects that are owned by this object
// utilize original collision element cache
domLib_detectCollisions(tipObj, true, true);
}
}
}
}
 
// }}}
// {{{ domTT_mouseout()
 
function domTT_mouseout(in_owner, in_event)
{
if (!domLib_useLibrary) { return false; }
 
if (typeof(in_event) == 'undefined') { in_event = window.event; }
 
var toChild = domLib_isDescendantOf(in_event[domLib_eventTo], in_owner, domTT_bannedTags);
var tooltip = domTT_tooltips.get(in_owner.id);
if (tooltip && (tooltip.get('type') == 'greasy' || tooltip.get('status') != 'active'))
{
// deactivate tip if exists and we moved away from the owner
if (!toChild)
{
domTT_deactivate(in_owner.id);
try { window.status = window.defaultStatus; } catch(e) {}
}
}
else if (!toChild)
{
try { window.status = window.defaultStatus; } catch(e) {}
}
}
 
// }}}
// {{{ domTT_mousemove()
 
function domTT_mousemove(in_owner, in_event)
{
if (!domLib_useLibrary) { return false; }
 
if (typeof(in_event) == 'undefined') { in_event = window.event; }
 
var tooltip = domTT_tooltips.get(in_owner.id);
if (tooltip && tooltip.get('trail') && tooltip.get('status') == 'active')
{
// see if we are trailing lazy
if (tooltip.get('lazy'))
{
domLib_setTimeout(domTT_runShow, domTT_trailDelay, [in_owner.id, in_event]);
}
else
{
domTT_show(in_owner.id, in_event);
}
}
}
 
// }}}
// {{{ domTT_addPredefined()
 
function domTT_addPredefined(in_id)
{
var options = new Hash();
for (var i = 1; i < arguments.length; i += 2)
{
options.set(arguments[i], arguments[i + 1]);
}
 
domTT_predefined.set(in_id, options);
}
 
// }}}
// {{{ domTT_correctEdgeBleed()
 
function domTT_correctEdgeBleed(in_width, in_height, in_x, in_y, in_offsetX, in_offsetY, in_mouseOffset, in_window)
{
var win, doc;
var bleedRight, bleedBottom;
var pageHeight, pageWidth, pageYOffset, pageXOffset;
 
var x = in_x + in_offsetX;
var y = in_y + in_offsetY + in_mouseOffset;
 
win = (typeof(in_window) == 'undefined' ? window : in_window);
 
// Gecko and IE swaps values of clientHeight, clientWidth properties when
// in standards compliance mode from documentElement to document.body
doc = ((domLib_standardsMode && (domLib_isIE || domLib_isGecko)) ? win.document.documentElement : win.document.body);
 
// for IE in compliance mode
if (domLib_isIE)
{
pageHeight = doc.clientHeight;
pageWidth = doc.clientWidth;
pageYOffset = doc.scrollTop;
pageXOffset = doc.scrollLeft;
}
else
{
pageHeight = doc.clientHeight;
pageWidth = doc.clientWidth;
 
if (domLib_isKHTML)
{
pageHeight = win.innerHeight;
}
 
pageYOffset = win.pageYOffset;
pageXOffset = win.pageXOffset;
}
 
// we are bleeding off the right, move tip over to stay on page
// logic: take x position, add width and subtract from effective page width
if ((bleedRight = (x - pageXOffset) + in_width - (pageWidth - domTT_screenEdgePadding)) > 0)
{
x -= bleedRight;
}
 
// we are bleeding to the left, move tip over to stay on page
// if tip doesn't fit, we will go back to bleeding off the right
// logic: take x position and check if less than edge padding
if ((x - pageXOffset) < domTT_screenEdgePadding)
{
x = domTT_screenEdgePadding + pageXOffset;
}
 
// if we are bleeding off the bottom, flip to north
// logic: take y position, add height and subtract from effective page height
if ((bleedBottom = (y - pageYOffset) + in_height - (pageHeight - domTT_screenEdgePadding)) > 0)
{
y = in_y - in_height - in_offsetY;
}
 
// if we are bleeding off the top, flip to south
// if tip doesn't fit, we will go back to bleeding off the bottom
// logic: take y position and check if less than edge padding
if ((y - pageYOffset) < domTT_screenEdgePadding)
{
y = in_y + domTT_mouseHeight + in_offsetY;
}
 
return {'x' : x, 'y' : y};
}
 
// }}}
// {{{ domTT_isActive()
 
// in_id is either the tip id or the owner id
function domTT_isActive(in_id)
{
var tooltip = domTT_tooltips.get(in_id);
if (!tooltip || tooltip.get('status') != 'active')
{
return false;
}
else
{
return true;
}
}
 
// }}}
// {{{ domTT_runXXX()
 
// All of these domMenu_runXXX() methods are used by the event handling sections to
// avoid the circular memory leaks caused by inner functions
function domTT_runDeactivate(args) { domTT_deactivate(args[0]); }
function domTT_runShow(args) { domTT_show(args[0], args[1]); }
 
// }}}
// {{{ domTT_replaceTitles()
 
function domTT_replaceTitles(in_decorator)
{
var elements = domLib_getElementsByClass('tooltip');
for (var i = 0; i < elements.length; i++)
{
if (elements[i].title)
{
var content;
if (typeof(in_decorator) == 'function')
{
content = in_decorator(elements[i]);
}
else
{
content = elements[i].title;
}
 
content = content.replace(new RegExp('\'', 'g'), '\\\'');
elements[i].onmouseover = new Function('in_event', "domTT_activate(this, in_event, 'content', '" + content + "')");
elements[i].title = '';
}
}
}
 
// }}}
// {{{ domTT_update()
 
// Allow authors to update the contents of existing tips using the DOM
// Unfortunately, the tip must already exist, or else no work is done.
// TODO: make getting at content or caption cleaner
function domTT_update(handle, content, type)
{
// type defaults to 'content', can also be 'caption'
if (typeof(type) == 'undefined')
{
type = 'content';
}
 
var tip = domTT_tooltips.get(handle);
if (!tip)
{
return;
}
 
var tipObj = tip.get('node');
var updateNode;
if (type == 'content')
{
// <div class="contents">...
updateNode = tipObj.firstChild;
if (updateNode.className != 'contents')
{
// <table><tbody><tr>...</tr><tr><td><div class="contents">...
updateNode = updateNode.firstChild.firstChild.nextSibling.firstChild.firstChild;
}
}
else
{
updateNode = tipObj.firstChild;
if (updateNode.className == 'contents')
{
// missing caption
return;
}
 
// <table><tbody><tr><td><div class="caption">...
updateNode = updateNode.firstChild.firstChild.firstChild.firstChild;
}
 
// TODO: allow for a DOM node as content
updateNode.innerHTML = content;
}
 
// }}}
/trunk/api/js/domtooltip/fadomatic.js
New file
0,0 → 1,180
/** $Id: fadomatic.js,v 1.1 2007-03-16 12:39:35 jp_milcent Exp $ */
// Title: Fadomatic
// Version: 1.2
// Homepage: http://chimpen.com/fadomatic
// Author: Philip McCarthy <fadomatic@chimpen.com>
 
// Fade interval in milliseconds
// Make this larger if you experience performance issues
Fadomatic.INTERVAL_MILLIS = 50;
 
// Creates a fader
// element - The element to fade
// speed - The speed to fade at, from 0.0 to 100.0
// initialOpacity (optional, default 100) - element's starting opacity, 0 to 100
// minOpacity (optional, default 0) - element's minimum opacity, 0 to 100
// maxOpacity (optional, default 0) - element's minimum opacity, 0 to 100
function Fadomatic (element, rate, initialOpacity, minOpacity, maxOpacity) {
this._element = element;
this._intervalId = null;
this._rate = rate;
this._isFadeOut = true;
 
// Set initial opacity and bounds
// NB use 99 instead of 100 to avoid flicker at start of fade
this._minOpacity = 0;
this._maxOpacity = 99;
this._opacity = 99;
 
if (typeof minOpacity != 'undefined') {
if (minOpacity < 0) {
this._minOpacity = 0;
} else if (minOpacity > 99) {
this._minOpacity = 99;
} else {
this._minOpacity = minOpacity;
}
}
 
if (typeof maxOpacity != 'undefined') {
if (maxOpacity < 0) {
this._maxOpacity = 0;
} else if (maxOpacity > 99) {
this._maxOpacity = 99;
} else {
this._maxOpacity = maxOpacity;
}
 
if (this._maxOpacity < this._minOpacity) {
this._maxOpacity = this._minOpacity;
}
}
if (typeof initialOpacity != 'undefined') {
if (initialOpacity > this._maxOpacity) {
this._opacity = this._maxOpacity;
} else if (initialOpacity < this._minOpacity) {
this._opacity = this._minOpacity;
} else {
this._opacity = initialOpacity;
}
}
 
// See if we're using W3C opacity, MSIE filter, or just
// toggling visiblity
if(typeof element.style.opacity != 'undefined') {
 
this._updateOpacity = this._updateOpacityW3c;
 
} else if(typeof element.style.filter != 'undefined') {
 
// If there's not an alpha filter on the element already,
// add one
if (element.style.filter.indexOf("alpha") == -1) {
 
// Attempt to preserve existing filters
var existingFilters="";
if (element.style.filter) {
existingFilters = element.style.filter+" ";
}
element.style.filter = existingFilters+"alpha(opacity="+this._opacity+")";
}
 
this._updateOpacity = this._updateOpacityMSIE;
} else {
 
this._updateOpacity = this._updateVisibility;
}
 
this._updateOpacity();
}
 
// Initiates a fade out
Fadomatic.prototype.fadeOut = function () {
this._isFadeOut = true;
this._beginFade();
}
 
// Initiates a fade in
Fadomatic.prototype.fadeIn = function () {
this._isFadeOut = false;
this._beginFade();
}
 
// Makes the element completely opaque, stops any fade in progress
Fadomatic.prototype.show = function () {
this.haltFade();
this._opacity = this._maxOpacity;
this._updateOpacity();
}
 
// Makes the element completely transparent, stops any fade in progress
Fadomatic.prototype.hide = function () {
this.haltFade();
this._opacity = 0;
this._updateOpacity();
}
 
// Halts any fade in progress
Fadomatic.prototype.haltFade = function () {
 
clearInterval(this._intervalId);
}
 
// Resumes a fade where it was halted
Fadomatic.prototype.resumeFade = function () {
 
this._beginFade();
}
 
// Pseudo-private members
 
Fadomatic.prototype._beginFade = function () {
 
this.haltFade();
var objref = this;
this._intervalId = setInterval(function() { objref._tickFade(); },Fadomatic.INTERVAL_MILLIS);
}
 
Fadomatic.prototype._tickFade = function () {
 
if (this._isFadeOut) {
this._opacity -= this._rate;
if (this._opacity < this._minOpacity) {
this._opacity = this._minOpacity;
this.haltFade();
}
} else {
this._opacity += this._rate;
if (this._opacity > this._maxOpacity ) {
this._opacity = this._maxOpacity;
this.haltFade();
}
}
 
this._updateOpacity();
}
 
Fadomatic.prototype._updateVisibility = function () {
if (this._opacity > 0) {
this._element.style.visibility = 'visible';
} else {
this._element.style.visibility = 'hidden';
}
}
 
Fadomatic.prototype._updateOpacityW3c = function () {
this._element.style.opacity = this._opacity/100;
this._updateVisibility();
}
 
Fadomatic.prototype._updateOpacityMSIE = function () {
this._element.filters.alpha.opacity = this._opacity;
this._updateVisibility();
}
 
Fadomatic.prototype._updateOpacity = null;
/trunk/api/js/domtooltip/HOWTO.html
New file
0,0 → 1,160
<html>
<head>
<title>DOM Tooltip Library :: HOWTO</title>
<style type="text/css">
body
{
margin: 0;
padding: 10px;
font-size: .85em;
line-height: 1.3em;
}
dl
{
margin-left: 10px;
}
dt
{
font-weight: bold;
}
</style>
</head>
<body>
<h1>DOM Tooltip Library HOWTO</h1>
<h3>Usage</h3>
<p>This library offers a variety of ways to enable custom tooltips. The standard way of creating a tooltip is to add the domTT_activate() call to one of the event handlers of the target element. Tips can also be created programatically, which can be used for popping up inline windows. Another option is to call the method domTT_replaceTitles(), which replaces all elements containing the class 'tooltip' and the title attribute with a custom tooltip on mouseover.</p>
<h3>Examples</h3>
<pre>&lt;a href="index.html" onmouseover="domTT_activate(this, event, 'content', 'My first tooltip', 'trail', true);"&gt;sample link&lt;/a&gt;</pre>
<h3>Options</h3>
<p>The only required option to create a tooltip is the 'content' option. Most of the options below have a default value which is held in a global variable. If the option is specified, it overrides the default. The options are summarized below.</p>
<dl>
<dt>caption [text|xhtml|DOM Node]</dt>
<dd>An auto-generated caption will be created if this text is present. <strong>Set this to <code>false</code> when creating a sticky tip to prevent the automatic caption with close link.</strong></dd>
 
<dt>content [text|xhtml|DOM Node|function] (required)</dt>
<dd>The main content of the tip, which may be XHTML text. Note that when using a function, it is only called when the tip is activated, so it is necessary to use 'closeMethod' of 'destroy' to redraw each time.</dd>
 
<dt>clearMouse [boolean]</dt>
<dd>This option flags whether the tip should attempt to avoid the mouse when the direction is south.</dd>
 
<dt>closeAction ['hide'|'destroy']</dt>
<dd>Determines if the tip should be destroyed (removed from DOM) or just hidden when deactivated. (If fading is used, hiding is forced)</dd>
 
<dt>closeLink [text|xhtml|DOM Node]</dt>
<dd>The text that should be used for the auto-generated close link used for sticky tips.</dd>
 
<dt>delay [ms]</dt>
<dd>Time in milliseconds before the tip appears.</dd>
 
<dt>direction ['southeast'|'southwest'|'northeast'|'northwest'|'north'|'south']</dt>
<dd>The position of the tip relative to the mouse.</dd>
 
<dt>draggable [boolean]</dt>
<dd>Determines of the sticky tooltip can be dragged.</dd>
 
<dt>fade ['in'|'out'|'neither'|'both']</dt>
<dd>Sets the alpha effect when the tip is created or destroyed.</dd>
 
<dt>fadeMax [0-100]</dt>
<dd>Sets the maximum alpha that should be used for the alpha effect. (Minimum is always 0, or invisible)</dd>
 
<dt>grid [px]</dt>
<dd>Snaps the trailing to a grid, so that the tip only moves after a set number of pixels.</dd>
 
<dt>id [string]</dt>
<dd>The XML id that should be assigned to the tip. Using this setting allows for external manipulation of the tip.</dd>
 
<dt>inframe [boolean]</dt>
<dd>Hints that the tooltip is inside an iframe, so that the tip can be manipulated from the parent frame.</dd>
 
<dt>lifetime [ms]</dt>
<dd>The duration of time before the tooltip is automatically terminated, as long as it is still activated.</dd>
 
<dt>offsetX [px]</dt>
<dd>The left-to-right offset from the event where the tip should be placed.</dd>
 
<dt>offsetY [px]</dt>
<dd>The top-to-bottom offset from the event where the tip should be placed.</dd>
 
<dt>parent [DOM Node]</dt>
<dd>The parent node on which the tip should be appended. Usually used for tips with a relative position.</dd>
 
<dt>position ['absolute'|'relative'|'fixed']</dt>
<dd>The style position of the tip. (In most cases, the position is 'absolute')</dd>
 
<dt>predefined [string]</dt>
<dd>A reference to a previously defined tooltip using domTT_addPredefined()</dd>
 
<dt>statusText [string]</dt>
<dd>Sets the text to be used in the statusbar when the tip is activated. <strong>If used with mouseover, it is necessary to wrap the domTT_activate() call in 'return domTT_true()'.</strong></dd>
 
<dt>styleClass [string]</dt>
<dd>The class that will be assigned to the tip. The contents of the tip is assigned the class 'content' and the caption of the tip is assigned the class 'caption'.</dd>
 
<dt>type ['greasy'|'sticky'|'velcro']</dt>
<dd>Sets the fate of the tip. A greasy tip disappears when a mouse out occurs on owner. A sticky tip stays active until explicitly destroyed (a caption is also forced). A velcro tip disappears when a mouse out occurs on the tip itself.</dd>
 
<dt>trail [true|false|'x'|'y']</dt>
<dd>On which axis the tip should be updated when the mouse moves. A value of true updates on both axes.</dd>
 
<dt>lazy [boolean]</dt>
<dd>Whether or not to enable a delay when updating the mouse position of a trailing tip (drunk tooltip).</dd>
 
<dt>width [px]</dt>
<dd>A manual width for the tip.</dd>
 
<dt>maxWidth [px]</dt>
<dd>A manual maximum width for the tip. (In Firefox, this is controlled by the max-width style of the element)</dd>
 
<dt>x [px]</dt>
<dd>The absolute x position to be used for the tip location. This can be a calculated value, such as 'this.offsetLeft + 5'.</dd>
 
<dt>y [px]</dt>
<dd>The absolute y position to be used for the tip location. This can be a calculated value, such as 'this.offsetTop + 5'.</dd>
 
</dl>
<h3>Function Reference</h3>
<p>The DOM tooltip library offers a handful of functions, prefixed with 'domTT_', to aid in manipulating the tooltips. The following is a reference of these function calls.</p>
<dl>
<dt>domTT_activate()</dt>
<dd>The primary method for activating a tooltip, typically placed in an event handler such as <code>onmouseover</code>. The first two arguments must always be <code>this</code> and <code>event</code>, respectively. These two variable capture the environment on which to act. The rest of the arguments alternate between option name and option value from the list above.</dd>
<dt>domTT_addPredefined()</dt>
<dd>For times when tooltip creation should be seperated from activation, this method can be used to prepare the tooltips. The first argument is a unique name for the configuration, and the rest of the arguments alternate between option name and option value from the list of options above. A preconfigured tip can be reused any number of times, and the activate call can override options in the predefined configuration. A typical activate call for a predefined tooltip looks like: <code>domTT_activate(this, event, 'predefined', 'mytip')</code></dd>
<dt>domTT_close()</dt>
<dd>A more flexible alternative to <code>domTT_deactivate()</code>, this function assists in immediately closing the tooltip. The argument can either be a child object of the tip, the tip id or the owner id. From within a tooltip, the call is typically: <code>domTT_close(this)</code></dd>
<dt>domTT_deactivate()</dt>
<dd>In most cases, this method is automatically registered on the target element when <code>domTT_activate()</code> is first called. However, it may be necessary to programmatically close a tooltip. In this case, this method can be used. It requires one parameter, which can be the ID of the tooltip, the ID of the target or the target object itself.</dd>
<dt>domTT_mouseout()</dt>
<dd>When a tooltip is activate, it automatically registers a mouseout handler to close to tooltip unless one already exists. If you intend to have a custom mouseout handler on the target that activates the tip, you <strong><u>must</u></strong> make a <strong><u>call</u></strong> to <strong><code>domTT_mouseout(this, event)</code></strong> from within your mouseout handler. Otherwise, the tooltip will never be deactivated!</dd>
<dt>domTT_update()</dt>
<dd>If you find that you need to update the contents or caption of a tooltip after it has been created, you will find this function convenient. You must specify a tooltip id, target id or target node and new text or XHTML content and it will be used to replace the content of the existing tooltip. The third parameter allows you to specify either 'content' or 'caption', though it is optional and 'content' is the default.</dd>
<dt>makeTrue()/makeFalse()</dt>
<dd>These methods are indended soley for coaxing the return value of an event handler. Of times, it is necessary to return either true or false to the event handler, regardless of what the function in the handler might return. These methods will guarantee that result. For instance, the <code>onclick</code> handler must return false for a link or else the browser will follow the target href. Conversely, the handler must return true or else the browser will stall. These methods just help to achieve the desired behavior.</dd>
</dl>
<h3>Global Settings</h3>
<p>All of the options above can be used a global settings by prepending the 'domTT_' prefix. These assignments are a good way to establish common behaviors for your tooltips on the webpage. A couple of additional settings are documented here. <em>Be sure to include your custom values below the point when the domTT library is included so that they override the default values.</em></p>
<dl>
<dt>domTT_oneOnly</dt>
<dd>Set to this <code>true</code> to allow only one active tip at a time. When a tooltip is created, it will deactivate the last opened tooltip. You can access the last opened tooltip using the global variable domTT_lastOpened</dd>
<dt>fading</dt>
<dd>In order to use the fading feature, you must include the library fadomatic.js in your web page. See examples #5.</dd>
<dt>dragging</dt>
<dd>In order to drag tooltips, you must include the library domTT_drag.js in your web page. See example #4.</dd>
<dt>domTT_useGlobalMousePosition</dt>
<dd>This setting will allow domTT to register an event handler on the document to track the position of the mouse. Registering this event allows the trailing feature to behave more smoothly.</dd>
<dt>domTT_screenEdgeDetection</dt>
<dd>Enable the screen edge detection feature, which will prevent the tip from leaving the page. Setting this to <code>false</code> disables this feature.</dd>
<dt>domTT_screenEdgePadding</dt>
<dd>When using screen edge detection, this setting specifies how close to the edge the tip should be allowed to travel.</dd>
<dt>domTT_detectCollisions</dt>
<dd>If you would rather not having the select boxes and other interfering elements hidden when a visual collision is detected, you may turn off the functionality globally using this flag.</dd>
</dl>
<h3>Common Problems</h3>
<ul>
<li>If tips are not disappearing in low latency situations, use <code>onmouseover = domTT_deactivate(this.id);</code> to be sure it is discarded. (It seems, though, that a bug fix in 0.7.3 solved this problem.)</li>
<li>If the error 'operation aborted' is being thrown in IE, use the domTT_postponeActivation along with domTT_documentLoaded to prevent these types of page load problems.</li>
<li>To get dynamic updates on your tips using AJAX, you can either address the tip by its id, manipulate the node linked to the content, or use this domTT_update method. This point to remember is that the content is only processed when the tip is activated.</li>
<li>Disabled form fields do not have positions in the page. This prevents tooltips from being placed next to them. In order to use tooltips with form fields that are inactive, please use the onfocus="this.blur()" trick along with appropriate visual styling. In general, the disabled attribute causes other side-effects anyway.</li>
</ul>
</body>
</html>
/trunk/api/js/domtooltip/AUTHORS
New file
0,0 → 1,7
DOM Tooltip Library 0.70
 
Maintainer: Dan Allen <dan.allen@mojavelinux.com>
Contributors:
Josh Gross <josh@jportalhome.com>
Jason Rust <jason@rustyparts.com>
Vic Mackey <shield24@gmail.com>
/trunk/api/js/domtooltip/TODO
New file
0,0 → 1,205
$Id: TODO,v 1.1 2007-03-16 12:39:35 jp_milcent Exp $
 
TODO
----
[+] deactivate delay with appropriate timeout cancel handles (can then do the fancy work with velcro tip)
[+] use json for options to tip
[+] content can be a function, but until tip is destroyed, it isn't called again (call in domTT_show)
[+] option to use the DOM node rather than cloning for caption/content
[+] possible edge detection problem in Opera
 
[+] build a namespace for dom.lib dom.tt dom.menu or something
[+] doInDomTT() which would allow a function to be run when the tip is to be positioned
[+] issue a callback to fadomatic to destroy tip on fadeOut completion (allow the destory action for fading tips)
[+] make this domTT_runShow more clear as to what it is doing...maybe even
rework the timeout process we cannot allow for the timeout to hold onto any
object that might reference the DOM, else it won't get garbage collected
[+] think about creating a lightweight version that uses replaceTitles
 
[+] create addEvent() function for posting global events
 
[+] lazy trailing broken in Opera
 
[+] maxWidth handling is a bit ugly
[+] maybe not show contents when dragging? (also resize of sticky tooltips)
[+] drag API / add snap to grid when dragging
 
THOUGHTS
--------
[+] make alpha settings a sub-object or array...so we can set: max, step, etc...
[+] a more smooth lazy trail should be implemented by not moving the full amount each time
[+] make cursor "move" if caption is draggable
[+] Konq and Opera don't allow tip to flow over IFRAME in example11...but the code is working
 
NOTES
-----
never use:
onmouseover = function(e) { ... } as it will create a circular reference because of the function definition
 
 
[1,2,3] array object
{'one' : 1, 'two' : 2} object
cannot use setTimeout() with anonymous function in IE 5.0 since it crashes the browser when you execute clearTimeout() following this call
in compliance mode, IE measures use document.documentElement for many of the document.body functions
Text node cannot have an event in IE, but it can in mozilla
IE bubbles by default, which means that the child nodes get the event before the offsetParent nodes
setting an event to null in mozilla does not remove events registered using addEventListener...but it does in IE.
IE 5.0* does not have the .*? functionality in regexp
bug in linux onmousedown causes onmouseout beforehand
on IE, if there is an onmousemove and onmouseover, both will fire onmouseover
 
// innerHTML the DOM way
var range = document.createRange();
range.selectNodeContents(document.body);
var fragment = range.createContextualFragment('<b>test</b>');
var tooltip = document.createElement('div');
tooltip.appendChild(fragment);
 
WHAT I AM NOT THRILLED ABOUT
----------------------------
- (mozilla keeps firing events after javascript functions have been unloaded
- when appending a tooltip to a table cell, the table seems to get stretched out
 
DONE
----
[@] delay firing tooltip events until page has loaded (fix IE bug)
[@] missing fade should still allow tip to close
[@] one tooltip at a time
[@] mousemove makes konqueror flip the tip up (was a konqueror bug, fixed in 3.2)
[@] IE not detecting bottom edge of browser
[@] created global constant for standards mode detection
[@] if position relative, don't append to parent until tip is done creating or else parent get's all screwed up
[@] show should not set left and top style if position relative
[@] incorrect use of pending...pending should be between inactive and active
[@] fade fails when mouseout while fading when fading in 'in' only
[@] fade in is VERY slow
[@] domTT_isActive awkward
[@] velcro not working right
[@] strange stuff going on when doing click to stick
[@] mouseover then mouseout still has issues (sticky tips)
[@] what if tooltip is inactive and domTT_activate() fires again
[@] fix the FIXME's
[@] change domTT_true and domTT_false to makeTrue() and makeFalse()
[@] fix fades
[@] drag not working
[@] put delay back in for IE 5.0/Konq
[@] mousemove update is overridden by the mouseover placement, firing at wrong time
[@] cut the use of writing onmouseout() if is specified, same with onmousemove (make automatic)
[@] get rid of the float and go with tables instead so we can cut code
[@] try to speed it up a bit
[@] create lite version for simpler cases
[@] make a domTT_deactivate() that the user can use to make his/her own onmouseout()
[@] check for standards compliance mode, make it work either way
[@] problem if select box is inside tooltip
[@] infinite recursion bug in konqueror when using onmouseover
[@] be able to specify unique id as option
[@] use callTimeout
[@] problem with the setTimeout calls when using mousemove...before the tooltip activates, many setTimeouts can be registered, but only one can be cancelled
[@] have domTT_deactivate take a tip id or a tip object
[@] possibly make use of 'this' in the drag functions
[@] fix onmouseout to work as expected
[@] show off the preserving of the onmouseout
[@] talk about the auto width in the demo (which overlib does not have)
[@] select detection does not account for visible sticky tooltips...for this we have to have a global hash of the open tips...then, when we are going to change the style of a select element to visible, we check the open tips and make sure it is not conflicting with any of them
[@] some demos not working in Konqueror
[@] maxWidth handling is a bit awkward
[@] velcro having a rough time in IE, and in mozilla linux, cannot mousedown before it closes
[@] use typeof() instead of this.undefined
[@] strip out the javascript code for reporting errors in the packaged file
[@] store onmouseout function in the eventTarget attribute?
[@] common function for placing the tip (show and create do this stuff)
[@] be able to specify the width
[@] make function for domTT_mouseout()
[@] think about window.status on Example 4, right link
[@] few places where I get the mouse_x/mouse_y when I don't need it (relative position)
[@] when doing onmouseout for a greasy, make sure we are not entering a child...hmmm
[@] make example for relative position
[@] make maxWidth of 0 ignored
[@] since we can specify parent, be able to specify relative position or something so that we can just have the tooltip expand into the container
[@] have makefile fill in the version
[@] if event target is documentElement, coax it to document.body
[@] cursor errors in IE 5.5
[@] we don't need domTT_defaultStatus, just use window.defaultStatus
[@] add option for lifetime to tip
[@] create demo for velcro
[@] snap to grid tooltip (problem is we need to determine the difference from where the tip is located now, and where we would put it next, not just the mouse position)
[@] be able to fade out on close
[@] mouseover tip functionality...be able to keep it open when you mouseover, maybe another type...velcro
[@] don't kill the onmouseout the existed on tip...try to just add the close (see foo.html)
[@] fixed position tooltip (maybe pass in coordinates)
[@] change domTT_deactivate attribute to domTT_destroy
[@] tip lifetime for onmouseover
[@] set prefix for each tooltip in example pages
[@] maybe creat a domTT_writeStatus() function to be used for onmouseover
[@] added domTT_false() for onclick events on links that open IFRAMES
[@] remove hardcoded -1000px for a setting
[@] make fade a passed in option
[@] fading tooltip
[@] check for valid browser and don't execute if not meet requirements
[@] opera7 does not hide contents of IFRAME when tooltip is hidden
[@] make domTT_defaultStatus option
[@] prevent dragging close element
[@] drag bug in Opera 7
[@] full Opera 7 support!
[@] try Opera 7
[@] function for detect screen edge?
[@] edge detection not account for scroll (messes up placement bigtime when scroll is in effect)
[@] if content is empty, need to bail on creating tip
[@] why oncontextmenu no deliver onclick
[@] add domTT_isActive()
[@] add option 'deactivate' to be 'hide' or 'destroy', important for embedded IFRAMES
[@] option not to have X for sticky, but put onclick on document
[@] maybe remove the restriction for onmouseover and let it happen as it will
[@] more options for predefined can come over to tip definition, overridden by those passed in
[@] release to dynamic drive ddsubmit@yahoo.com
[@] if you have onmouseover sticky, and you mouseover then leave, it doesn't kill tip
[@] variable for tipObj visibility state to prevent all the lookups
[@] be able to specify style prefix for different styles on different tips
[@] add addPredefined() function
[@] make only draggable from caption
[@] be able to turn off dragging of sticky tips
[@] cleaner call to domTT_show()
[@] screenshot for freshmeat
[@] custom close text
[@] full screen edge detection
[@] handle the mouse cursor height automatically
[@] prettier way to handle default options
[@] support for directional tips (extending west from mouse action instead of east)
[@] eventDelay should be set to 0 if onmousemove and visible so it updates right away
[@] make function for reappear, domTT_show()
[@] when mouseover, use most recent location of mouse position
[@] perhaps do type instead of 'sticky' true or false?
[@] collision detection shouldn't delay when doing mousemove/click and tip is visible
[@] adjustable delay for tip in options
[@] change in_options to options in domTT_activate
[@] drag in IE jumps when select domTTContent area
[@] mouseout in IE when sticky active makes select boxes come back, event when tooptip is over it
[@] X should not be a dragable part of tooltip
[@] function for get mouse event position
[@] domTT_detectCollisions should do the lines just above it
[@] be able to drag sticky
[@] have getPosition return all 4 coordinates
[@] konqueror support
[@] browser variables
[@] code for x and y is twice in the activate function
[@] when you fly in and then click on the object while the tip is being created, it bugs out
[@] another paramater to domTT_activate() whether to unhide selects
[@] domTT_deactivate to take object instead of id
[@] fix problem with onmousemove after onclick beating setTimeout(...,0) on windows
[@] after we use a sticky, and it is closed, mousemove no longer works
[@] if we are sticky, all events on the same object should be cancelled
[@] be able to do sticky on click when onmousemove is used for non-sticky
[@] hiding of select boxes is not subject to the delay that the tooltip is subject to
[@] do internal hash, from the arguments after event
[@] itemExists to hash
[@] account for scroll offset of page
[@] fix max-width for IE
[@] fix broken float right for IE
[@] fix e.target to event.srcElement for IE
[@] need delay on reappear from cache
[@] no delay for onclick
[@] implement zIndex so new tips can go over old tips
[@] cache tooltips created by using visibility style
[@] pass in options as Hash
[@] auto-assign onmouseout
[@] add ability to have sticky (x in caption...what if we don't have caption?)
/trunk/api/js/domtooltip/Changelog
New file
0,0 → 1,342
$Id: Changelog,v 1.1 2007-03-16 12:39:35 jp_milcent Exp $
DOM Tootip: Javascript tooltip generator
 
version 0.7.3 (SVN HEAD):
* added example integration with behaviour.js
* added domTT_postponeActivation option to workaround 'operation aborted' error
* added domTT_closeAll function to remove all tooltips on page
* 'content' option can now be a function to return the content
* make id prefix configurable
* close velcro tip by clicking on it
* allow tips to be created with no event (null value)
* allow disabling of collision detection
* fixed problem of tip not disappearing on rapid mouse movement
* fixed problem of using global mouse position before first mouse movement
* prevent tooltip events on banned tags, such as OPTION (for consistency)
* improvements to example14 to allow caption to render properly
 
version 0.7.2 (2006/04/12):
* added example to demonstrate custom positioning with a parent
* fixes in clear timeout made in domLib.js
* fixed a regression in the collision detection that left elements hidden
* content and caption are only cloned if domTT_cloneNodes is set to true, otherwise the reference is used
 
version 0.7.1 (2005/07/16):
 
* changed fading library from alphaAPI to fadomatic
* fixed problem with fade where links and buttons would become inactive
* fixed problem where tooltips would hang around if browser doesn't support fading
* released under Apache 2.0 license
* added example for dynamically updating tooltip content
* added method for updating tooltip content, domTT_update()
* enabled caption to be html or a DOM node
* removed the clone() prototype method in domLib to prevent conflicts with other libraries
* option to have only one tip show at a time
* fixed edge detection to be more precise
* added fadeMax as upper limit for an alpha fade-in
* fixed wrapping problem when tip nears edge in opera and IE
* replace domLib_isKonq with domLib_isKHTML
* added auto-generated tooltips from the title attribute for elements with class "tooltip"
* custom offsets can be set on a per-tip basis
* tips are now indexed on both tip id and owner id, for greater flexibility
* added a convenient method for use in custom close events, domTT_close()
* custom id can now be used for the tip for easy reference
* domTT_classPrefix is now domTT_styleClass, option classPrefix is now styleClass
* wrapper div for contents styled with generic class 'contents'
* wrapper for caption is now styled with generic class 'caption'
* make drag an optional parameter for tip to turn on/off dragging of sticky tips
* trail can now be either 'x' or 'y' which will lock trailing to a single axis
* added HOWTO
* updated all examples
 
version 0.7.0 (2004/11/10):
 
* Create tip on parent specified instead on document.body and then moving the tip in the DOM
* Added a standards mode detection, which was the root of edge bleed issues
* Added info in README about how to make the program smaller using jsmin
* Fixed memory leaks in IE caused by using inner functions
* Now works in Mac IE
* Tooltips can be created from a child iframe element
* IE 5.0 (Windows) removed from supported list of browsers
 
version 0.6.0 (2003/02/13):
 
* major rewrite (please consult this changelog and example for new requirements)
* made fading modular using alphaAPI (seperate file, alphaAPI.js)
* large gains in speed and compliance (fix Konq and IE 5 bugs)
* eliminate need for domTT_activate() in the mousemove event handler!!!
* new option 'trail' to specify tip to follow mouse movement (only for absolute)
* changed domTT_true/false() functions to makeTrue/false()!!!
* changed option 'status' option to 'statusText'!!!
* changed 'prefix' option to 'classPrefix'!!!
* changed 'close' option to 'closeAction'!!!
* made dragging of tips loadable (seperate file, domTT_drag.js)
* divided out common functions from domTT functions (seperate file, domLib.js)
* browser detection variables now prefixed with domLib_is*!!!
* to create an onload window, first option is unique id (no longer have 'id' option)
 
version 0.5.5 (2003/02/09):
 
* fixed major crashes in IE 5.0 (cannot use delays since setTimeout is buggy)
* fixed hideList error in all browsers
* fixed a bug on example10.html when using a popup
 
version 0.5.4 (2003/02/05):
 
* fixed a scroll offset problem when IE is in compatibility mode
* fixed problem where select box detection nixed element inside tooltip
 
version 0.5.3 (2003/01/29):
 
* fix misspelled document on like 971 in domTT.js
 
version 0.5.2 (2003/01/17):
 
* fix for document.documentElement.scrollTop for IE in standards compliance mode
 
version 0.5.1 (2002/12/19):
 
* implemented callTimeout() as an wrapper for setTimeout() for variable persistence
* konqueror can now implement delays for tips!!!
* konqueror can now handle tip lifetime!!!
* added workaround for some konqueror quirks
 
version 0.5.0 (2002/12/19):
 
* fixed invalid variable name tmp_offsetX...regression from fixes in 0.4.9
 
version 0.4.9 (2002/12/18):
 
* reworked domTT_deactivate() a bit
* can now specify an 'id' option on each tip to have multiple tips on one trigger
* fixed the activateTimeout process to rid of lingering bugs
* updated demos
 
version 0.4.8 (2002/12/11):
 
* fixed recursion bug
 
version 0.4.7 (2002/12/08):
 
* dragging of sticky tips in konqueror!!
* cleaned up the mouseout code a great deal and now it actually works as expected
* selects only appear again when all tooltips which hid them are cleared away!!!
* fixed IE javascript error caused by global onmousemove operating before page load
* simplified deactivate by putting code for unhide selects in detectCollisions()
* updated demos
 
version 0.4.6 (2002/12/07):
 
* eliminated unnecessary code in domTT_show()
* konqueror fixes (checks in wrong place, clientHeight problem)
* fixed onclick x, y measurement in konqueror
 
version 0.4.5 (2002/12/06):
 
* added maxWidth option (false to disable) and width option now independent
* added workaround for maxWidth bug in Opera
* switch to toggling display property to hide rather than using visibility hidden
* fixed error in IE 5.5 bypassing a safeguard and causing a javascript error
* fixed compliance error with IE 5.5 when executing IE hack for float
* fixed height calculation with IE 5.5 vs IE 6 (compliance difference)
* fixed case when hack IE code was executing under the wrong circumstances
* fixing small javascript errors
* totally block IE 5.0 until I can get to testing it
* demo fixes and cleanups
* fixed missing check for tip object existance in mouseout function
 
version 0.4.4 (2002/12/06):
 
* fixed onload problem in IE
 
version 0.4.3 (2002/12/05):
 
* code cleanups with strict compliance mozilla
* fixed so that using domTT_activate() can be used as an onload event
* closeLink will be interpreted as html (but note the link is automatically created)
 
version 0.4.2 (2002/12/05):
 
* fixed missing units in drag update
* fixed width calculation in IE in strict mode
* fix document.body.clientHeight -> document.documentElement.clientHeight (IE strict.dtd)
* catch permission errors in mozilla to write status text
 
version 0.4.1 (2002/12/05):
 
* forget to add contentEditable when made changed to domTT_create() in 0.4.0
* fixes to the domTT_isDescendantOf to exclude absolute elements
* fixed error in mozilla (tip was trying to be destroyed twice)
* fixed regexp bug in IE 5.01
* fixed link in demo for opera (example8.html)
* fixed javascript error in IE when triggerObj was #document
* fixed IE bug when contentEditable property was screwing up the height
* demo fixes
 
version 0.4.0 (2002/12/02):
 
* add required 'this' add the beginning of every domTT_activate() call
* prevent tip from disappearing when mouseout goes to child of target element
* tons of code cleanup dealing with onmouseout
* 'status' now clears after each mouseout, even if tip is sticky or velcro
* added 'width' option, which overides the global domTT_maxWidth (and the style)
* merged logic in create() and show() so that create() can use show() (normalize)
 
version 0.3.2 (2002/12/01):
 
* changed 'close' to 'closeLink' since it was confusing what it was
* added relative positioned tips (inline), added option 'position'
* maxWidth of 0 will be ignored
* fixed a fade bug when tooltip object exists (domTT_show())
* several other fade bugs fixed
 
version 0.3.1 (2002/12/01):
 
* 'caption' can be set to false to force it not to show, even when using 'type' sticky
* fixed error "Could not get cursor property" in IE5 because must use 'hand' not 'pointer'
* misspelled descendant
* cleaned up the preserving of onmouseout a ton
* 'caption' only has to be set to false if type is 'sticky', otherwise it can be left off
* updated demos
 
version 0.3.0 (2002/11/30):
 
* added global domTT_lifetime to set how long the tip stays alive when mouse is stationary
* added option 'lifetime' for each individual tip (0 for infinite)
* added fixed position tooltip option by passing in 'x' and 'y' as options
* changed hash method itemExists to hasItem to be DOM compliant
* perserve the onmouseout that existed on the target rather than just overwriting
* new type 'velcro', which disappears when you mouseout of the tooltip instead of target
* added ability to fade out and changed 'fade' option from boolean to in/out/both/neither
* added fade direction to the domTT_doFade() function to hande fade in both directions
* made a global variable for domTT_onClose, either 'hide' or 'remove'
* changed 'deactivate' option to 'onClose' which can be 'hide' or 'remove'
* added 'grid' option and domTT_grid global to snap to a grid on updates (0 for no grid)
* got rid of domTT_defaultStatus, just use window.defaultStatus for this value
* code cleanups
* demo addition and cleanups
 
version 0.2.3 (2002/11/27):
 
* added domTT_false() as a wrapper for links that make IFRAME tooltips to cancel click
* fixed case when domTT_isGecko was not deteting select-multiple with size=1
* can specify only 'status' to domTT_activate, and will change status and register clear
* made demo pages for library
* removed a hack width setting width because I was confused before...and didn't need it
* made global setting variable for domTT_prefix
 
version 0.2.2 (2002/11/21):
 
* fade-in on tips!!! (mozilla and IE only)
* global option for fade on or off (click events don't use fade ever)
* added option to domTT_activate for fade
 
version 0.2.1 (2002/11/21):
 
* perfect support for Opera7 !!! (what a great browser as far as standards go!)
* no need for select collision detection in opera (again, tremendous)
* prevented the close element from being draggable in all browsers (works this time)
* fixed bug that opera does not hide IFRAME children when tip is hidden or destroyed
* added domTT_defaultStatus to be used when clearing status bar
* for opera, you will want to disable all opera tooltips except 'element titles'
* added 'mousedown' as a trigger to set delay to 0 (3 types of mouse depress possible)
 
version 0.2.0 (2002/11/20):
 
* domTT_activate returns the id of the tip if it needs to be referenced externally
* added domTT_isActive() to check for an activated tip, returns tip object if active
* create domTT_true() function, which should be used to wrap domTT_activate for onmouseover
* second option to domTT_deactivate is optional (default to true)
* domTT_predefined now takes all the options domTT_activate takes
* domTT_activate loads in predefined options if predefined is the first option
* domTT_activate uses options from domTT_activate call to override predefined options
* take off restriction for status of onmouseover and just let it happen as it will
* caption now not used if empty, even if it is sticky (can externally close tip)
* added 'contextmenu' event type alongside 'click' for auto changing delay to 0
* if content is empty, bail on creating the tip (hmmm...still thinking on this)
* Gecko always makes the tip 4px too wide, for some unknown reason (maybe gecko bug?)
* bug in right edge detection (was giving the width the padding instead of taking away)
* fixed bug in global onmousemove (wasn't passing event to function for mozilla)
* fixed edge detection, which was not accounting for scroll offset
* made function domTT_correctEdgeBleed() for edge bleeding (since I used it twice)
* code cleanups, added docs and another example page
 
version 0.1.7 (2002/11/18):
 
* domTT_close can be an object, hence an image for an 'X' for close
* drag limited to the caption bar for sticky tips
* added domTT_addPredefined function for caching tip definitions
* added ability to pass in custom prefix for class styles, other than domTT
* can pass in 'close' option for text/image to be used as close markup
* fixed bug for onmouseover sticky tip which prevented cancel of tip creation onmouseout
* added a new example.html file
 
version 0.1.6 (2002/11/17):
 
* added option for directionality in tips (southeast, southwest, northeast, northwest)
* set default options at beginning of domTT_activate() instead of checking for each
* global setting for mouse height so that offset is from edge of mouse cursor
* added LICENSE, README to package
* finished screen edge detection and correction
* custom close text for sticky
* can globally turn off dragging of sticky tips
 
version 0.1.5 (2002/11/16):
* ability to grab current mouse position when tip is created on delay
* option for not using current mouse position when tip is created on delay (use passed in)
* changed mouseover to mousemove for event on the tooltip (prevent artifact tooltips)
* added delay as option (will use global if not passed in)
* added status as an option, which will change the status bar text
* eliminated collision detection delay when tip is already visible
* 'sticky' option changed to 'type' and can be 'greasy' or 'sticky'
* fixed some serious bugs in setTimout logic when destroying tips
* created function domTT_show() for showing hidden tip (previously created)
 
version 0.1.4 (2002/11/15):
 
* ability to drag sticky tooltips (lots of work here)
* change domTT_getPosition to domTT_getOffsets
* return more information from domTT_getOffsets
* simplify domTT_detectCollisions (now requires only one argument)
* made function for getting mouse position (since browsers do crazy things)
* the 'X' part of the tip is not draggable
 
version 0.1.3 (2002/11/14):
 
* konqueror support (lots of fixes for this) (onclick is somewhate hacked)
* browser variables instead of using javascript objects to differentiate
* eliminated duplicate mouse_x and mouse_y code
* changed lamda function calls in setTimeout to support konqueror
* getPosition returns right and bottom as well
 
version 0.1.2 (2002/11/13):
 
* fixed case when you flew over object and then clicked fast to create sticky and it failed
* domTT_deactivate now takes an object instead of id (avoids lookup)
* fixed problem with onmousemove after onclick beating setTimeout(...,0) on windows
* fixed the e.target to e.currentTarget for mozilla (which is the registered target)
* sticky tips now work correctly
* fixed domTT_detectCollisions to be subject to the activate delay on tip unhide
* no longer dependent on global Hash() function...arguments become hash internally
* account for the scroll offset when working with event coordinates
* compensated for lack of max-width for IE
* fixed broken float right for IE (cannot assign through DOM)
* float right causes tooltip to stretch to widht of page, fixed that
* fixed javascript error because IE doesn't have e.target (event.srcElement instead)
 
version 0.1.1 (2002/11/10):
 
* pass in options as Hash
* cache created tips to reuse via visibility style
* auto-assign onmouseout to deactivate
* add ability to have sticky
* implemented zIndex so new tips can go over old tips
* no delay for onclick tips
* implemented delay when toggling visibility of cached tips
* ability to pass in html content
 
version 0.1.0 (2002/10/30):
 
* Initial release
 
/trunk/api/js/domtooltip/alphaAPI.js
New file
0,0 → 1,294
/** $Id: alphaAPI.js,v 1.1 2007-03-16 12:39:35 jp_milcent Exp $ */
// {{{ license
 
/*
* Copyright 2002-2005 Dan Allen, Mojavelinux.com (dan.allen@mojavelinux.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
 
// }}}
// {{{ intro
 
/**
* Title: alphaAPI
* Original Author: chrisken
* Original Url: http://www.cs.utexas.edu/users/chrisken/alphaapi.html
*
* Modified by Dan Allen <dan.allen@mojavelinux.com>
* Note: When the stopAlpha is reached and it is equal to 0, the element's
* style is set to display: none to fix a bug in domTT
*/
 
// }}}
function alphaAPI(element, fadeInDelay, fadeOutDelay, startAlpha, stopAlpha, offsetTime, deltaAlpha)
{
// {{{ properties
 
this.element = typeof(element) == 'object' ? element : document.getElementById(element);
this.fadeInDelay = fadeInDelay || 40;
this.fadeOutDelay = fadeOutDelay || this.fadeInDelay;
this.startAlpha = startAlpha;
this.stopAlpha = stopAlpha;
// make sure a filter exists so an error is not thrown
if (typeof(this.element.filters) == 'object')
{
if (typeof(this.element.filters.alpha) == 'undefined')
{
this.element.style.filter += 'alpha(opacity=100)';
}
}
 
this.offsetTime = (offsetTime || 0) * 1000;
this.deltaAlpha = deltaAlpha || 10;
this.timer = null;
this.paused = false;
this.started = false;
this.cycle = false;
this.command = function() {};
return this;
 
// }}}
}
 
// use prototype methods to save memory
// {{{ repeat()
 
alphaAPI.prototype.repeat = function(repeat)
{
this.cycle = repeat ? true : false;
}
 
// }}}
// {{{ setAlphaBy()
 
alphaAPI.prototype.setAlphaBy = function(deltaAlpha)
{
this.setAlpha(this.getAlpha() + deltaAlpha);
}
 
// }}}
// {{{ toggle()
 
alphaAPI.prototype.toggle = function()
{
if (!this.started)
{
this.start();
}
else if (this.paused)
{
this.unpause();
}
else
{
this.pause();
}
}
 
// }}}
// {{{ timeout()
 
alphaAPI.prototype.timeout = function(command, delay)
{
this.command = command;
this.timer = setTimeout(command, delay);
}
 
// }}}
// {{{ setAlpha()
 
alphaAPI.prototype.setAlpha = function(opacity)
{
if (typeof(this.element.filters) == 'object')
{
this.element.filters.alpha.opacity = opacity;
}
else if (this.element.style.setProperty)
{
this.element.style.setProperty('opacity', opacity / 100, '');
// handle the case of mozilla < 1.7
this.element.style.setProperty('-moz-opacity', opacity / 100, '');
// handle the case of old kthml
this.element.style.setProperty('-khtml-opacity', opacity / 100, '');
}
}
 
// }}}
// {{{ getAlpha()
 
alphaAPI.prototype.getAlpha = function()
{
if (typeof(this.element.filters) == 'object')
{
return this.element.filters.alpha.opacity;
}
else if (this.element.style.getPropertyValue)
{
var opacityValue = this.element.style.getPropertyValue('opacity');
// handle the case of mozilla < 1.7
if (opacityValue == '')
{
opacityValue = this.element.style.getPropertyValue('-moz-opacity');
}
 
// handle the case of old khtml
if (opacityValue == '')
{
opacityValue = this.element.style.getPropertyValue('-khtml-opacity');
}
 
return opacityValue * 100;
}
 
return 100;
}
 
// }}}
// {{{ start()
 
alphaAPI.prototype.start = function()
{
this.started = true;
this.setAlpha(this.startAlpha);
// determine direction
if (this.startAlpha > this.stopAlpha)
{
var instance = this;
this.timeout(function() { instance.fadeOut(); }, this.offsetTime);
}
else
{
var instance = this;
this.timeout(function() { instance.fadeIn(); }, this.offsetTime);
}
}
 
// }}}
// {{{ stop()
 
alphaAPI.prototype.stop = function()
{
this.started = false;
this.setAlpha(this.stopAlpha);
if (this.stopAlpha == 0)
{
this.element.style.display = 'none';
}
 
this.stopTimer();
this.command = function() {};
}
 
// }}}
// {{{ reset()
 
alphaAPI.prototype.reset = function()
{
this.started = false;
this.setAlpha(this.startAlpha);
this.stopTimer();
this.command = function() {};
}
 
// }}}
// {{{ pause()
 
alphaAPI.prototype.pause = function()
{
this.paused = true;
this.stopTimer();
}
 
// }}}
// {{{ unpause()
 
alphaAPI.prototype.unpause = function()
{
this.paused = false;
if (!this.started)
{
this.start();
}
else
{
this.command();
}
}
 
// }}}
// {{{ stopTimer()
 
alphaAPI.prototype.stopTimer = function()
{
clearTimeout(this.timer);
this.timer = null;
}
 
// }}}
// {{{ fadeOut()
 
alphaAPI.prototype.fadeOut = function()
{
this.stopTimer();
if (this.getAlpha() > this.stopAlpha)
{
this.setAlphaBy(-1 * this.deltaAlpha);
var instance = this;
this.timeout(function() { instance.fadeOut(); }, this.fadeOutDelay);
}
else
{
if (this.cycle)
{
var instance = this;
this.timeout(function() { instance.fadeIn(); }, this.fadeInDelay);
}
else
{
if (this.stopAlpha == 0)
{
this.element.style.display = 'none';
}
this.started = false;
}
}
}
 
// }}}
// {{{ fadeIn()
 
alphaAPI.prototype.fadeIn = function()
{
this.stopTimer();
if (this.getAlpha() < this.startAlpha)
{
this.setAlphaBy(this.deltaAlpha);
var instance = this;
this.timeout(function() { instance.fadeIn(); }, this.fadeInDelay);
}
else
{
if (this.cycle)
{
var instance = this;
this.timeout(function() { instance.fadeOut(); }, this.fadeOutDelay);
}
else
{
this.started = false;
}
}
}
 
// }}}
/trunk/api/js/domtooltip/README
New file
0,0 → 1,142
$Id: README,v 1.1 2007-03-16 12:39:35 jp_milcent Exp $
 
Project: DOM Tooltip
Maintainer: Dan Allen (Mojavelinux) <dan.allen@mojavelinux.com>
Contributors:
Josh Gross (JPortalHome) <josh@jportalhome.com>
Jason Rust (CodeJanitor) <jason@rustyparts.com>
License: Apache 2.0
 
What is it?
-----------
This javascript library will allow you to have dynamic and configurable
tooltips on your html pages. There are several other tooltip libraries on the
web, but you will find that this library is very complete and stable. It
includes support for all the modern browsers and behaves in a consistent way
across these platforms. This library does not support Netscape 4. Netscape 4
is no longer an acceptable browser and it is time to move forward. That is why
I prefixed the project title with DOM. If your browser doesn't support the DOM
standard, then this library won't work.
 
How does it work?
-----------------
This library supports Gecko (Mozilla/Netscape6+,Firefox, etc), IE 5.5+, IE on
Mac, Safari, Konqueror and Opera 7 (which includes full DOM and CSS2 support).
The tooltips are configured through class definitions in your stylesheet and
the rest is up to javascript. The tooltips may consist of two parts, the
caption and the content. The caption is optional. The tips can either be
greasy, sticky, or velcro. Greasy means that they move around when you move
the mouse around and go away when you leave the element. Sticky means that they
stick around after you leave the element and are otherwise stationary. Velcro
tips disappear after a mouseout occurs on the tip itself. The tooltips also
have directionality, so you can have tips that are 'northeast', 'northwest',
'southeast' or 'southwest' of the mouse.
 
Be sure to include the file 'domLib.js' whereever you use 'domTT.js' and if you
want to have draggable tips or opacity fading, include the 'domTT_drag.js' and
'fadomatic.js' files as well. **Some of these libraries are available under the
domLib project.** Please see the HOWTO.html for details on how to use the
library and the options that are available.
 
Why is this program so big?
---------------------------
Partly because it is feature rich and thus there is lots of code, partly
because we try to use comments where ever necessary to clarify issues, and
partly because our coding style is one which makes liberal use of whitespace.
However, to save your users the trouble of downloading 50k of JavaScript every
time they come to your page you can use Douglas Crockford's excellent jsmin
program to strip all non-essentials from the code, reducing it's size by as
much as 50%. This program has been verified to work with his program, located at:
http://www.crockford.com/javascript/jsmin.html
An example usage would be:
bash# ./jsmin domTT.js domTT_min.js \
"domTT is Copyright Dan Allen (dan.allen@mojavelinux.com) (2002 - 2005). Licensed under the Apache 2.0 license"
 
Anything I should know?
-----------------------
Additionally, this tooltip library autodetects select boxes in IE and the
scrollbar on multiple selects in mozilla (the only issue mozilla has) and
HIDES them whenever the tooltip collides with them. Hence, it has full
collision detection with components which cannot use the zIndex propery!!
 
In order for it to work correctly you'll want to follow the example stylesheet
pretty closely. It has been crafted to work well on all the supported
browsers. Note the body { margin: 0; } style which is needed if you want it to
work decently on Mac IE and Opera. (According the W3C standard, a body cannot
have a margin anyway).
 
By default, the library accounts for the size of the mouse when the tip is
in one of the two southern positions. If you need to turn off this correction
on a given tip, set the option 'clearMouse' to false. If the size of the mouse
needs to be adjusted, overwrite the global variable domTT_mouseHeight.
 
In 0.7.1, the hiding of flash animations was added for those browsers that
cannot put html over top of flash. However, there are a couple of
requirements. First, the syntax that must be used is:
 
<object
type="application/x-shockwave-flash"
data="animation.swf"
width="450px"
height="250px"
pluginspage="http://www.macromedia.com/go/getflashplayer">
<param name="movie" value="animation.swf" />
<param name="wmode" value="opaque" />
...alternate (non-flash) html here!...
</object>
 
If you use the object+embed syntax, the flash will not be properly detected.
The second requirement is that the flash must be included in an element with a
position of either absolute or relative. If it is not, the flash animation
will be relocated in the DOM and therefore will not be aware of its location on
the page, making collision detection worthless.
 
Why did you write it?
---------------------
The reason I wrote this library is because I wanted a library which used 100%
DOM to do the tooltips, was easy to configure, was fast, and which was freely
distributable. You may use this library in personal or company, open source or
proprietry projects. I wrote it for you, so enjoy it. All I ask is that you
spread the word and please give me credit by leaving in my comments. If you
do make patches, please let me know about them on my forums. Viva Open Source!!
 
Important Changes in 0.7.1
--------------------------
Fading library is now fadomatic.js, so be sure to change your include
when using the fade feature. This is a third party library developed
by fadomatic@chimpen.com. You can find this library at the following URL:
 
http://chimpen.com/fadomatic
 
The global setting domTT_classPrefix was changed to domTT_styleClass and the
equivalent options without the domTT_ prefix in the domTT_activate() function
call have been changed.
 
Important Changes in 0.70
-----------------------------
IE 5.0 is no longer supported because its DOM implementation is just too
crippled. Many of the complaints about the positioning of the tips and
the screen edge detecting are now fixed.
 
Important API Changes in 0.60
------------------------------
The release is 0.60 and it introduced several significant changes over the
0.55 release. Several of the options have changed names. The following is a
list:
 
'status' -> 'statusText'
'close' -> 'closeAction'
'prefix' -> 'classPrefix'
'id' -> *no longer an option*
 
There is also a new option 'trail' which is used in place of mousemove. Do not
use domTT_activate() in the onmousemove event handler any longer!!! It was far
too slow to parse the same options all over again from onmouseover, so now just
specify the domTT_activate() in onmouseover with the option trail.
 
Also to note, the functions domTT_true() and domTT_false() have been changed to
makeTrue() and makeFalse() respectively to make them more understandable.
 
Be sure to include the file 'domLib.js' whereever you use 'domTT.js'
and if you want to have draggable tips or opacity fading, include the
'domTT_drag.js' and 'fadomatic.js' files as well.
/trunk/api/js/domtooltip/domTT_drag.js
New file
0,0 → 1,102
/** $Id: domTT_drag.js,v 1.1 2007-03-16 12:39:35 jp_milcent Exp $ */
// {{{ license
 
/*
* Copyright 2002-2005 Dan Allen, Mojavelinux.com (dan.allen@mojavelinux.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
 
// }}}
// {{{ globals (DO NOT EDIT)
 
var domTT_dragEnabled = true;
var domTT_currentDragTarget;
var domTT_dragMouseDown;
var domTT_dragOffsetLeft;
var domTT_dragOffsetTop;
 
// }}}
// {{{ domTT_dragStart()
 
function domTT_dragStart(in_this, in_event)
{
if (typeof(in_event) == 'undefined') { in_event = window.event; }
 
var eventButton = in_event[domLib_eventButton];
if (eventButton != 1 && !domLib_isKHTML)
{
return;
}
 
domTT_currentDragTarget = in_this;
in_this.style.cursor = 'move';
 
// upgrade our z-index
in_this.style.zIndex = ++domLib_zIndex;
 
var eventPosition = domLib_getEventPosition(in_event);
 
var targetPosition = domLib_getOffsets(in_this);
domTT_dragOffsetLeft = eventPosition.get('x') - targetPosition.get('left');
domTT_dragOffsetTop = eventPosition.get('y') - targetPosition.get('top');
domTT_dragMouseDown = true;
}
 
// }}}
// {{{ domTT_dragUpdate()
 
function domTT_dragUpdate(in_event)
{
if (domTT_dragMouseDown)
{
if (domLib_isGecko)
{
window.getSelection().removeAllRanges()
}
 
if (domTT_useGlobalMousePosition && domTT_mousePosition != null)
{
var eventPosition = domTT_mousePosition;
}
else
{
if (typeof(in_event) == 'undefined') { in_event = window.event; }
var eventPosition = domLib_getEventPosition(in_event);
}
 
domTT_currentDragTarget.style.left = (eventPosition.get('x') - domTT_dragOffsetLeft) + 'px';
domTT_currentDragTarget.style.top = (eventPosition.get('y') - domTT_dragOffsetTop) + 'px';
 
// update the collision detection
domLib_detectCollisions(domTT_currentDragTarget);
}
}
 
// }}}
// {{{ domTT_dragStop()
 
function domTT_dragStop()
{
if (domTT_dragMouseDown) {
domTT_dragMouseDown = false;
domTT_currentDragTarget.style.cursor = 'default';
domTT_currentDragTarget = null;
if (domLib_isGecko)
{
window.getSelection().removeAllRanges()
}
}
}
 
// }}}