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