1/**
2 * Tooltips populated by ajax request
3 *
4 * @author Michael Große
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 */
7
8jQuery(function initializeTooltips() {
9    'use strict';
10
11    function getLinkData($issueLink) {
12        return {
13            'issuelinks-service': $issueLink.data('service'),
14            'issuelinks-project': $issueLink.data('project'),
15            'issuelinks-issueid': $issueLink.data('issueid'),
16            'issuelinks-ismergerequest': $issueLink.data('ismergerequest'),
17            call: 'plugin_issuelinks',
18            'issuelinks-action': 'issueToolTip',
19            sectok: jQuery('input[name=sectok]').val(),
20        };
21    }
22
23    function addTooltip(selectorOr$element, url, dataOrDataFunction, complete) {
24        'use strict';
25
26        const serverEndpoint = url || window.DOKU_BASE + 'lib/exe/ajax.php';
27        const DELAY = 300;
28        const HOVER_DETECTION_DELAY = 100;
29        const TOOLTIP_PARENT_CLASS = 'hasTooltip';
30
31        function hoverStart() {
32            const $element = jQuery(this);
33            $element.addClass('hover');
34            if ($element.hasClass(TOOLTIP_PARENT_CLASS)) {
35                if ($element.data('MMtooltipID')) {
36                    const $tooltipDiv = jQuery('#' + $element.data('MMtooltipID'));
37                    $tooltipDiv.show().position({
38                        my: 'left top',
39                        at: 'left bottom',
40                        of: $element,
41                    }).attr('aria-hidden', 'false');
42                }
43                return;
44            }
45            const payload = typeof dataOrDataFunction === 'function' ? dataOrDataFunction($element) : dataOrDataFunction;
46            const timeOutReference = setTimeout(function getToolTip() {
47                const $div = jQuery('<div class="serverToolTip">')
48                    .uniqueId()
49                    .mouseleave(function hideTooltip() {
50                        $div.removeClass('hover');
51                        $div.hide().attr('aria-hidden', 'true');
52                    })
53                    .mouseenter(function allowJSHoverDetection() {
54                        $div.addClass('hover');
55                    });
56                $element.addClass(TOOLTIP_PARENT_CLASS);
57                jQuery.get(serverEndpoint, payload).done(function injectTooltip(response) {
58                    window.issuelinksUtil.showAjaxMessages(response);
59                    $div.html(response.data);
60                    $div.appendTo(jQuery('body'));
61                    $div.show().position({
62                        my: 'left top',
63                        at: 'left bottom',
64                        of: $element,
65                    });
66                    if (!$element.hasClass('hover')) {
67                        $div.hide();
68                    }
69                    $element.data('MMtooltipID', $div.attr('id'));
70                    if (typeof complete === 'function') {
71                        complete($element, $div);
72                    }
73                }).fail(function handleFailedState(jqXHR) {
74                    window.issuelinksUtil.showAjaxMessages(jqXHR.responseJSON);
75                    $div.remove();
76                });
77            }, DELAY);
78            $element.data('timeOutReference', timeOutReference);
79        }
80
81        function hoverEnd() {
82            const $this = jQuery(this);
83            $this.removeClass('hover');
84            clearTimeout($this.data('timeOutReference'));
85            if ($this.data('MMtooltipID')) {
86                setTimeout(function conditionalHideTooltip() {
87                    const $tooltip = jQuery('#' + $this.data('MMtooltipID'));
88                    if (!$tooltip.hasClass('hover')) {
89                        $tooltip.hide().attr('aria-hidden', 'true');
90                    }
91                }, HOVER_DETECTION_DELAY);
92            }
93        }
94
95        if (typeof selectorOr$element === 'string') {
96            jQuery(document).on('mouseenter', selectorOr$element, hoverStart);
97            jQuery(document).on('mouseleave', selectorOr$element, hoverEnd);
98        } else {
99            selectorOr$element.hover(hoverStart, hoverEnd);
100        }
101    }
102
103    addTooltip('.issuelink', undefined, getLinkData, function getAdditionalIssueData($issueLink, $tooltip) {
104        jQuery.get(window.DOKU_BASE + 'lib/exe/ajax.php', {
105            'issuelinks-service': $issueLink.data('service'),
106            'issuelinks-project': $issueLink.data('project'),
107            'issuelinks-issueid': $issueLink.data('issueid'),
108            'issuelinks-ismergerequest': $issueLink.data('ismergerequest'),
109            call: 'plugin_issuelinks',
110            'issuelinks-action': 'getAdditionalIssueData',
111            sectok: jQuery('input[name=sectok]').val(),
112        }).done(function updateIssueTooltip(response) {
113            const data = response.data;
114            window.issuelinksUtil.showAjaxMessages(response);
115            $tooltip.find('.waiting').removeClass('waiting');
116            if (typeof data.avatarHTML === 'string') {
117                $tooltip.find('.assigneeAvatar').html(data.avatarHTML);
118            }
119            if (typeof data.fancyLabelsHTML === 'string') {
120                $tooltip.find('.labels').html(data.fancyLabelsHTML);
121            }
122        }).fail(function handleFailedState(jqXHR) {
123            window.issuelinksUtil.showAjaxMessages(jqXHR.responseJSON);
124        });
125    });
126});
127