This commit is contained in:
2026-05-28 21:46:47 +02:00
parent a8978e232f
commit d1b0e3542c
3 changed files with 28 additions and 17 deletions

View File

@@ -3088,31 +3088,27 @@ body.layout-legacy .scroll-to-bottom svg {
} }
/* Ensure spoilers properly envelope media */ /* Ensure spoilers properly envelope media */
.spoiler:has(img, video, iframe, audio) {
display: inline-block;
max-width: 100%;
}
.spoiler:has(.vocaroo-embed-wrap, .video-embed-wrap, .yt-embed-wrap, .audio-embed-wrap, img, video, iframe, audio) { .spoiler:has(.vocaroo-embed-wrap, .video-embed-wrap, .yt-embed-wrap, .audio-embed-wrap, img, video, iframe, audio) {
display: inline-grid; display: inline-block;
grid-auto-flow: column; width: max-content;
max-width: 100%; max-width: 100%;
vertical-align: middle; vertical-align: middle;
} }
.spoiler .vocaroo-embed-wrap, .spoiler .vocaroo-embed-wrap,
.spoiler .video-embed-wrap, .spoiler .video-embed-wrap,
.spoiler .yt-embed-wrap,
.spoiler .audio-embed-wrap { .spoiler .audio-embed-wrap {
display: inline-block; display: inline-block !important;
vertical-align: middle; vertical-align: middle;
width: auto; width: auto !important;
max-width: 100%; max-width: 480px;
margin: 4px 2px; margin: 4px 2px;
} }
.spoiler .yt-embed-wrap { .spoiler .yt-embed-wrap {
display: inline-block !important;
width: 480px; width: 480px;
max-width: 100%;
/* YouTube needs a base width for the aspect ratio padding trick */ /* YouTube needs a base width for the aspect ratio padding trick */
} }
@@ -7867,7 +7863,8 @@ video.autoplay-gif {
.image-embed-wrap { .image-embed-wrap {
position: relative; position: relative;
display: inline-block; display: inline-block;
max-width: 100%; width: 100%;
max-width: 480px;
} }
.admin-delete-attachment-btn { .admin-delete-attachment-btn {
@@ -8445,9 +8442,9 @@ span.badge.badge-current {
.comment-content img { .comment-content img {
/*max-height: 200px;*/ /*max-height: 200px;*/
max-width: 100%; max-width: 480px;
width: 100%;
border-radius: 4px; border-radius: 4px;
} }
/*.sidebar-comment-img { /*.sidebar-comment-img {
@@ -8490,6 +8487,8 @@ span.badge.badge-current {
.comment-content img:not(.emoji) { .comment-content img:not(.emoji) {
display: block; display: block;
cursor: pointer; cursor: pointer;
max-width: 480px;
width: 100%;
} }
/* Smaller emojis in the narrow left sidebar */ /* Smaller emojis in the narrow left sidebar */

View File

@@ -1669,7 +1669,7 @@ class CommentSystem {
}); });
} }
const hostsRegexPart = allowedHosts.join('|'); const hostsRegexPart = allowedHosts.join('|');
const domainOrRelative = `(?:(?:https?:\\/\\/|\\/\\/)?(?:${hostsRegexPart})|(?<!\\S)(?=\\/[a-zA-Z0-9_\\-]))`; const domainOrRelative = `(?:(?:https?:\\/\\/|\\/\\/)?(?:${hostsRegexPart})|(?:(?<!\\S)|(?<=\\]))(?=\\/[a-zA-Z0-9_\\-]))`;
// "Safe non-whitespace" — matches any \S except the start of an https?:// boundary. // "Safe non-whitespace" — matches any \S except the start of an https?:// boundary.
// Prevents concatenated URLs (url1.webpurl2.webp) being consumed as one giant src. // Prevents concatenated URLs (url1.webpurl2.webp) being consumed as one giant src.

View File

@@ -8481,8 +8481,9 @@ document.addEventListener('DOMContentLoaded', () => {
resetTransform(); resetTransform();
}; };
// Expose globally for guaranteed navigation cleanup // Expose globally for guaranteed navigation cleanup and spoiler integration
window.closeImageModal = closeImageModal; window.closeImageModal = closeImageModal;
window.openImageModal = openImageModal;
// Zoom Logic // Zoom Logic
const handleWheel = (e) => { const handleWheel = (e) => {
@@ -8653,9 +8654,12 @@ document.addEventListener('DOMContentLoaded', () => {
return; return;
} }
// Comment embedded images → open in image modal (skip emoji images) // Comment embedded images → open in image modal (skip emoji images, skip unrevealed spoilers)
const commentImg = e.target.closest('.comment-content img, .comment-attachments img'); const commentImg = e.target.closest('.comment-content img, .comment-attachments img');
if (commentImg && !commentImg.classList.contains('emoji')) { if (commentImg && !commentImg.classList.contains('emoji')) {
// If this image is inside an unrevealed spoiler, let the spoiler handler deal with it
const parentSpoiler = commentImg.closest('.spoiler');
if (parentSpoiler && !parentSpoiler.classList.contains('revealed')) return;
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
openImageModal(commentImg.src); openImageModal(commentImg.src);
@@ -9108,6 +9112,14 @@ if (navigator.vibrate) {
return; return;
} }
// Spoiler is already revealed — check if the click is on an image
const clickedImg = path.find(el => el.tagName === 'IMG' && !el.classList.contains('emoji'));
if (clickedImg && typeof window.openImageModal === 'function') {
// Let the click event through; the image modal handler will pick it up.
// We just need to make sure we don't re-hide the spoiler.
return;
}
// Only handle re-hiding on the container itself or non-interactive parts // Only handle re-hiding on the container itself or non-interactive parts
const interactive = path.find(el => const interactive = path.find(el =>
el.tagName === 'A' || el.tagName === 'VIDEO' || el.tagName === 'AUDIO' || el.tagName === 'A' || el.tagName === 'VIDEO' || el.tagName === 'AUDIO' ||