| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- /* Copyright (c) Business Objects 2006. All rights reserved. */
- bobj.crv.Tooltip = {
- show: function(tipHtml, x, y, options) {
- options = MochiKit.Base.update({
- delay: 0.5, // delay before starting to show the tooltip
- duration: 0.5, // duration of fade in/out effect in seconds
- aspect: 2.0, // Ratio of width to height
- wrapThreshold: 200 // Min width in px before growing vertically
- }, options);
-
- this._options = options;
- this._tipHtml = tipHtml;
- this._x = x;
- this._y = y;
-
- if (!this._layer) {
- this._createLayer();
- this._delayedShow = MochiKit.Base.bind(this._delayedShow, this);
- this._delayedHide = MochiKit.Base.bind(this._delayedHide, this);
- }
-
- clearTimeout(this._timeoutId);
- this._timeoutId = setTimeout(this._delayedShow, options.delay * 1000);
- },
-
- _delayedShow: function() {
- if (this._effect) {
- this._effect.cancel();
- }
-
- var style = this._layer.style;
-
- if (!this._options._fastShow) {
- if (bobj.isString(this._tipHtml)) {
- this._layer.firstChild.innerHTML = this._tipHtml;
- }
-
- this._resize();
- bobj.placeElement(this._layer, this._x, this._y, false, false);
- }
- style.visibility = 'visible';
- this._effect = MochiKit.Visual.appear(this._layer, {duration: this._options.duration});
- },
-
- hide: function(options) {
- if (this._layer) {
- this._options = MochiKit.Base.update(this._options, options);
- clearTimeout(this._timeoutId);
- this._timeoutId = setTimeout(this._delayedHide, this._options.delay * 1000);
- }
- },
-
- _delayedHide: function() {
- if (this._effect) {
- this._effect.cancel();
- }
-
- var layer = this._layer;
- this._effect = MochiKit.Visual.fade(layer, {
- duration: this._options.duration,
- afterFinish: function(){layer.style.visibility = 'hidden';},
- afterFinishInternal: null //don't set display:none
- });
- },
-
- _elementConnections: {},
-
- setElementTooltip: function(elt, tipHtml, options) {
- var CONNECT = MochiKit.Signal.connect;
- if (elt) {
- if (elt.bobj_crv_tooltip_id) {
- this.removeElementTooltip(elt);
- }
- else {
- elt.bobj_crv_tooltip_id = bobj.uniqueId();
- }
-
- var idents = [];
- this._elementConnections[elt.bobj_crv_tooltip_id] = idents;
-
- var over = function(e) {
- var p = e.mouse().page;
- bobj.crv.Tooltip.show(tipHtml, p.x, p.y, options);
- };
- var out = function(e) {
- bobj.crv.Tooltip.hide(options);
- };
- idents.push(CONNECT(elt, 'onmouseover', over));
- idents.push(CONNECT(elt, 'onmouseout', out));
- }
- },
- removeElementTooltip: function(elt) {
- if (elt && elt.bobj_crv_tooltip_id) {
- var idents = this._elementConnections[elt.bobj_crv_tooltip_id];
- if (idents) {
- for (var i = 0, len = idents.length; i < len; ++i) {
- MochiKit.Signal.disconnect(idents[i]);
- }
- delete this._elementConnections[elt.bobj_crv_tooltip_id];
- }
- }
- },
-
- _createLayer: function() {
- var CONNECT = MochiKit.Signal.connect;
- var DIV = MochiKit.DOM.DIV;
- this._layer = DIV({'class': "crvTooltip",
- style:"visibility:hidden, position:absolute; display:block; top:0px; left:0px"},
- DIV(null, ' '));
-
- MochiKit.DOM.setOpacity(this._layer, 0);
- document.body.appendChild(this._layer);
-
- var over = function(e) {
- if (bobj.crv.Tooltip._effect) {
- bobj.crv.Tooltip.show(null, null, null,
- MochiKit.Base.update({_fastShow: true}, bobj.crv.Tooltip._options));
- }
- };
- var out = function(e) {
- bobj.crv.Tooltip.hide(bobj.crv.Tooltip._options);
- };
- CONNECT(this._layer, 'onmouseover', over);
- CONNECT(this._layer, 'onmouseout', out);
- },
-
- _resize: function() {
- var layer = this._layer;
- var layerStyle = layer.style;
- var content = layer.firstChild;
-
- var aspect = this._options.aspect;
- var wrapThreshold = this._options.wrapThreshold;
-
- var oldLeft = layerStyle.left;
- layerStyle.visibility = "hidden";
- layerStyle.left = '-' + wrapThreshold + 'px';
- layerStyle.width = null;
- layerStyle.height = null;
-
- if (content.offsetWidth > wrapThreshold) {
- var paddingY = parseInt(MochiKit.Style.computedStyle(layer, 'padding-top'), 10) || 0;
- paddingY += parseInt(MochiKit.Style.computedStyle(layer, 'padding-bottom'), 10) || 0;
-
- var paddingX = parseInt(MochiKit.Style.computedStyle(layer, 'padding-left'), 10) || 0;
- paddingX += parseInt(MochiKit.Style.computedStyle(layer, 'padding-right'), 10) || 0;
-
- //force overflow to get the smallest possible content width
- layerStyle.width = '1px';
- //now force reflow because some browsers will not fill the available
- //width otherwise (IE7)
- layerStyle.width = (content.offsetWidth + paddingX) +'px';
- content.innerHTML += '';
-
- var contentArea = content.offsetWidth * content.offsetHeight;
- var height = Math.ceil(Math.sqrt(contentArea / aspect));
- var width = height * aspect;
-
- layerStyle.height = height + paddingY + 'px';
- layerStyle.width = width + 'px';
-
- while(content.offsetWidth > layer.clientWidth ||
- content.offsetHeight > layer.clientHeight) {
- height += 5;
- width = height * aspect;
- layerStyle.height = height + 'px';
- layerStyle.width = width + 'px';
- }
- }
-
- layerStyle.left = oldLeft || null; //setting "" doesn't always work
- }
- };
|