/**
* @module mouse
* @desc The mouse module provides three event listener functions for mouseover, mouseout, and mousemove
* events. Additionally, it provides a suspend function which is exposed by the
* [default]{@link module:index~default} object, which is exported in [index.js]{@link module:index}.
*/
import {getOrientation, optimumOrientation, position} from './orient.js';
import {applyOptions, resetOptions} from './options.js';
import {tips, tipsIndex, sizeTip} from './tips.js';
import {beforeRule} from './init.js';
import {checkBoolean} from './utils.js';
/**
* The current mouse cursor X position in the client space.
* @type number
* @global
*/
export let mouseX;
/**
* The current mouse cursor Y position in the client space.
* @type number
* @global
*/
export let mouseY;
/**
* Countdown timer that executes a on [mouseout]{@link module:mouse~mouseOut} event
* to ensure that the .fxToolTip visibility CSS rule
* is not set to hidden until the current tooltip's transition to hidden is completed.
* @type number
* @inner
*/
let timer;
/**
* Current state of the [suspended]{@link module:mouse~suspend} toggle.
* @type boolean
* @inner
*/
let suspended = false;
/**
* @function getMouseCoordinates
* @desc Internal helper function which retrieves the current X and Y coordinates in the client window
* and stores them in the global variables mouseX and mouseY.
* @param {Event} event - The firing window event
*/
function getMouseCoordinates (event) {
event = event || window.event;
mouseX = event.clientX;
mouseY = event.clientY;
}
/**
* @function mouseOver
* @desc Fires when the cursor hovers over a DOM element that has a tooltip associated with it.
* @param {Event} event - The firing event.
* @event mouseover
*/
export function mouseOver (event) {
event = event || window.event;
if (suspend()) {return};
let targetElement = this;
let target;
if (beforeRule.visibility !== 'hidden') { //executed if another tooltip is transitioning to hidden
beforeRule.transition = '';
clearTimeout(timer);
};
beforeRule.visibility = 'visible';
getMouseCoordinates(event);
target = tips[tipsIndex.indexOf(targetElement.id)];
applyOptions(target);
let orientation = getOrientation(targetElement, target);
position(targetElement, target, orientation);
beforeRule.opacity = target.backgroundOpacity();
}
/**
* @function mouseMove
* @desc Fires when the cursor moves over a DOM element that has a tooltip associated with it.
* @param {event} event - The firing window event.
* @event mousemove
*/
export function mouseMove (event) {
event = event || window.event;
if (suspend()) {return};
let targetElement = this;
let target;
target = tips[tipsIndex.indexOf(targetElement.id)];
if (!target.trackMouse()) { return; };
getMouseCoordinates(event);
let orientation = getOrientation(targetElement, target);
position(targetElement, target, orientation);
}
/**
* @function mouseOut
* @desc Fires when the cursor leaves a DOM element that has a tooltip associated with it.
* @param {event} event - The firing window event.
* @event mouseout
*/
export function mouseOut (event) {
event = event || window.event;
let targetElement = this;
if (window.getComputedStyle(targetElement, null).getPropertyValue('opacity') == 0 && suspend()) {
return;
};
let target = tips[tipsIndex.indexOf(targetElement.id)];
let transitionString = target.transitionHidden();
let transitionDuration = +transitionString.split(' ')[1].replace('s', '');
let transitionDelay = +transitionString.split(' ')[3].replace('s', '');
beforeRule.transition = transitionString;
beforeRule['-moz-transition'] = transitionString;
beforeRule['-webkit-transiton'] = transitionString;
beforeRule['-o-transition'] = transitionString;
timer = window.setTimeout(function() { // ensures the visibility isn't set to hidden until the transition completes
beforeRule.visibility = 'hidden';
resetOptions(target);
},
(transitionDuration + transitionDelay) * 1000);
beforeRule.opacity = 0;
}
/**
* @function suspend
* @desc This method is useful for temporarily suspending and re-enabling tooltips globally
* in such cases where other on-screen interaction may be interfered with by the tooltips.
* @param {boolean} suspendTips Whether or not to suspend toolTips.
* @returns {(boolean | undefined)} If the method is called without the suspendTips argument, the method
* returns the current state of tooltips (true for suspended, false for enabled).
* Otherwise, nothing is returned.
*/
export function suspend (suspendTips) {
if (suspendTips == undefined) {return suspended};
if (checkBoolean(suspendTips, 'suspend')) {
suspended = suspendTips;
};
}