blob: c8a06d11be92bd7ef4a34c0f0d8d621e06a671b5 [file] [log] [blame]
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.widget.Tooltip");
dojo.require("dojo.widget.ContentPane");
dojo.require("dojo.widget.PopupContainer");
dojo.require("dojo.uri.Uri");
dojo.require("dojo.widget.*");
dojo.require("dojo.event.*");
dojo.require("dojo.html.style");
dojo.require("dojo.html.util");
dojo.widget.defineWidget(
"dojo.widget.Tooltip",
[dojo.widget.ContentPane, dojo.widget.PopupContainerBase],
{
// summary
// Pops up a tooltip (a help message) when you hover over a node
// caption: String
// Text to display in the tooltip.
// Can also be specified as innerHTML (when creating the widget from markup).
caption: "",
// showDelay: Integer
// Number of milliseconds to wait after hovering over the object, before
// the tooltip is displayed.
showDelay: 500,
// hideDelay: Integer
// Number of milliseconds to wait after moving mouse off of the object (or
// off of the tooltip itself), before erasing the tooltip
hideDelay: 100,
// connectId: String
// Id of domNode to attach the tooltip to.
// (When user hovers over specified dom node, the tooltip will appear.)
connectId: "",
templateCssPath: dojo.uri.dojoUri("src/widget/templates/TooltipTemplate.css"),
fillInTemplate: function(args, frag){
if(this.caption != ""){
this.domNode.appendChild(document.createTextNode(this.caption));
}
this._connectNode = dojo.byId(this.connectId);
dojo.widget.Tooltip.superclass.fillInTemplate.call(this, args, frag);
this.addOnLoad(this, "_loadedContent");
dojo.html.addClass(this.domNode, "dojoTooltip");
//copy style from input node to output node
var source = this.getFragNodeRef(frag);
dojo.html.copyStyle(this.domNode, source);
//apply the necessary css rules to the node so that it can popup
this.applyPopupBasicStyle();
},
postCreate: function(args, frag){
dojo.event.connect(this._connectNode, "onmouseover", this, "_onMouseOver");
dojo.widget.Tooltip.superclass.postCreate.call(this, args, frag);
},
_onMouseOver: function(e){
this._mouse = {x: e.pageX, y: e.pageY};
// Start tracking mouse movements, so we know when to cancel timers or erase the tooltip
if(!this._tracking){
dojo.event.connect(document.documentElement, "onmousemove", this, "_onMouseMove");
this._tracking=true;
}
this._onHover(e);
},
_onMouseMove: function(e) {
this._mouse = {x: e.pageX, y: e.pageY};
if(dojo.html.overElement(this._connectNode, e) || dojo.html.overElement(this.domNode, e)){
this._onHover(e);
} else {
// mouse has been moved off the element/tooltip
// note: can't use onMouseOut to detect this because the "explode" effect causes
// spurious onMouseOut events (due to interference from outline), w/out corresponding _onMouseOver
this._onUnHover(e);
}
},
_onHover: function(e) {
if(this._hover){ return; }
this._hover=true;
// If the tooltip has been scheduled to be erased, cancel that timer
// since we are hovering over element/tooltip again
if(this._hideTimer) {
clearTimeout(this._hideTimer);
delete this._hideTimer;
}
// If tooltip not showing yet then set a timer to show it shortly
if(!this.isShowingNow && !this._showTimer){
this._showTimer = setTimeout(dojo.lang.hitch(this, "open"), this.showDelay);
}
},
_onUnHover: function(e){
if(!this._hover){ return; }
this._hover=false;
if(this._showTimer){
clearTimeout(this._showTimer);
delete this._showTimer;
}
if(this.isShowingNow && !this._hideTimer){
this._hideTimer = setTimeout(dojo.lang.hitch(this, "close"), this.hideDelay);
}
// If we aren't showing the tooltip, then we can stop tracking the mouse now;
// otherwise must track the mouse until tooltip disappears
if(!this.isShowingNow){
dojo.event.disconnect(document.documentElement, "onmousemove", this, "_onMouseMove");
this._tracking=false;
}
},
open: function() {
// summary: display the tooltip; usually not called directly.
if (this.isShowingNow) { return; }
dojo.widget.PopupContainerBase.prototype.open.call(this, this._mouse.x, this._mouse.y, null, [this._mouse.x, this._mouse.y], "TL,TR,BL,BR", [10,15]);
},
close: function() {
// summary: hide the tooltip; usually not called directly.
if (this.isShowingNow) {
if ( this._showTimer ) {
clearTimeout(this._showTimer);
delete this._showTimer;
}
if ( this._hideTimer ) {
clearTimeout(this._hideTimer);
delete this._hideTimer;
}
dojo.event.disconnect(document.documentElement, "onmousemove", this, "_onMouseMove");
this._tracking=false;
dojo.widget.PopupContainerBase.prototype.close.call(this);
}
},
_position: function(){
this.move(this._mouse.x, this._mouse.y, [10,15], "TL,TR,BL,BR");
},
_loadedContent: function(){
if(this.isShowingNow){
// the tooltip has changed size due to downloaded contents, so reposition it
this._position();
}
},
checkSize: function(){
// Override checkSize() in HtmlWidget.
// checkSize() is called when the user has resized the browser window,
// but that doesn't affect this widget (or this widget's children)
// so it can be safely ignored
},
uninitialize: function(){
this.close();
dojo.event.disconnect(this._connectNode, "onmouseover", this, "_onMouseOver");
}
}
);