1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
// Attach global hover handler for tooltips.
// Applies to all elements having a "data-tooltip" attribute.
// Tooltip may be provided in the data-attribute itself or by
// defining a title attribute. The latter is prefered due to
// the obvious accessibility issues.
let timeout = null;
STUDIP.Tooltip.threshold = 6;
$(document).on('mouseenter mouseleave focusin focusout', '[data-tooltip],.tooltip:has(.tooltip-content)', function(event) {
let data = $(this).data();
const inTopBar = $(this).parents('#top-bar').length > 0;
const visible = ['mouseenter', 'focusin'].includes(event.type);
const offset = $(this).offset();
const x = offset.left + $(this).outerWidth(true) / 2;
const y = inTopBar ? offset.top + 160 : offset.top;
const delay = data.tooltipDelay ?? 300;
const tooltipClasses = inTopBar ? 'studip-tooltip studip-tooltip-top' : '';
let content;
let tooltip;
if (!data.tooltipObject) {
// If tooltip has not yet been created (first hover), obtain it's
// contents and create the actual tooltip object.
if (!data.tooltip || !$.isPlainObject(data.tooltip)) {
content = $('<div/>').text(data.tooltip || $(this).attr('title')).html();
} else if (data.tooltip.html !== undefined) {
content = data.tooltip.html;
} else if (data.tooltip.text !== undefined) {
content = data.tooltip.text;
} else {
throw "Invalid content for tooltip via data";
}
if (!content) {
content = $(this).find('.tooltip-content').remove().html();
}
$(this).attr('title', null);
$(this).attr('data-tooltip', content);
tooltip = new STUDIP.Tooltip(x, y, content, tooltipClasses);
data.tooltipObject = tooltip;
if (!this.hasAttribute('aria-label')) {
const div = document.createElement('div');
div.innerHTML = content;
this.setAttribute('aria-label', div.innerText.trim());
}
$(this).on('remove', function() {
tooltip.remove();
});
} else if (visible) {
// If tooltip has already been created, update it's position.
// This is neccessary if the surrounding content is scrollable AND has
// been scrolled. Otherwise the tooltip would appear at it's previous
// and now wrong location.
data.tooltipObject.position(x, y);
}
if (visible) {
$('.studip-tooltip').not(data.tooltipObject).hide();
data.tooltipObject.show();
} else {
timeout = setTimeout(() => data.tooltipObject.hide(), delay);
}
}).on('mouseenter focusin', '.studip-tooltip', () => {
clearTimeout(timeout);
}).on('mouseleave focusout', '.studip-tooltip', function() {
$(this).hide();
});
|