xref: /plugin/autotooltip/script.js (revision d20b44e110fe1ced37d38eb1618637d407235810)
1/**
2 * Javascript for the autotooltip plugin.
3 *
4 * @type {{show:function, hide:function}}
5 */
6var autotooltip = function($) {
7	var timer;
8	var MAX_WIDTH = 500;
9	var moveCount = 0;
10	var isVisible;
11	var tt;
12
13	/**
14	 * Initialize the module.
15	 *
16	 * @private
17	 */
18	var _init = function() {
19		if (!tt) {
20			tt = $('<div class="plugin-autotooltip_tip" role="tooltip"></div>');
21			// Cover the various templates.
22			var container = $('.dokuwiki .bodyContent, .dokuwiki .wiki-content, #dokuwiki__content');
23			// Use the root .dokuwiki if we have to, though we might lose some font information.
24			if (!container.length) {
25				container = $('.dokuwiki');
26			}
27			// In case the template is really strange.
28			if (!container.length) {
29				container = $('body');
30			}
31			container.first().append(tt);
32		}
33
34		$(document).on('mousemove', _moveThrottled);
35		_init = function() {}; // Only once.
36	};
37
38
39	/**
40	 * Move the the tooltip to the current mouse position.
41	 *
42	 * @param {MouseEvent} e
43	 * @private
44	 */
45	var _move = function(e) {
46		var top = Math.max(e.pageY - window.scrollY - tt.outerHeight() - 4, 8);
47		var left = Math.max(e.pageX + 4, 8);
48		var right = '';
49		var winWidth = window.innerWidth;
50		var width;
51		if (winWidth - left < MAX_WIDTH && left > winWidth / 2) {
52			// Show left of the cursor.
53			left = '';
54			right = winWidth - e.pageX - 4;
55			width = Math.min(e.pageX - 4, MAX_WIDTH);
56		} else {
57			// Show right of the cursor.
58			left = left + 'px';
59			width = Math.min(winWidth - e.pageX - 4, MAX_WIDTH);
60		}
61
62		tt.css({top: top + 'px', left: left, right: right, width: 'auto', 'max-width': width + 'px'});
63	};
64
65	/**
66	 * Mousemove handler. When the mouse moves, so does the tooltip.
67	 *
68	 * @param {MouseEvent} e
69	 * @private
70	 */
71	var _moveThrottled = function(e) {
72		if (isVisible) {
73			var localMoveCount = ++moveCount;
74			requestAnimationFrame(function() {
75				if (localMoveCount == moveCount) {
76					_move(e);
77				}
78			});
79		}
80	};
81
82
83	/**
84	 * Show the tooltip with the given HTML.
85	 *
86	 * @param {MouseEvent} evt
87	 * @param {String} html - The HTML content of the tooltip.
88	 * @param {String} classes - CSS classes to add.
89	 * @param {int} delay - Delay, in ms.
90	 * @private
91	 */
92	var _show = function(evt, html, classes, delay) {
93		delay = parseInt(delay) || 50;
94		tt.html(html).attr('class', 'plugin-autotooltip_tip ' + classes);
95		_move(evt);
96		isVisible = true;
97		clearInterval(timer);
98		timer = setTimeout(function() {
99			tt.addClass('plugin-autotooltip--visible');
100		}, delay);
101	};
102
103
104	return {
105		/**
106		 * Show a tooltip.
107		 *
108		 * @param {MouseEvent} evt
109		 */
110		show: function(evt) {
111			var elt = evt.currentTarget;
112			_init();
113			_show(evt, $('.plugin-autotooltip-hidden-tip', elt).html(), $('.plugin-autotooltip-hidden-classes', elt).text(), $(elt).attr('data-delay'));
114		},
115
116
117		/**
118		 * Hide the tooltip.
119		 */
120		hide: function() {
121			isVisible = false;
122			timer = setTimeout(function() {
123				tt.removeClass('plugin-autotooltip--visible');
124			}, 50);
125		}
126	};
127}(jQuery);
128