JSDoc: Source: noop.tooltip.js

/**
 * NOOP Tooltip module.
 * @memberof noop
 * @namespace tooltip
 * @author cisco211
 * @copyright © 2019 by "cisco211"
 * @version 0.200
 */
(function(noop, undefined)
{
	'use strict';

	// #region Private
	/**
	 * @summary Default tooltip options.
	 * @typedef {object.<string, any>} noop.tooltip.Defaults
	 * @memberof noop.tooltip
	 * @property {string} [attr='noop-tooltip'] - Default data attribute name.
	 * @property {string} [edgeH=10] - Default viewport horizontal edge offset.
	 * @property {string} [edgeV=10] - Default viewport vertical edge offset.
	 * @property {string} [offsetX=10] - Default mouse x offset.
	 * @property {string} [offsetY=10] - Default mouse y offset.
	 */
	class Defaults
	{
		constructor()
		{
			this.attr = 'noop-tooltip';
			this.edgeH = 10;
			this.edgeV = 10;
			this.offsetX = 25;
			this.offsetY = 25;
		}
	}; // class Defaults

	var current_ = null;

	var edgeH_ = Defaults.edgeH;

	var edgeV_ = Defaults.edgeV;

	var offsetX_ = Defaults.offsetX;

	var offsetY_ = Defaults.offsetY;

	var attrToIndex_ = function(a)
	{
		return a.replace(/-([a-z]{1})/, function($0, $1)
		{
			return $0.replace('-', '').replace($1, $1.toUpperCase());
		});
	};

	var ttShow_ = function(tt, eventMouse)
	{
		ttMove_(tt, eventMouse)
	};

	var ttHide_ = function(tt)
	{
		if (noop.isNull(tt))
			return;
		current_ = null;
		tt.style.display = 'none';
	};

	var ttMove_ = function(tt, eventMouse)
	{
		if (noop.isNull(tt) || noop.isNull(eventMouse))
			return;
		current_ = tt;
		tt.style.display = 'block';
		tt.style.left = (eventMouse.clientX + offsetX_) + 'px';
		tt.style.top = (eventMouse.clientY + offsetY_) + 'px';
		if (!window || !window.getComputedStyle)
			return;
		var c = window.getComputedStyle(tt);
		var ttHeight = parseInt(c.height.replace('px', ''));
		var ttWidth = parseInt(c.width.replace('px', ''));
		if (eventMouse.clientX + offsetX_+ ttWidth >= document.documentElement.clientWidth - edgeH_)
			tt.style.left = (eventMouse.clientX - offsetX_ - ttWidth) + 'px';
		if (eventMouse.clientY + offsetY_ + ttHeight >= document.documentElement.clientHeight - edgeV_)
			tt.style.top = (eventMouse.clientY - offsetY_ - ttHeight) + 'px';
	};

	var scroll_ = function()
	{
		if (noop.isNull(current_))
			return;
		ttHide_(current_);
	}

	var touchEnd_ = function(opts, eventTouch)
	{
		var a = attrToIndex_(opts.attr);
		if (!noop.isNull(eventTouch.target.dataset[a]))
			return;
		if (noop.isNull(current_))
			return;
		ttHide_(current_);
	};
	// #endregion Private

	// #region Public
	noop.tooltip = new class Tooltip
	{
		constructor()
		{
			this.defaults = function()
			{
				return new Defaults();
			};

			this.register = function(opts = noop.tooltip.defaults())
			{
				var a = attrToIndex_(opts.attr);
				edgeH_ = noop.isSet(opts.edgeH) ? opts.edgeH : edgeH_;
				edgeV_ = noop.isSet(opts.edgeV) ? opts.edgeV : edgeV_;
				offsetX_ = noop.isSet(opts.offsetX) ? opts.offsetX : offsetX_;
				offsetY_ = noop.isSet(opts.offsetY) ? opts.offsetY : offsetY_;
				var l = document.querySelectorAll('[data-' + opts.attr + ']');
				if (l)
				{
					l.forEach(function(e)
					{
						var tt = document.getElementById(e.dataset[a]);
						if (tt)
						{
							e.addEventListener('mouseenter', function(eventMouse){ttShow_(tt, eventMouse);}, false);
							e.addEventListener('mouseleave', function(){ttHide_(tt);}, false);
							e.addEventListener('mousemove', function(eventMouse){ttMove_(tt, eventMouse);}, false);
						}
					}); // l.forEach(function(e)
					document.documentElement.addEventListener('touchend', function(eventTouch){touchEnd_(opts, eventTouch);}, false);
					window.addEventListener('scroll', function(){scroll_();}, false);
				} // if (l)
			}; // register = function(opts = noop.tooltip.defaults())
		}
	}; // noop.tooltip = new class Tooltip
	// #endregion Public

} // (function(noop, undefined)
(window.noop = window.noop || new class NOOP{}));

// EOF