thumbnails: Structure adjacent images into galleries.

This commit is contained in:
Karl Stolley
2024-09-19 15:45:30 -04:00
committed by Tim Abbott
parent 4d1bfe6537
commit ad75ab590a
2 changed files with 105 additions and 6 deletions

View File

@@ -238,5 +238,35 @@ export function postprocess_content(html: string): string {
}
}
// After all other processing on images has been done, we look for
// adjacent images and tuck them structurally into galleries.
// This will also process uploaded video thumbnails, which likewise
// take the `.message_inline_image` class
for (const elt of template.content.querySelectorAll(".message_inline_image")) {
let gallery_element;
const is_part_of_open_gallery = elt.previousElementSibling?.classList.contains(
"message-thumbnail-gallery",
);
if (is_part_of_open_gallery) {
// If the the current media element's previous sibling is a gallery,
// it should be kept with the other media in that gallery.
gallery_element = elt.previousElementSibling;
} else {
// Otherwise, we've found an image element that follows some other
// content (or is the first in the message) and need to create a
// gallery for it, and perhaps other adjacent sibling media elements,
// if they exist.
gallery_element = inertDocument.createElement("div");
gallery_element.classList.add("message-thumbnail-gallery");
// We insert the gallery just before the media element we've found
elt.before(gallery_element);
}
// Finally, the media element gets moved into the current gallery
gallery_element?.append(elt);
}
return template.innerHTML;
}

View File

@@ -41,6 +41,7 @@ run_test("postprocess_content", () => {
"<a>invalid</a> " +
"<a>unsafe</a> " +
'<a href="/#fragment" title="http://zulip.zulipdev.com/#fragment">fragment</a>' +
'<div class="message-thumbnail-gallery">' +
'<div class="message_inline_image">' +
'<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> ' +
@@ -54,6 +55,7 @@ run_test("postprocess_content", () => {
'<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" class="media-image-element" loading="lazy">' +
"</a>" +
"</div>" +
"</div>",
);
});
@@ -65,6 +67,61 @@ run_test("ordered_lists", () => {
);
});
run_test("inline_image_galleries", ({override}) => {
const thumbnail_formats = [
{
name: "840x560.webp",
max_width: 840,
max_height: 560,
format: "webp",
animated: false,
},
];
override(thumbnail, "preferred_format", thumbnail_formats[0]);
assert.equal(
postprocess_content(
"<p>Message text</p>" +
'<div class="message_inline_image">' +
'<a href="/user_uploads/path/to/image.png" title="image.png">' +
'<img data-original-dimensions="1000x2000" src="/user_uploads/thumbnail/path/to/image.png/840x560.webp">' +
"</a>" +
"</div>" +
'<div class="message_inline_image">' +
'<a href="/user_uploads/path/to/image.png" title="image.png">' +
'<img data-original-dimensions="2000x1000" src="/user_uploads/thumbnail/path/to/image.png/840x560.webp">' +
"</a>" +
"</div>" +
"<p>Message text</p>" +
'<div class="message_inline_image">' +
'<a href="/user_uploads/path/to/image.png" title="image.png">' +
'<img data-original-dimensions="1000x1000" src="/user_uploads/thumbnail/path/to/image.png/840x560.webp">' +
"</a>" +
"</div>",
),
"<p>Message text</p>" +
'<div class="message-thumbnail-gallery">' +
'<div class="message_inline_image">' +
'<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="1000x2000" src="/user_uploads/thumbnail/path/to/image.png/840x560.webp" class="media-image-element portrait-thumbnail" width="1000" height="2000" loading="lazy">' +
"</a>" +
"</div>" +
'<div class="message_inline_image">' +
'<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="2000x1000" src="/user_uploads/thumbnail/path/to/image.png/840x560.webp" class="media-image-element landscape-thumbnail" width="2000" height="1000" loading="lazy">' +
"</a>" +
"</div>" +
"</div>" +
"<p>Message text</p>" +
'<div class="message-thumbnail-gallery">' +
'<div class="message_inline_image">' +
'<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="1000x1000" src="/user_uploads/thumbnail/path/to/image.png/840x560.webp" class="media-image-element portrait-thumbnail" width="1000" height="1000" loading="lazy">' +
"</a>" +
"</div>" +
"</div>",
);
});
run_test("message_inline_animated_image_still", ({override}) => {
const thumbnail_formats = [
{
@@ -116,10 +173,12 @@ run_test("message_inline_animated_image_still", ({override}) => {
"</a>" +
"</div>",
),
'<div class="message-thumbnail-gallery">' +
'<div class="message_inline_image">' +
'<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" class="media-image-element landscape-thumbnail" width="3264" height="2448" loading="lazy">' +
"</a>" +
"</div>" +
"</div>",
);
@@ -132,10 +191,12 @@ run_test("message_inline_animated_image_still", ({override}) => {
"</a>" +
"</div>",
),
'<div class="message-thumbnail-gallery">' +
'<div class="message_inline_image">' +
'<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="100x200" src="/user_uploads/thumbnail/path/to/image.png/300x200.webp" class="media-image-element portrait-thumbnail" width="100" height="200" loading="lazy">' +
"</a>" +
"</div>" +
"</div>",
);
@@ -148,10 +209,12 @@ run_test("message_inline_animated_image_still", ({override}) => {
"</a>" +
"</div>",
),
'<div class="message-thumbnail-gallery">' +
'<div class="message_inline_image">' +
'<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="1x10" src="/user_uploads/thumbnail/path/to/image.png/300x200.webp" class="media-image-element dinky-thumbnail extreme-aspect-ratio portrait-thumbnail" width="1" height="10" loading="lazy">' +
"</a>" +
"</div>" +
"</div>",
);
@@ -165,10 +228,12 @@ run_test("message_inline_animated_image_still", ({override}) => {
"</a>" +
"</div>",
),
'<div class="message-thumbnail-gallery">' +
'<div class="message_inline_image">' +
'<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" class="media-image-element landscape-thumbnail" width="3264" height="2448" loading="lazy">' +
"</a>" +
"</div>" +
"</div>",
);
@@ -182,10 +247,12 @@ run_test("message_inline_animated_image_still", ({override}) => {
"</a>" +
"</div>",
),
'<div class="message-thumbnail-gallery">' +
'<div class="message_inline_image message_inline_animated_image_still">' +
'<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" class="media-image-element landscape-thumbnail" width="3264" height="2448" loading="lazy">' +
"</a>" +
"</div>" +
"</div>",
);
@@ -198,10 +265,12 @@ run_test("message_inline_animated_image_still", ({override}) => {
"</a>" +
"</div>",
),
'<div class="message-thumbnail-gallery">' +
'<div class="message_inline_image message_inline_animated_image_still">' +
'<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" class="media-image-element landscape-thumbnail" width="3264" height="2448" loading="lazy">' +
"</a>" +
"</div>" +
"</div>",
);