# photonic/3.37/include/js/front-end/src/Components/Tooltip.js

Photonic Gallery &amp; Lightbox for Flickr, SmugMug &amp; Others, version 3.37. 122 lines.

- Page: https://pluginprobe.com/plugins/photonic/3.37/code/include/js/front-end/src/Components/Tooltip.js
- Raw: https://pluginprobe.com/plugins/photonic/3.37/raw/include/js/front-end/src/Components/Tooltip.js
- Modified: 2026-07-23T21:21:48+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/photonic/3.37/code/include/js/front-end/src/Components/Tooltip.js#L10-L20`.

```javascript
/*
 * Photonic Tooltip
 * License: MIT
 */

export const Tooltip = function (selector, tooltip_element) {
	let tooltip, tooltipClass, elemEdges, tooltipElems;

	// From https://locutus.io/php/strings/strip_tags/, or https://stackoverflow.com/questions/5601903/jquery-almost-equivalent-of-phps-strip-tags/46483672#46483672
	function strip_tags(input, allowed) {
		allowed = (((allowed || '') + '').toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join('')
		const tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi
		const commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi
		return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {
			return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''
		});
	}

	function create(tooltip, elm) {
		let tooltipText = elm.getAttribute('data-photonic-tooltip');
		tooltipText = strip_tags(tooltipText, '<br><strong><em><b><i><p>');

		if (tooltipText !== '') {
			elm.setAttribute('title', ''); // Blank out the regular title

			// elemEdges relative to the viewport.
			elemEdges = elm.getBoundingClientRect();

			const tooltipTextNode = document.createTextNode(tooltipText);
			tooltip.innerHTML = tooltipText; // ''; // Reset, or upon refresh the node gets repeated
			// tooltip.appendChild(tooltipTextNode);

			// Remove no-display + set the correct classname based on the position
			// of the elm.
			if (elemEdges.left > window.innerWidth - 100) {
				tooltip.className = 'photonic-tooltip-container tooltip-left';
			}
			else if ((elemEdges.left + (elemEdges.width / 2)) < 100) {
				tooltip.className = 'photonic-tooltip-container tooltip-right';
			}
			else {
				tooltip.className = 'photonic-tooltip-container tooltip-center';
			}
		}
	}

	function position(tooltip, elm) {
		const tooltipText = elm.getAttribute('data-photonic-tooltip');
		if (tooltipText !== '') {
			if (elemEdges === undefined) {
				elemEdges = elm.getBoundingClientRect();
			}

			// 10 = arrow height
			const elm_top = elemEdges.top + elemEdges.height + window.scrollY;
			const viewport_edges = window.innerWidth - 100;

			// Position tooltip on the left side of the elm if the elm touches
			// the viewports right edge and elm width is < 50px.
			if (elemEdges.left + window.scrollX > viewport_edges && elemEdges.width < 50) {
				tooltip.style.left = (elemEdges.left + window.scrollX - (tooltip.offsetWidth + elemEdges.width)) + 'px';
				tooltip.style.top = elm.offsetTop + 'px';
				// Position tooltip on the left side of the elm if the elm touches
				// the viewports right edge and elm width is > 50px.
			}
			else if (elemEdges.left + window.scrollX > viewport_edges && elemEdges.width > 50) {
				tooltip.style.left = (elemEdges.left + window.scrollX - tooltip.offsetWidth - 20) + 'px';
				tooltip.style.top = elm.offsetTop + 'px';
			}
			else if ((elemEdges.left + window.scrollX + (elemEdges.width / 2)) < 100) {
				// position tooltip on the right side of the elm.
				tooltip.style.left = (elemEdges.left + window.scrollX + elemEdges.width + 20) + 'px';
				tooltip.style.top = elm.offsetTop + 'px';
			}
			else {
				// Position the toolbox in the center of the elm.
				const centered = (elemEdges.left + window.scrollX + (elemEdges.width / 2)) - (tooltip.offsetWidth / 2);
				tooltip.style.left = centered + 'px';
				tooltip.style.top = elm_top + 'px';
			}
		}
	}

	function show(evt) {
		create(tooltip, evt.currentTarget);
		position(tooltip, evt.currentTarget);
	}

	function hide(evt) {
		tooltip.className = tooltipClass + ' no-display';
		if (tooltip.innerText !== '') {
			tooltip.removeChild(tooltip.firstChild);
			tooltip.removeAttribute('style');
			const element = evt.currentTarget;
			element.setAttribute('title', element.getAttribute('data-photonic-tooltip'));
		}
	}

	function init() {
		tooltipElems = document.documentElement.querySelectorAll(selector);
		tooltip = document.documentElement.querySelector(tooltip_element);
		tooltipClass = tooltip_element.replace(/^\.+/g, '');

		if (tooltip === null || tooltip.length === 0) {
			tooltip = document.createElement('div');
			tooltip.className = tooltipClass + ' no-display';
			document.body.appendChild(tooltip);
		}

		tooltipElems.forEach(elm => {
			elm.removeEventListener('mouseenter', show);
			elm.removeEventListener('mouseleave', hide);

			elm.addEventListener('mouseenter', show, false);
			elm.addEventListener('mouseleave', hide, false);
		});
	}

	init();
};


```
