| /* |
| 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"); |
| } |
| |
| } |
| ); |