Difference between revisions of "MediaWiki:Common.js"
| Line 1: | Line 1: | ||
| + | .meter.open .metertext, | ||
| + | .parallel.open .paralleltext, | ||
| + | .commentary.open .commentarytext, | ||
| + | .pictures.open .picturestext, | ||
| + | .outline.open .outlinetext, | ||
| + | .comment.open .commenttext, | ||
| + | .word.open .wordtext | ||
| + | { | ||
| + | display: block; | ||
| + | position: absolute; | ||
| + | top: 100%; | ||
| + | left: 0; | ||
| + | right: auto; | ||
| + | margin-top: 0; | ||
| + | transform: translateY(var(--popup-offset, 0px)); | ||
| + | border: 2px dotted darkslategray; | ||
| + | padding: 1em; | ||
| + | background-color:rgb(255,255,255); | ||
| + | z-index: 500; | ||
| + | width: var(--popup-width, 70vw); | ||
| + | max-width: var(--popup-width, 70vw); | ||
| + | min-width: 0; | ||
| + | box-sizing: border-box; | ||
| + | overflow-wrap: break-word; | ||
| + | } | ||
| + | |||
| + | Then replace the JavaScript with: | ||
| + | |||
(function () { | (function () { | ||
var iconSelector = | var iconSelector = | ||
| Line 6: | Line 34: | ||
'.metertext, .paralleltext, .commentarytext, ' + | '.metertext, .paralleltext, .commentarytext, ' + | ||
'.picturestext, .outlinetext, .commenttext, .wordtext'; | '.picturestext, .outlinetext, .commenttext, .wordtext'; | ||
| − | |||
| − | |||
function updateWidth(icon) { | function updateWidth(icon) { | ||
var viewportWidth = document.documentElement.clientWidth; | var viewportWidth = document.documentElement.clientWidth; | ||
| − | var | + | var iconLeft = icon.getBoundingClientRect().left; |
| − | + | var availableWidth = viewportWidth - iconLeft - 16; | |
icon.style.setProperty( | icon.style.setProperty( | ||
| Line 18: | Line 44: | ||
Math.max(0, Math.min(viewportWidth * 0.7, availableWidth)) + 'px' | Math.max(0, Math.min(viewportWidth * 0.7, availableWidth)) + 'px' | ||
); | ); | ||
| + | } | ||
| + | |||
| + | function arrangePopups() { | ||
| + | var openIcons = Array.from( | ||
| + | document.querySelectorAll(iconSelector) | ||
| + | ).filter(function (icon) { | ||
| + | return icon.classList.contains('open'); | ||
| + | }); | ||
| + | |||
| + | openIcons.forEach(function (icon) { | ||
| + | icon.style.setProperty('--popup-offset', '0px'); | ||
| + | updateWidth(icon); | ||
| + | }); | ||
| + | |||
| + | var placedPanels = []; | ||
| + | |||
| + | openIcons.forEach(function (icon) { | ||
| + | var panel = icon.querySelector(panelSelector); | ||
| + | |||
| + | if (!panel) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | var offset = 0; | ||
| + | var panelRect = panel.getBoundingClientRect(); | ||
| + | |||
| + | placedPanels.forEach(function (previousRect) { | ||
| + | var overlapsHorizontally = | ||
| + | panelRect.left < previousRect.right && | ||
| + | panelRect.right > previousRect.left; | ||
| + | |||
| + | var overlapsVertically = | ||
| + | panelRect.top < previousRect.bottom && | ||
| + | panelRect.bottom > previousRect.top; | ||
| + | |||
| + | if (overlapsHorizontally && overlapsVertically) { | ||
| + | offset = Math.max( | ||
| + | offset, | ||
| + | previousRect.bottom - panelRect.top + 8 | ||
| + | ); | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | icon.style.setProperty( | ||
| + | '--popup-offset', | ||
| + | offset + 'px' | ||
| + | ); | ||
| + | |||
| + | placedPanels.push(panel.getBoundingClientRect()); | ||
| + | }); | ||
} | } | ||
| Line 33: | Line 109: | ||
} | } | ||
| − | + | icon.classList.toggle('open'); | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | + | requestAnimationFrame(arrangePopups); | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
}); | }); | ||
window.addEventListener('resize', function () { | window.addEventListener('resize', function () { | ||
| − | + | requestAnimationFrame(arrangePopups); | |
| − | |||
| − | |||
}); | }); | ||
})(); | })(); | ||
Revision as of 17:07, 24 July 2026
.meter.open .metertext,
.parallel.open .paralleltext,
.commentary.open .commentarytext,
.pictures.open .picturestext,
.outline.open .outlinetext,
.comment.open .commenttext,
.word.open .wordtext
{
display: block;
position: absolute;
top: 100%;
left: 0;
right: auto;
margin-top: 0;
transform: translateY(var(--popup-offset, 0px));
border: 2px dotted darkslategray;
padding: 1em;
background-color:rgb(255,255,255);
z-index: 500;
width: var(--popup-width, 70vw);
max-width: var(--popup-width, 70vw);
min-width: 0;
box-sizing: border-box;
overflow-wrap: break-word;
}
Then replace the JavaScript with:
(function () {
var iconSelector =
'.meter, .parallel, .commentary, .pictures, .outline, .comment, .word';
var panelSelector =
'.metertext, .paralleltext, .commentarytext, ' +
'.picturestext, .outlinetext, .commenttext, .wordtext';
function updateWidth(icon) {
var viewportWidth = document.documentElement.clientWidth;
var iconLeft = icon.getBoundingClientRect().left;
var availableWidth = viewportWidth - iconLeft - 16;
icon.style.setProperty(
'--popup-width',
Math.max(0, Math.min(viewportWidth * 0.7, availableWidth)) + 'px'
);
}
function arrangePopups() {
var openIcons = Array.from(
document.querySelectorAll(iconSelector)
).filter(function (icon) {
return icon.classList.contains('open');
});
openIcons.forEach(function (icon) {
icon.style.setProperty('--popup-offset', '0px');
updateWidth(icon);
});
var placedPanels = [];
openIcons.forEach(function (icon) {
var panel = icon.querySelector(panelSelector);
if (!panel) {
return;
}
var offset = 0;
var panelRect = panel.getBoundingClientRect();
placedPanels.forEach(function (previousRect) {
var overlapsHorizontally =
panelRect.left < previousRect.right &&
panelRect.right > previousRect.left;
var overlapsVertically =
panelRect.top < previousRect.bottom &&
panelRect.bottom > previousRect.top;
if (overlapsHorizontally && overlapsVertically) {
offset = Math.max(
offset,
previousRect.bottom - panelRect.top + 8
);
}
});
icon.style.setProperty(
'--popup-offset',
offset + 'px'
);
placedPanels.push(panel.getBoundingClientRect());
});
}
document.addEventListener('click', function (event) {
var icon = event.target.closest(iconSelector);
if (!icon) {
return;
}
var panel = icon.querySelector(panelSelector);
if (panel && panel.contains(event.target)) {
return;
}
icon.classList.toggle('open');
requestAnimationFrame(arrangePopups);
});
window.addEventListener('resize', function () {
requestAnimationFrame(arrangePopups);
});
})();