diff --git a/tonalmine/javascripts/theme.js b/tonalmine/javascripts/theme.js
index 755c7c8..9dc6cd2 100644
--- a/tonalmine/javascripts/theme.js
+++ b/tonalmine/javascripts/theme.js
@@ -133,6 +133,40 @@
});
});
+ // Calendar/Gantt hover cards: Redmine renders "Tracker #id: subject
" followed by
+ // "Label: value
" lines. Regroup them on first hover into a title and a
+ // label/value grid (nodes are moved, not re-parsed, so links and avatars stay intact).
+ function structureTip(tip) {
+ var lines = [[]];
+ Array.prototype.slice.call(tip.childNodes).forEach(function (node) {
+ if (node.nodeName === 'BR') lines.push([]);
+ else if (node.nodeType !== 3 || node.nodeValue.trim()) lines[lines.length - 1].push(node);
+ });
+ var title = document.createElement('span');
+ var fields = document.createElement('span');
+ title.className = 'nm-tip__title';
+ fields.className = 'nm-tip__fields';
+ lines.filter(function (line) { return line.length; }).forEach(function (line, i) {
+ var head = line[0];
+ var value = document.createElement('span');
+ line.slice(1).forEach(function (node) { value.appendChild(node); });
+ if (value.firstChild && value.firstChild.nodeType === 3) {
+ value.firstChild.nodeValue = value.firstChild.nodeValue.replace(/^\s*:\s*/, '');
+ }
+ var target = i > 0 && head.nodeName === 'STRONG' ? fields : title;
+ target.appendChild(head);
+ target.appendChild(value);
+ });
+ tip.replaceChildren(title, fields);
+ tip.classList.add('nm-tip');
+ }
+
+ document.addEventListener('mouseover', function (event) {
+ var tip = event.target.closest && event.target.closest('div.tooltip');
+ tip = tip && tip.querySelector(':scope > span.tip:not(.nm-tip)');
+ if (tip) structureTip(tip);
+ });
+
document.addEventListener('DOMContentLoaded', function () {
var menu = document.querySelector('#account .dropdown-content .dropdown-divider');
if (menu) menu.insertAdjacentHTML('afterend', pickerHtml() + '