PluginProbe
Photonic Gallery & Lightbox for Flickr, SmugMug & Others / 3.33
Photonic Gallery & Lightbox for Flickr, SmugMug & Others v3.33
3.36 3.35 3.34 3.33 2.19 2.20 2.21 2.22 2.23 2.24 2.25 2.26 2.27 2.28 2.29 2.30 2.31 2.32 2.33 2.34 2.40 2.41 2.42 2.43 2.44 All 141 releases
photonic / include / js / front-end / src / Components / Tooltip.js

Tooltip.js in Photonic Gallery & Lightbox for Flickr, SmugMug & Others 3.33, at include/js/front-end/src/Components/Tooltip.js

120 lines 4.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*
2 * Photonic Tooltip
3 * License: MIT
4 */
5
6 export const Tooltip = function (selector, tooltip_element) {
7 let tooltip, tooltipClass, elemEdges, tooltipElems;
8
9 // From https://locutus.io/php/strings/strip_tags/, or https://stackoverflow.com/questions/5601903/jquery-almost-equivalent-of-phps-strip-tags/46483672#46483672
10 function strip_tags(input, allowed) {
11 allowed = (((allowed || '') + '').toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join('')
12 const tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi
13 const commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi
14 return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {
15 return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''
16 });
17 }
18
19 function create(tooltip, elm) {
20 const tooltipText = elm.getAttribute('data-photonic-tooltip');
21 if (tooltipText !== '') {
22 elm.setAttribute('title', ''); // Blank out the regular title
23
24 // elemEdges relative to the viewport.
25 elemEdges = elm.getBoundingClientRect();
26
27 const tooltipTextNode = document.createTextNode(tooltipText);
28 tooltip.innerHTML = ''; // Reset, or upon refresh the node gets repeated
29 tooltip.appendChild(tooltipTextNode);
30
31 // Remove no-display + set the correct classname based on the position
32 // of the elm.
33 if (elemEdges.left > window.innerWidth - 100) {
34 tooltip.className = 'photonic-tooltip-container tooltip-left';
35 }
36 else if ((elemEdges.left + (elemEdges.width / 2)) < 100) {
37 tooltip.className = 'photonic-tooltip-container tooltip-right';
38 }
39 else {
40 tooltip.className = 'photonic-tooltip-container tooltip-center';
41 }
42 }
43 }
44
45 function position(tooltip, elm) {
46 const tooltipText = elm.getAttribute('data-photonic-tooltip');
47 if (tooltipText !== '') {
48 if (elemEdges === undefined) {
49 elemEdges = elm.getBoundingClientRect();
50 }
51
52 // 10 = arrow height
53 const elm_top = elemEdges.top + elemEdges.height + window.scrollY;
54 const viewport_edges = window.innerWidth - 100;
55
56 // Position tooltip on the left side of the elm if the elm touches
57 // the viewports right edge and elm width is < 50px.
58 if (elemEdges.left + window.scrollX > viewport_edges && elemEdges.width < 50) {
59 tooltip.style.left = (elemEdges.left + window.scrollX - (tooltip.offsetWidth + elemEdges.width)) + 'px';
60 tooltip.style.top = elm.offsetTop + 'px';
61 // Position tooltip on the left side of the elm if the elm touches
62 // the viewports right edge and elm width is > 50px.
63 }
64 else if (elemEdges.left + window.scrollX > viewport_edges && elemEdges.width > 50) {
65 tooltip.style.left = (elemEdges.left + window.scrollX - tooltip.offsetWidth - 20) + 'px';
66 tooltip.style.top = elm.offsetTop + 'px';
67 }
68 else if ((elemEdges.left + window.scrollX + (elemEdges.width / 2)) < 100) {
69 // position tooltip on the right side of the elm.
70 tooltip.style.left = (elemEdges.left + window.scrollX + elemEdges.width + 20) + 'px';
71 tooltip.style.top = elm.offsetTop + 'px';
72 }
73 else {
74 // Position the toolbox in the center of the elm.
75 const centered = (elemEdges.left + window.scrollX + (elemEdges.width / 2)) - (tooltip.offsetWidth / 2);
76 tooltip.style.left = centered + 'px';
77 tooltip.style.top = elm_top + 'px';
78 }
79 }
80 }
81
82 function show(evt) {
83 create(tooltip, evt.currentTarget);
84 position(tooltip, evt.currentTarget);
85 }
86
87 function hide(evt) {
88 tooltip.className = tooltipClass + ' no-display';
89 if (tooltip.innerText !== '') {
90 tooltip.removeChild(tooltip.firstChild);
91 tooltip.removeAttribute('style');
92 const element = evt.currentTarget;
93 element.setAttribute('title', element.getAttribute('data-photonic-tooltip'));
94 }
95 }
96
97 function init() {
98 tooltipElems = document.documentElement.querySelectorAll(selector);
99 tooltip = document.documentElement.querySelector(tooltip_element);
100 tooltipClass = tooltip_element.replace(/^\.+/g, '');
101
102 if (tooltip === null || tooltip.length === 0) {
103 tooltip = document.createElement('div');
104 tooltip.className = tooltipClass + ' no-display';
105 document.body.appendChild(tooltip);
106 }
107
108 tooltipElems.forEach(elm => {
109 elm.removeEventListener('mouseenter', show);
110 elm.removeEventListener('mouseleave', hide);
111
112 elm.addEventListener('mouseenter', show, false);
113 elm.addEventListener('mouseleave', hide, false);
114 });
115 }
116
117 init();
118 };
119
120