Difference between revisions of "MediaWiki:Common.js"

From Waltharius
Jump to: navigation, search
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';
 
    var openIcon = null;
 
  
 
     function updateWidth(icon) {
 
     function updateWidth(icon) {
 
         var viewportWidth = document.documentElement.clientWidth;
 
         var viewportWidth = document.documentElement.clientWidth;
         var availableWidth =
+
         var iconLeft = icon.getBoundingClientRect().left;
            viewportWidth - icon.getBoundingClientRect().left - 16;
+
        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:
 
         }
 
         }
  
         if (icon === openIcon) {
+
         icon.classList.toggle('open');
            icon.classList.remove('open');
 
            openIcon = null;
 
            return;
 
        }
 
  
         if (openIcon) {
+
         requestAnimationFrame(arrangePopups);
            openIcon.classList.remove('open');
 
        }
 
 
 
        updateWidth(icon);
 
        icon.classList.add('open');
 
        openIcon = icon;
 
 
     });
 
     });
  
 
     window.addEventListener('resize', function () {
 
     window.addEventListener('resize', function () {
         if (openIcon) {
+
         requestAnimationFrame(arrangePopups);
            updateWidth(openIcon);
 
        }
 
 
     });
 
     });
 
})();
 
})();

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);
    });
})();