thumbnails: Reference media anchors, images, and video by class.

This commit is contained in:
Karl Stolley
2025-04-08 15:00:13 -05:00
committed by Tim Abbott
parent 1dc87be1db
commit 4e19e82f64
3 changed files with 57 additions and 27 deletions

View File

@@ -52,6 +52,26 @@ export function postprocess_content(html: string): string {
elt.removeAttribute("target"); elt.removeAttribute("target");
} }
if (elt.querySelector("img") || elt.querySelector("video")) {
// We want a class to refer to media links
elt.classList.add("media-anchor-element");
// Add a class to the video, if it exists
if (elt.querySelector("video")) {
elt.querySelector("video")?.classList.add("media-video-element");
}
// Add a class to the image, if it exists
if (elt.querySelector("img")) {
elt.querySelector("img")?.classList.add("media-image-element");
}
}
if (elt.querySelector("video")) {
// We want a class to refer to media links
elt.classList.add("media-anchor-element");
// And likewise a class to refer to image elements
elt.querySelector("video")?.classList.add("media-image-element");
}
// Update older, smaller default.jpg YouTube preview images // Update older, smaller default.jpg YouTube preview images
// with higher-quality preview images (320px wide) // with higher-quality preview images (320px wide)
if (elt.parentElement?.classList.contains("youtube-video")) { if (elt.parentElement?.classList.contains("youtube-video")) {

View File

@@ -460,7 +460,7 @@
background: hsl(0deg 0% 0% / 15%); background: hsl(0deg 0% 0% / 15%);
} }
& a { & .media-anchor-element {
display: block; display: block;
height: 100%; height: 100%;
width: 100%; width: 100%;
@@ -522,8 +522,8 @@
} }
p:first-child > .katex-display > .katex, p:first-child > .katex-display > .katex,
.message_inline_image a, .message_inline_image .media-anchor-element,
.message_inline_image video { .message_inline_image .media-video-element {
/* We explicitly place the containing /* We explicitly place the containing
media element in the thumbnail area. */ media element in the thumbnail area. */
grid-area: media; grid-area: media;
@@ -575,9 +575,9 @@
margin-right: 5px; margin-right: 5px;
} }
.twitter-image img, .twitter-image .media-image-element,
.message_inline_image img, .message_inline_image .media-image-element,
.message_inline_ref img { .message_inline_ref .media-image-element {
/* We use `scale-down` so that images smaller than the container are /* We use `scale-down` so that images smaller than the container are
neither scaled up nor cropped to fit. This preserves neither scaled up nor cropped to fit. This preserves
their aspect ratio, which is often helpful. */ their aspect ratio, which is often helpful. */
@@ -595,17 +595,17 @@
border-radius: inherit; border-radius: inherit;
} }
.message_inline_image img { .message_inline_image .media-image-element {
cursor: zoom-in; cursor: zoom-in;
} }
.youtube-video img, .youtube-video .media-image-element,
.vimeo-video img, .vimeo-video .media-image-element,
.embed-video img { .embed-video .media-image-element {
cursor: pointer; cursor: pointer;
} }
.youtube-video img { .youtube-video .media-image-element {
/* We do this for the sake of increasing /* We do this for the sake of increasing
the size of older YouTube thumbnail the size of older YouTube thumbnail
previews, but there are no ill effects previews, but there are no ill effects
@@ -613,21 +613,21 @@
object-fit: contain; object-fit: contain;
} }
&.rtl .twitter-image img, &.rtl .twitter-image .media-image-element,
&.rtl .message_inline_image img, &.rtl .message_inline_image .media-image-element,
&.rtl .message_inline_ref img { &.rtl .message_inline_ref .media-image-element {
float: right; float: right;
margin-right: unset; margin-right: unset;
margin-left: 10px; margin-left: 10px;
} }
& li .message_inline_image img { & li .message_inline_image .media-image-element {
float: none; float: none;
} }
.message_inline_video, .message_inline_video,
.message_inline_animated_image_still, .message_inline_animated_image_still,
.youtube-video a[data-id] { .youtube-video .media-anchor-element {
&:hover { &:hover {
&::after { &::after {
transform: scale(1); transform: scale(1);
@@ -659,7 +659,7 @@
transition: transform 0.2s; transition: transform 0.2s;
} }
& video { & .media-video-element {
display: block; display: block;
object-fit: contain; object-fit: contain;
height: 100%; height: 100%;

View File

@@ -25,6 +25,11 @@ run_test("postprocess_content", () => {
'<a href="http://zulip.zulipdev.com/user_uploads/w/ha/tever/inline.png" title="inline image">upload</a> ' + '<a href="http://zulip.zulipdev.com/user_uploads/w/ha/tever/inline.png" title="inline image">upload</a> ' +
'<a role="button">button</a> ' + '<a role="button">button</a> ' +
"</div>" + "</div>" +
'<div class="message_inline_image message_inline_video">' +
'<a href="http://zulip.zulipdev.com/user_uploads/w/ha/tever/inline.mp4">' +
'<video src="http://zulip.zulipdev.com/user_uploads/w/ha/tever/inline.mp4"></video>' +
"</a>" +
"</div>" +
'<div class="youtube-video message_inline_image">' + '<div class="youtube-video message_inline_image">' +
'<a class="" href="https://www.youtube.com/watch?v=tyKJueEk0XM">' + '<a class="" href="https://www.youtube.com/watch?v=tyKJueEk0XM">' +
'<img src="https://i.ytimg.com/vi/tyKJueEk0XM/default.jpg">' + '<img src="https://i.ytimg.com/vi/tyKJueEk0XM/default.jpg">' +
@@ -40,9 +45,14 @@ run_test("postprocess_content", () => {
'<a href="http://zulip.zulipdev.com/user_uploads/w/ha/tever/inline.png" target="_blank" rel="noopener noreferrer" aria-label="inline image">upload</a> ' + '<a href="http://zulip.zulipdev.com/user_uploads/w/ha/tever/inline.png" target="_blank" rel="noopener noreferrer" aria-label="inline image">upload</a> ' +
'<a role="button">button</a> ' + '<a role="button">button</a> ' +
"</div>" + "</div>" +
'<div class="message_inline_image message_inline_video">' +
'<a href="http://zulip.zulipdev.com/user_uploads/w/ha/tever/inline.mp4" target="_blank" rel="noopener noreferrer" class="media-anchor-element">' +
'<video src="http://zulip.zulipdev.com/user_uploads/w/ha/tever/inline.mp4" class="media-video-element media-image-element"></video>' +
"</a>" +
"</div>" +
'<div class="youtube-video message_inline_image">' + '<div class="youtube-video message_inline_image">' +
'<a class="" href="https://www.youtube.com/watch?v=tyKJueEk0XM" target="_blank" rel="noopener noreferrer">' + '<a class="media-anchor-element" href="https://www.youtube.com/watch?v=tyKJueEk0XM" target="_blank" rel="noopener noreferrer">' +
'<img src="https://i.ytimg.com/vi/tyKJueEk0XM/mqdefault.jpg" loading="lazy">' + '<img src="https://i.ytimg.com/vi/tyKJueEk0XM/mqdefault.jpg" class="media-image-element" loading="lazy">' +
"</a>" + "</a>" +
"</div>", "</div>",
); );
@@ -106,8 +116,8 @@ run_test("message_inline_animated_image_still", ({override}) => {
"</div>", "</div>",
), ),
'<div class="message_inline_image">' + '<div class="message_inline_image">' +
'<a href="/user_uploads/path/to/image.png" target="_blank" rel="noopener noreferrer" aria-label="image.png">' + '<a href="/user_uploads/path/to/image.png" target="_blank" rel="noopener noreferrer" class="media-anchor-element" aria-label="image.png">' +
'<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/300x200.webp" loading="lazy">' + '<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/300x200.webp" class="media-image-element" loading="lazy">' +
"</a>" + "</a>" +
"</div>", "</div>",
); );
@@ -123,8 +133,8 @@ run_test("message_inline_animated_image_still", ({override}) => {
"</div>", "</div>",
), ),
'<div class="message_inline_image">' + '<div class="message_inline_image">' +
'<a href="/user_uploads/path/to/image.png" target="_blank" rel="noopener noreferrer" aria-label="image.png">' + '<a href="/user_uploads/path/to/image.png" target="_blank" rel="noopener noreferrer" class="media-anchor-element" aria-label="image.png">' +
'<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/300x200-anim.webp" data-animated="true" loading="lazy">' + '<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/300x200-anim.webp" data-animated="true" class="media-image-element" loading="lazy">' +
"</a>" + "</a>" +
"</div>", "</div>",
); );
@@ -140,8 +150,8 @@ run_test("message_inline_animated_image_still", ({override}) => {
"</div>", "</div>",
), ),
'<div class="message_inline_image message_inline_animated_image_still">' + '<div class="message_inline_image message_inline_animated_image_still">' +
'<a href="/user_uploads/path/to/image.png" target="_blank" rel="noopener noreferrer" aria-label="image.png">' + '<a href="/user_uploads/path/to/image.png" target="_blank" rel="noopener noreferrer" class="media-anchor-element" aria-label="image.png">' +
'<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/300x200.webp" data-animated="true" loading="lazy">' + '<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/300x200.webp" data-animated="true" class="media-image-element" loading="lazy">' +
"</a>" + "</a>" +
"</div>", "</div>",
); );
@@ -156,8 +166,8 @@ run_test("message_inline_animated_image_still", ({override}) => {
"</div>", "</div>",
), ),
'<div class="message_inline_image message_inline_animated_image_still">' + '<div class="message_inline_image message_inline_animated_image_still">' +
'<a href="/user_uploads/path/to/image.png" target="_blank" rel="noopener noreferrer" aria-label="image.png">' + '<a href="/user_uploads/path/to/image.png" target="_blank" rel="noopener noreferrer" class="media-anchor-element" aria-label="image.png">' +
'<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/300x200.webp" data-animated="true" loading="lazy">' + '<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/300x200.webp" data-animated="true" class="media-image-element" loading="lazy">' +
"</a>" + "</a>" +
"</div>", "</div>",
); );