MediaWiki:Common.js: Difference between revisions
MediaWiki interface page
More actions
Jonatanktk (talk | contribs) No edit summary |
Jonatanktk (talk | contribs) No edit summary |
||
| (One intermediate revision by the same user not shown) | |||
| Line 6: | Line 6: | ||
'use strict'; | 'use strict'; | ||
// Tooltip erstellen | |||
const tooltip = document.createElement('div'); | const tooltip = document.createElement('div'); | ||
tooltip.id = 'citizen-tooltip'; | |||
Object.assign(tooltip.style, { | Object.assign(tooltip.style, { | ||
position: 'absolute', | position: 'absolute', | ||
zIndex: 999999, | zIndex: 999999, | ||
padding: '10px 14px', | |||
borderRadius: '8px', | |||
maxWidth: '240px', | |||
wordWrap: 'break-word', | |||
fontSize: '13px', | fontSize: '13px', | ||
lineHeight: '1.4', | lineHeight: '1.4', | ||
pointerEvents: 'none', | pointerEvents: 'none', | ||
opacity: '0', | opacity: '0', | ||
transition: 'opacity 0. | transform: 'translateY(4px)', | ||
transition: 'opacity 0.25s ease, transform 0.25s ease', | |||
boxShadow: '0 4px 12px rgba(0,0,0,0.3)', | |||
backdropFilter: 'blur(6px)', | |||
backgroundColor: 'var(--citizen-tooltip-bg, rgba(25,25,25,0.95))', | |||
color: 'var(--citizen-tooltip-text, #fff)', | |||
}); | }); | ||
document.body.appendChild(tooltip); | document.body.appendChild(tooltip); | ||
// Pfeil | |||
const arrow = document.createElement('div'); | const arrow = document.createElement('div'); | ||
Object.assign(arrow.style, { | Object.assign(arrow.style, { | ||
| Line 29: | Line 35: | ||
width: '0', | width: '0', | ||
height: '0', | height: '0', | ||
borderLeft: ' | borderLeft: '7px solid transparent', | ||
borderRight: ' | borderRight: '7px solid transparent', | ||
borderTop: ' | borderTop: '7px solid var(--citizen-tooltip-bg, rgba(25,25,25,0.95))', | ||
pointerEvents: 'none', | pointerEvents: 'none', | ||
}); | }); | ||
| Line 51: | Line 57: | ||
tooltip.appendChild(arrow); | tooltip.appendChild(arrow); | ||
tooltip.style.opacity = '0'; | tooltip.style.opacity = '0'; | ||
tooltip.style.transform = 'translateY(4px)'; | |||
// Animation / Bounce | |||
requestAnimationFrame(() => { | requestAnimationFrame(() => { | ||
positionTooltip(el); | positionTooltip(el); | ||
tooltip.style.opacity = '1'; | tooltip.style.opacity = '1'; | ||
tooltip.style.transform = 'translateY(0)'; | |||
}); | }); | ||
| Line 63: | Line 72: | ||
if (!activeEl) return; | if (!activeEl) return; | ||
tooltip.style.opacity = '0'; | tooltip.style.opacity = '0'; | ||
tooltip.style.transform = 'translateY(4px)'; | |||
activeEl.setAttribute('title', storedTitle); | activeEl.setAttribute('title', storedTitle); | ||
activeEl = null; | activeEl = null; | ||
| Line 71: | Line 81: | ||
const rect = el.getBoundingClientRect(); | const rect = el.getBoundingClientRect(); | ||
const ttRect = tooltip.getBoundingClientRect(); | const ttRect = tooltip.getBoundingClientRect(); | ||
const spacing = | const spacing = 8; | ||
const spaceAbove = rect.top; | const spaceAbove = rect.top; | ||
| Line 78: | Line 88: | ||
const spaceRight = window.innerWidth - rect.right; | const spaceRight = window.innerWidth - rect.right; | ||
let position = 'top'; | let position = 'top'; | ||
if (spaceAbove < ttRect.height + spacing && spaceBelow > ttRect.height + spacing) position = 'bottom'; | if (spaceAbove < ttRect.height + spacing && spaceBelow > ttRect.height + spacing) position = 'bottom'; | ||
if (spaceRight > ttRect.width + spacing && rect.left < 50) position = 'right'; | if (spaceRight > ttRect.width + spacing && rect.left < 50) position = 'right'; | ||
if (spaceLeft > ttRect.width + spacing && rect.right > window.innerWidth - 50) position = 'left'; | if (spaceLeft > ttRect.width + spacing && rect.right > window.innerWidth - 50) position = 'left'; | ||
let top, left; | let top, left; | ||
switch(position) { | switch(position) { | ||
case 'top': | case 'top': | ||
| Line 102: | Line 108: | ||
left = rect.left + rect.width/2 - ttRect.width/2; | left = rect.left + rect.width/2 - ttRect.width/2; | ||
Object.assign(arrow.style, { | Object.assign(arrow.style, { | ||
top: '- | top: '-7px', | ||
left: '50%', | left: '50%', | ||
transform: 'translateX(-50%) rotate(180deg)' | transform: 'translateX(-50%) rotate(180deg)' | ||
| Line 112: | Line 118: | ||
Object.assign(arrow.style, { | Object.assign(arrow.style, { | ||
top: '50%', | top: '50%', | ||
left: '- | left: '-7px', | ||
transform: 'translateY(-50%) rotate(90deg)' | transform: 'translateY(-50%) rotate(90deg)' | ||
}); | }); | ||
Latest revision as of 23:59, 1 November 2025
/* Any JavaScript here will be loaded for all users on every page load. */
/* Schönes Tooltip-System auf Basis von alt-Attributen
Funktioniert sicher mit Citizen & MediaWiki UI */
(function() {
'use strict';
// Tooltip erstellen
const tooltip = document.createElement('div');
tooltip.id = 'citizen-tooltip';
Object.assign(tooltip.style, {
position: 'absolute',
zIndex: 999999,
padding: '10px 14px',
borderRadius: '8px',
maxWidth: '240px',
wordWrap: 'break-word',
fontSize: '13px',
lineHeight: '1.4',
pointerEvents: 'none',
opacity: '0',
transform: 'translateY(4px)',
transition: 'opacity 0.25s ease, transform 0.25s ease',
boxShadow: '0 4px 12px rgba(0,0,0,0.3)',
backdropFilter: 'blur(6px)',
backgroundColor: 'var(--citizen-tooltip-bg, rgba(25,25,25,0.95))',
color: 'var(--citizen-tooltip-text, #fff)',
});
document.body.appendChild(tooltip);
// Pfeil
const arrow = document.createElement('div');
Object.assign(arrow.style, {
position: 'absolute',
width: '0',
height: '0',
borderLeft: '7px solid transparent',
borderRight: '7px solid transparent',
borderTop: '7px solid var(--citizen-tooltip-bg, rgba(25,25,25,0.95))',
pointerEvents: 'none',
});
tooltip.appendChild(arrow);
let activeEl = null;
let storedTitle = null;
function showTooltip(e) {
const el = e.target.closest('[title]');
if (!el) return;
storedTitle = el.getAttribute('title');
if (!storedTitle) return;
activeEl = el;
el.removeAttribute('title');
tooltip.textContent = storedTitle;
tooltip.appendChild(arrow);
tooltip.style.opacity = '0';
tooltip.style.transform = 'translateY(4px)';
// Animation / Bounce
requestAnimationFrame(() => {
positionTooltip(el);
tooltip.style.opacity = '1';
tooltip.style.transform = 'translateY(0)';
});
el.addEventListener('mouseleave', hideTooltip, { once: true });
}
function hideTooltip() {
if (!activeEl) return;
tooltip.style.opacity = '0';
tooltip.style.transform = 'translateY(4px)';
activeEl.setAttribute('title', storedTitle);
activeEl = null;
storedTitle = null;
}
function positionTooltip(el) {
const rect = el.getBoundingClientRect();
const ttRect = tooltip.getBoundingClientRect();
const spacing = 8;
const spaceAbove = rect.top;
const spaceBelow = window.innerHeight - rect.bottom;
const spaceLeft = rect.left;
const spaceRight = window.innerWidth - rect.right;
let position = 'top';
if (spaceAbove < ttRect.height + spacing && spaceBelow > ttRect.height + spacing) position = 'bottom';
if (spaceRight > ttRect.width + spacing && rect.left < 50) position = 'right';
if (spaceLeft > ttRect.width + spacing && rect.right > window.innerWidth - 50) position = 'left';
let top, left;
switch(position) {
case 'top':
top = rect.top - ttRect.height - spacing;
left = rect.left + rect.width/2 - ttRect.width/2;
Object.assign(arrow.style, {
top: '100%',
left: '50%',
transform: 'translateX(-50%) rotate(0deg)'
});
break;
case 'bottom':
top = rect.bottom + spacing;
left = rect.left + rect.width/2 - ttRect.width/2;
Object.assign(arrow.style, {
top: '-7px',
left: '50%',
transform: 'translateX(-50%) rotate(180deg)'
});
break;
case 'right':
top = rect.top + rect.height/2 - ttRect.height/2;
left = rect.right + spacing;
Object.assign(arrow.style, {
top: '50%',
left: '-7px',
transform: 'translateY(-50%) rotate(90deg)'
});
break;
case 'left':
top = rect.top + rect.height/2 - ttRect.height/2;
left = rect.left - ttRect.width - spacing;
Object.assign(arrow.style, {
top: '50%',
left: '100%',
transform: 'translateY(-50%) rotate(-90deg)'
});
break;
}
// Clamp an Viewport
if (left < 4) left = 4;
if (left + ttRect.width > window.innerWidth - 4)
left = window.innerWidth - ttRect.width - 4;
if (top < 4) top = 4;
if (top + ttRect.height > window.innerHeight - 4)
top = window.innerHeight - ttRect.height - 4;
tooltip.style.top = `${top + window.scrollY}px`;
tooltip.style.left = `${left + window.scrollX}px`;
}
document.addEventListener('mouseover', showTooltip);
})();