SemanticScuttle/includes/js/dijit/Tooltip.js

293 lines
9.2 KiB
JavaScript
Raw Normal View History

if(!dojo._hasResource["dijit.Tooltip"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit.Tooltip"] = true;
dojo.provide("dijit.Tooltip");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.declare(
"dijit._MasterTooltip",
[dijit._Widget, dijit._Templated],
{
// summary
// Internal widget that holds the actual tooltip markup,
// which occurs once per page.
// Called by Tooltip widgets which are just containers to hold
// the markup
// duration: Integer
// Milliseconds to fade in/fade out
duration: 200,
templateString:"<div class=\"dijitTooltip dijitTooltipLeft\" id=\"dojoTooltip\">\n\t<div class=\"dijitTooltipContainer dijitTooltipContents\" dojoAttachPoint=\"containerNode\" waiRole='alert'></div>\n\t<div class=\"dijitTooltipConnector\"></div>\n</div>\n",
postCreate: function(){
dojo.body().appendChild(this.domNode);
this.bgIframe = new dijit.BackgroundIframe(this.domNode);
// Setup fade-in and fade-out functions.
this.fadeIn = dojo.fadeIn({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onShow") });
this.fadeOut = dojo.fadeOut({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onHide") });
},
show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode, /*String[]?*/ position){
// summary:
// Display tooltip w/specified contents to right specified node
// (To left if there's no space on the right, or if LTR==right)
if(this.aroundNode && this.aroundNode === aroundNode){
return;
}
if(this.fadeOut.status() == "playing"){
// previous tooltip is being hidden; wait until the hide completes then show new one
this._onDeck=arguments;
return;
}
this.containerNode.innerHTML=innerHTML;
// Firefox bug. when innerHTML changes to be shorter than previous
// one, the node size will not be updated until it moves.
this.domNode.style.top = (this.domNode.offsetTop + 1) + "px";
// position the element and change CSS according to position[] (a list of positions to try)
var align = {};
var ltr = this.isLeftToRight();
dojo.forEach( (position && position.length) ? position : dijit.Tooltip.defaultPosition, function(pos){
switch(pos){
case "after":
align[ltr ? "BR" : "BL"] = ltr ? "BL" : "BR";
break;
case "before":
align[ltr ? "BL" : "BR"] = ltr ? "BR" : "BL";
break;
case "below":
// first try to align left borders, next try to align right borders (or reverse for RTL mode)
align[ltr ? "BL" : "BR"] = ltr ? "TL" : "TR";
align[ltr ? "BR" : "BL"] = ltr ? "TR" : "TL";
break;
case "above":
default:
// first try to align left borders, next try to align right borders (or reverse for RTL mode)
align[ltr ? "TL" : "TR"] = ltr ? "BL" : "BR";
align[ltr ? "TR" : "TL"] = ltr ? "BR" : "BL";
break;
}
});
var pos = dijit.placeOnScreenAroundElement(this.domNode, aroundNode, align, dojo.hitch(this, "orient"));
// show it
dojo.style(this.domNode, "opacity", 0);
this.fadeIn.play();
this.isShowingNow = true;
this.aroundNode = aroundNode;
},
orient: function(/* DomNode */ node, /* String */ aroundCorner, /* String */ tooltipCorner){
// summary: private function to set CSS for tooltip node based on which position it's in
node.className = "dijitTooltip " +
{
"BL-TL": "dijitTooltipBelow dijitTooltipABLeft",
"TL-BL": "dijitTooltipAbove dijitTooltipABLeft",
"BR-TR": "dijitTooltipBelow dijitTooltipABRight",
"TR-BR": "dijitTooltipAbove dijitTooltipABRight",
"BR-BL": "dijitTooltipRight",
"BL-BR": "dijitTooltipLeft"
}[aroundCorner + "-" + tooltipCorner];
},
_onShow: function(){
if(dojo.isIE){
// the arrow won't show up on a node w/an opacity filter
this.domNode.style.filter="";
}
},
hide: function(aroundNode){
// summary: hide the tooltip
if(!this.aroundNode || this.aroundNode !== aroundNode){
return;
}
if(this._onDeck){
// this hide request is for a show() that hasn't even started yet;
// just cancel the pending show()
this._onDeck=null;
return;
}
this.fadeIn.stop();
this.isShowingNow = false;
this.aroundNode = null;
this.fadeOut.play();
},
_onHide: function(){
this.domNode.style.cssText=""; // to position offscreen again
if(this._onDeck){
// a show request has been queued up; do it now
this.show.apply(this, this._onDeck);
this._onDeck=null;
}
}
}
);
dijit.showTooltip = function(/*String*/ innerHTML, /*DomNode*/ aroundNode, /*String[]?*/ position){
// summary:
// Display tooltip w/specified contents in specified position.
// See description of dijit.Tooltip.defaultPosition for details on position parameter.
// If position is not specified then dijit.Tooltip.defaultPosition is used.
if(!dijit._masterTT){ dijit._masterTT = new dijit._MasterTooltip(); }
return dijit._masterTT.show(innerHTML, aroundNode, position);
};
dijit.hideTooltip = function(aroundNode){
// summary: hide the tooltip
if(!dijit._masterTT){ dijit._masterTT = new dijit._MasterTooltip(); }
return dijit._masterTT.hide(aroundNode);
};
dojo.declare(
"dijit.Tooltip",
dijit._Widget,
{
// summary
// Pops up a tooltip (a help message) when you hover over a node.
// label: String
// Text to display in the tooltip.
// Specified as innerHTML when creating the widget from markup.
label: "",
// showDelay: Integer
// Number of milliseconds to wait after hovering over/focusing on the object, before
// the tooltip is displayed.
showDelay: 400,
// connectId: String[]
// Id(s) of domNodes to attach the tooltip to.
// When user hovers over any of the specified dom nodes, the tooltip will appear.
connectId: [],
// position: String[]
// See description of dijit.Tooltip.defaultPosition for details on position parameter.
position: [],
postCreate: function(){
if(this.srcNodeRef){
this.srcNodeRef.style.display = "none";
}
this._connectNodes = [];
dojo.forEach(this.connectId, function(id) {
var node = dojo.byId(id);
if (node) {
this._connectNodes.push(node);
dojo.forEach(["onMouseOver", "onMouseOut", "onFocus", "onBlur", "onHover", "onUnHover"], function(event){
this.connect(node, event.toLowerCase(), "_"+event);
}, this);
if(dojo.isIE){
// BiDi workaround
node.style.zoom = 1;
}
}
}, this);
},
_onMouseOver: function(/*Event*/ e){
this._onHover(e);
},
_onMouseOut: function(/*Event*/ e){
if(dojo.isDescendant(e.relatedTarget, e.target)){
// false event; just moved from target to target child; ignore.
return;
}
this._onUnHover(e);
},
_onFocus: function(/*Event*/ e){
this._focus = true;
this._onHover(e);
this.inherited(arguments);
},
_onBlur: function(/*Event*/ e){
this._focus = false;
this._onUnHover(e);
this.inherited(arguments);
},
_onHover: function(/*Event*/ e){
if(!this._showTimer){
var target = e.target;
this._showTimer = setTimeout(dojo.hitch(this, function(){this.open(target)}), this.showDelay);
}
},
_onUnHover: function(/*Event*/ e){
// keep a tooltip open if the associated element has focus
if(this._focus){ return; }
if(this._showTimer){
clearTimeout(this._showTimer);
delete this._showTimer;
}
this.close();
},
open: function(/*DomNode*/ target){
// summary: display the tooltip; usually not called directly.
target = target || this._connectNodes[0];
if(!target){ return; }
if(this._showTimer){
clearTimeout(this._showTimer);
delete this._showTimer;
}
dijit.showTooltip(this.label || this.domNode.innerHTML, target, this.position);
this._connectNode = target;
},
close: function(){
// summary: hide the tooltip; usually not called directly.
dijit.hideTooltip(this._connectNode);
delete this._connectNode;
if(this._showTimer){
clearTimeout(this._showTimer);
delete this._showTimer;
}
},
uninitialize: function(){
this.close();
}
}
);
// dijit.Tooltip.defaultPosition: String[]
// This variable controls the position of tooltips, if the position is not specified to
// the Tooltip widget or *TextBox widget itself. It's an array of strings with the following values:
//
// * before: places tooltip to the left of the target node/widget, or to the right in
// the case of RTL scripts like Hebrew and Arabic
// * after: places tooltip to the right of the target node/widget, or to the left in
// the case of RTL scripts like Hebrew and Arabic
// * above: tooltip goes above target node
// * below: tooltip goes below target node
//
// The list is positions is tried, in order, until a position is found where the tooltip fits
// within the viewport.
//
// Be careful setting this parameter. A value of "above" may work fine until the user scrolls
// the screen so that there's no room above the target node. Nodes with drop downs, like
// DropDownButton or FilteringSelect, are especially problematic, in that you need to be sure
// that the drop down and tooltip don't overlap, even when the viewport is scrolled so that there
// is only room below (or above) the target node, but not both.
dijit.Tooltip.defaultPosition = ["after", "before"];
}