354 lines
7.3 KiB
JavaScript
354 lines
7.3 KiB
JavaScript
|
/**
|
||
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||
|
*/
|
||
|
/**
|
||
|
* Class: mxTooltipHandler
|
||
|
*
|
||
|
* Graph event handler that displays tooltips. <mxGraph.getTooltip> is used to
|
||
|
* get the tooltip for a cell or handle. This handler is built-into
|
||
|
* <mxGraph.tooltipHandler> and enabled using <mxGraph.setTooltips>.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* (code>
|
||
|
* new mxTooltipHandler(graph);
|
||
|
* (end)
|
||
|
*
|
||
|
* Constructor: mxTooltipHandler
|
||
|
*
|
||
|
* Constructs an event handler that displays tooltips with the specified
|
||
|
* delay (in milliseconds). If no delay is specified then a default delay
|
||
|
* of 500 ms (0.5 sec) is used.
|
||
|
*
|
||
|
* Parameters:
|
||
|
*
|
||
|
* graph - Reference to the enclosing <mxGraph>.
|
||
|
* delay - Optional delay in milliseconds.
|
||
|
*/
|
||
|
function mxTooltipHandler(graph, delay)
|
||
|
{
|
||
|
if (graph != null)
|
||
|
{
|
||
|
this.graph = graph;
|
||
|
this.delay = delay || 500;
|
||
|
this.graph.addMouseListener(this);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Variable: zIndex
|
||
|
*
|
||
|
* Specifies the zIndex for the tooltip and its shadow. Default is 10005.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.zIndex = 10005;
|
||
|
|
||
|
/**
|
||
|
* Variable: graph
|
||
|
*
|
||
|
* Reference to the enclosing <mxGraph>.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.graph = null;
|
||
|
|
||
|
/**
|
||
|
* Variable: delay
|
||
|
*
|
||
|
* Delay to show the tooltip in milliseconds. Default is 500.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.delay = null;
|
||
|
|
||
|
/**
|
||
|
* Variable: ignoreTouchEvents
|
||
|
*
|
||
|
* Specifies if touch and pen events should be ignored. Default is true.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.ignoreTouchEvents = true;
|
||
|
|
||
|
/**
|
||
|
* Variable: hideOnHover
|
||
|
*
|
||
|
* Specifies if the tooltip should be hidden if the mouse is moved over the
|
||
|
* current cell. Default is false.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.hideOnHover = false;
|
||
|
|
||
|
/**
|
||
|
* Variable: destroyed
|
||
|
*
|
||
|
* True if this handler was destroyed using <destroy>.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.destroyed = false;
|
||
|
|
||
|
/**
|
||
|
* Variable: enabled
|
||
|
*
|
||
|
* Specifies if events are handled. Default is true.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.enabled = true;
|
||
|
|
||
|
/**
|
||
|
* Function: isEnabled
|
||
|
*
|
||
|
* Returns true if events are handled. This implementation
|
||
|
* returns <enabled>.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.isEnabled = function()
|
||
|
{
|
||
|
return this.enabled;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function: setEnabled
|
||
|
*
|
||
|
* Enables or disables event handling. This implementation
|
||
|
* updates <enabled>.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.setEnabled = function(enabled)
|
||
|
{
|
||
|
this.enabled = enabled;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function: isHideOnHover
|
||
|
*
|
||
|
* Returns <hideOnHover>.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.isHideOnHover = function()
|
||
|
{
|
||
|
return this.hideOnHover;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function: setHideOnHover
|
||
|
*
|
||
|
* Sets <hideOnHover>.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.setHideOnHover = function(value)
|
||
|
{
|
||
|
this.hideOnHover = value;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function: init
|
||
|
*
|
||
|
* Initializes the DOM nodes required for this tooltip handler.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.init = function()
|
||
|
{
|
||
|
if (document.body != null)
|
||
|
{
|
||
|
this.div = document.createElement('div');
|
||
|
this.div.className = 'mxTooltip';
|
||
|
this.div.style.visibility = 'hidden';
|
||
|
|
||
|
document.body.appendChild(this.div);
|
||
|
|
||
|
mxEvent.addGestureListeners(this.div, mxUtils.bind(this, function(evt)
|
||
|
{
|
||
|
var source = mxEvent.getSource(evt);
|
||
|
|
||
|
if (source.nodeName != 'A')
|
||
|
{
|
||
|
this.hideTooltip();
|
||
|
}
|
||
|
}));
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function: getStateForEvent
|
||
|
*
|
||
|
* Returns the <mxCellState> to be used for showing a tooltip for this event.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.getStateForEvent = function(me)
|
||
|
{
|
||
|
return me.getState();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function: mouseDown
|
||
|
*
|
||
|
* Handles the event by initiating a rubberband selection. By consuming the
|
||
|
* event all subsequent events of the gesture are redirected to this
|
||
|
* handler.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.mouseDown = function(sender, me)
|
||
|
{
|
||
|
this.reset(me, false);
|
||
|
this.hideTooltip();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function: mouseMove
|
||
|
*
|
||
|
* Handles the event by updating the rubberband selection.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.mouseMove = function(sender, me)
|
||
|
{
|
||
|
if (me.getX() != this.lastX || me.getY() != this.lastY)
|
||
|
{
|
||
|
this.reset(me, true);
|
||
|
var state = this.getStateForEvent(me);
|
||
|
|
||
|
if (this.isHideOnHover() || state != this.state || (me.getSource() != this.node &&
|
||
|
(!this.stateSource || (state != null && this.stateSource ==
|
||
|
(me.isSource(state.shape) || !me.isSource(state.text))))))
|
||
|
{
|
||
|
this.hideTooltip();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.lastX = me.getX();
|
||
|
this.lastY = me.getY();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function: mouseUp
|
||
|
*
|
||
|
* Handles the event by resetting the tooltip timer or hiding the existing
|
||
|
* tooltip.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.mouseUp = function(sender, me)
|
||
|
{
|
||
|
this.reset(me, true);
|
||
|
this.hideTooltip();
|
||
|
};
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Function: resetTimer
|
||
|
*
|
||
|
* Resets the timer.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.resetTimer = function()
|
||
|
{
|
||
|
if (this.thread != null)
|
||
|
{
|
||
|
window.clearTimeout(this.thread);
|
||
|
this.thread = null;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function: reset
|
||
|
*
|
||
|
* Resets and/or restarts the timer to trigger the display of the tooltip.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.reset = function(me, restart, state)
|
||
|
{
|
||
|
if (!this.ignoreTouchEvents || mxEvent.isMouseEvent(me.getEvent()))
|
||
|
{
|
||
|
this.resetTimer();
|
||
|
state = (state != null) ? state : this.getStateForEvent(me);
|
||
|
|
||
|
if (restart && this.isEnabled() && state != null && (this.div == null ||
|
||
|
this.div.style.visibility == 'hidden'))
|
||
|
{
|
||
|
var node = me.getSource();
|
||
|
var x = me.getX();
|
||
|
var y = me.getY();
|
||
|
var stateSource = me.isSource(state.shape) || me.isSource(state.text);
|
||
|
|
||
|
this.thread = window.setTimeout(mxUtils.bind(this, function()
|
||
|
{
|
||
|
if (!this.graph.isEditing() && !this.graph.popupMenuHandler.isMenuShowing() && !this.graph.isMouseDown)
|
||
|
{
|
||
|
// Uses information from inside event cause using the event at
|
||
|
// this (delayed) point in time is not possible in IE as it no
|
||
|
// longer contains the required information (member not found)
|
||
|
var tip = this.graph.getTooltip(state, node, x, y);
|
||
|
this.show(tip, x, y);
|
||
|
this.state = state;
|
||
|
this.node = node;
|
||
|
this.stateSource = stateSource;
|
||
|
}
|
||
|
}), this.delay);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function: hide
|
||
|
*
|
||
|
* Hides the tooltip and resets the timer.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.hide = function()
|
||
|
{
|
||
|
this.resetTimer();
|
||
|
this.hideTooltip();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function: hideTooltip
|
||
|
*
|
||
|
* Hides the tooltip.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.hideTooltip = function()
|
||
|
{
|
||
|
if (this.div != null)
|
||
|
{
|
||
|
this.div.style.visibility = 'hidden';
|
||
|
this.div.innerHTML = '';
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function: show
|
||
|
*
|
||
|
* Shows the tooltip for the specified cell and optional index at the
|
||
|
* specified location (with a vertical offset of 10 pixels).
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.show = function(tip, x, y)
|
||
|
{
|
||
|
if (!this.destroyed && tip != null && tip.length > 0)
|
||
|
{
|
||
|
// Initializes the DOM nodes if required
|
||
|
if (this.div == null)
|
||
|
{
|
||
|
this.init();
|
||
|
}
|
||
|
|
||
|
var origin = mxUtils.getScrollOrigin();
|
||
|
|
||
|
this.div.style.zIndex = this.zIndex;
|
||
|
this.div.style.left = (x + origin.x) + 'px';
|
||
|
this.div.style.top = (y + mxConstants.TOOLTIP_VERTICAL_OFFSET +
|
||
|
origin.y) + 'px';
|
||
|
|
||
|
if (!mxUtils.isNode(tip))
|
||
|
{
|
||
|
this.div.innerHTML = tip.replace(/\n/g, '<br>');
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.div.innerHTML = '';
|
||
|
this.div.appendChild(tip);
|
||
|
}
|
||
|
|
||
|
this.div.style.visibility = '';
|
||
|
mxUtils.fit(this.div);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function: destroy
|
||
|
*
|
||
|
* Destroys the handler and all its resources and DOM nodes.
|
||
|
*/
|
||
|
mxTooltipHandler.prototype.destroy = function()
|
||
|
{
|
||
|
if (!this.destroyed)
|
||
|
{
|
||
|
this.graph.removeMouseListener(this);
|
||
|
mxEvent.release(this.div);
|
||
|
|
||
|
if (this.div != null && this.div.parentNode != null)
|
||
|
{
|
||
|
this.div.parentNode.removeChild(this.div);
|
||
|
}
|
||
|
|
||
|
this.destroyed = true;
|
||
|
this.div = null;
|
||
|
}
|
||
|
};
|