mirror of https://github.com/zulip/zulip.git
rendered_markdown: Move thumbnail rewriting to postprocess_content.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
edf34ada63
commit
94fe3f6194
|
@ -1,4 +1,7 @@
|
||||||
import {$t} from "./i18n";
|
import {$t} from "./i18n";
|
||||||
|
import * as thumbnail from "./thumbnail";
|
||||||
|
import {user_settings} from "./user_settings";
|
||||||
|
import * as util from "./util";
|
||||||
|
|
||||||
let inertDocument: Document | undefined;
|
let inertDocument: Document | undefined;
|
||||||
|
|
||||||
|
@ -84,5 +87,33 @@ export function postprocess_content(html: string): string {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const inline_img_thumbnail of template.content.querySelectorAll<HTMLImageElement>(
|
||||||
|
'div.message_inline_image > a > img[src^="/user_uploads/thumbnail/"]',
|
||||||
|
)) {
|
||||||
|
let thumbnail_name = thumbnail.preferred_format.name;
|
||||||
|
if (inline_img_thumbnail.dataset.animated === "true") {
|
||||||
|
if (
|
||||||
|
user_settings.web_animate_image_previews === "always" ||
|
||||||
|
// Treat on_hover as "always" on mobile web, where
|
||||||
|
// hovering is impossible and there's much less on
|
||||||
|
// the screen.
|
||||||
|
(user_settings.web_animate_image_previews === "on_hover" && util.is_mobile())
|
||||||
|
) {
|
||||||
|
thumbnail_name = thumbnail.animated_format.name;
|
||||||
|
} else {
|
||||||
|
// If we're showing a still thumbnail, show a play
|
||||||
|
// button so that users that it can be played.
|
||||||
|
inline_img_thumbnail
|
||||||
|
.closest(".message_inline_image")!
|
||||||
|
.classList.add("message_inline_animated_image_still");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline_img_thumbnail.src = inline_img_thumbnail.src.replace(
|
||||||
|
/\/[^/]+$/,
|
||||||
|
"/" + thumbnail_name,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return template.innerHTML;
|
return template.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import * as realm_playground from "./realm_playground";
|
||||||
import * as rows from "./rows";
|
import * as rows from "./rows";
|
||||||
import * as rtl from "./rtl";
|
import * as rtl from "./rtl";
|
||||||
import * as sub_store from "./sub_store";
|
import * as sub_store from "./sub_store";
|
||||||
import * as thumbnail from "./thumbnail";
|
|
||||||
import * as timerender from "./timerender";
|
import * as timerender from "./timerender";
|
||||||
import * as user_groups from "./user_groups";
|
import * as user_groups from "./user_groups";
|
||||||
import {user_settings} from "./user_settings";
|
import {user_settings} from "./user_settings";
|
||||||
|
@ -338,32 +337,4 @@ export const update_elements = ($content: JQuery): void => {
|
||||||
.contents()
|
.contents()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
$content
|
|
||||||
.find('div.message_inline_image > a > img[src^="/user_uploads/thumbnail/"]')
|
|
||||||
.each(function (): void {
|
|
||||||
const $inline_img_thumbnail = $(this);
|
|
||||||
let thumbnail_name = thumbnail.preferred_format.name;
|
|
||||||
if ($inline_img_thumbnail.attr("data-animated") === "true") {
|
|
||||||
if (
|
|
||||||
user_settings.web_animate_image_previews === "always" ||
|
|
||||||
// Treat on_hover as "always" on mobile web, where
|
|
||||||
// hovering is impossible and there's much less on
|
|
||||||
// the screen.
|
|
||||||
(user_settings.web_animate_image_previews === "on_hover" && util.is_mobile())
|
|
||||||
) {
|
|
||||||
thumbnail_name = thumbnail.animated_format.name;
|
|
||||||
} else {
|
|
||||||
// If we're showing a still thumbnail, show a play
|
|
||||||
// button so that users that it can be played.
|
|
||||||
$inline_img_thumbnail
|
|
||||||
.closest(".message_inline_image")
|
|
||||||
.addClass("message_inline_animated_image_still");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$inline_img_thumbnail.attr(
|
|
||||||
"src",
|
|
||||||
$inline_img_thumbnail.attr("src")!.replace(/\/[^/]+$/, "/" + thumbnail_name),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,8 +2,11 @@
|
||||||
|
|
||||||
const {strict: assert} = require("assert");
|
const {strict: assert} = require("assert");
|
||||||
|
|
||||||
const {zrequire} = require("./lib/namespace");
|
const {mock_esm, zrequire} = require("./lib/namespace");
|
||||||
const {run_test} = require("./lib/test");
|
const {run_test} = require("./lib/test");
|
||||||
|
const {user_settings} = require("./lib/zpage_params");
|
||||||
|
|
||||||
|
const thumbnail = mock_esm("../src/thumbnail");
|
||||||
|
|
||||||
const {postprocess_content} = zrequire("postprocess_content");
|
const {postprocess_content} = zrequire("postprocess_content");
|
||||||
|
|
||||||
|
@ -31,3 +34,111 @@ run_test("postprocess_content", () => {
|
||||||
"</div>",
|
"</div>",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
run_test("message_inline_animated_image_still", ({override}) => {
|
||||||
|
const thumbnail_formats = [
|
||||||
|
{
|
||||||
|
name: "840x560-anim.webp",
|
||||||
|
max_width: 840,
|
||||||
|
max_height: 560,
|
||||||
|
format: "webp",
|
||||||
|
animated: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "840x560.webp",
|
||||||
|
max_width: 840,
|
||||||
|
max_height: 560,
|
||||||
|
format: "webp",
|
||||||
|
animated: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "300x200-anim.webp",
|
||||||
|
max_width: 300,
|
||||||
|
max_height: 200,
|
||||||
|
format: "webp",
|
||||||
|
animated: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "300x200.webp",
|
||||||
|
max_width: 300,
|
||||||
|
max_height: 200,
|
||||||
|
format: "webp",
|
||||||
|
animated: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "300x200.jpg",
|
||||||
|
max_width: 300,
|
||||||
|
max_height: 200,
|
||||||
|
format: "jpg",
|
||||||
|
animated: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
// TODO: Initialize the real thumbnail.ts rather than mocking it.
|
||||||
|
override(thumbnail, "preferred_format", thumbnail_formats[3]);
|
||||||
|
override(thumbnail, "animated_format", thumbnail_formats[2]);
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
postprocess_content(
|
||||||
|
'<div class="message_inline_image">' +
|
||||||
|
'<a href="/user_uploads/path/to/image.png" title="image.png">' +
|
||||||
|
'<img data-original-dimensions="3264x2448" 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" target="_blank" rel="noopener noreferrer" aria-label="image.png">' +
|
||||||
|
'<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/300x200.webp">' +
|
||||||
|
"</a>" +
|
||||||
|
"</div>",
|
||||||
|
);
|
||||||
|
|
||||||
|
// Now verify the behavior for animated images.
|
||||||
|
override(user_settings, "web_animate_image_previews", "always");
|
||||||
|
assert.equal(
|
||||||
|
postprocess_content(
|
||||||
|
'<div class="message_inline_image">' +
|
||||||
|
'<a href="/user_uploads/path/to/image.png" title="image.png">' +
|
||||||
|
'<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/840x560.webp" data-animated="true">' +
|
||||||
|
"</a>" +
|
||||||
|
"</div>",
|
||||||
|
),
|
||||||
|
'<div class="message_inline_image">' +
|
||||||
|
'<a href="/user_uploads/path/to/image.png" target="_blank" rel="noopener noreferrer" aria-label="image.png">' +
|
||||||
|
'<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/300x200-anim.webp" data-animated="true">' +
|
||||||
|
"</a>" +
|
||||||
|
"</div>",
|
||||||
|
);
|
||||||
|
|
||||||
|
// And verify the different behavior for other values of the animation setting.
|
||||||
|
override(user_settings, "web_animate_image_previews", "on_hover");
|
||||||
|
assert.equal(
|
||||||
|
postprocess_content(
|
||||||
|
'<div class="message_inline_image">' +
|
||||||
|
'<a href="/user_uploads/path/to/image.png" title="image.png">' +
|
||||||
|
'<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/840x560.webp" data-animated="true">' +
|
||||||
|
"</a>" +
|
||||||
|
"</div>",
|
||||||
|
),
|
||||||
|
'<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">' +
|
||||||
|
'<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/300x200.webp" data-animated="true">' +
|
||||||
|
"</a>" +
|
||||||
|
"</div>",
|
||||||
|
);
|
||||||
|
|
||||||
|
override(user_settings, "web_animate_image_previews", "never");
|
||||||
|
assert.equal(
|
||||||
|
postprocess_content(
|
||||||
|
'<div class="message_inline_image">' +
|
||||||
|
'<a href="/user_uploads/path/to/image.png" title="image.png">' +
|
||||||
|
'<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/840x560.webp" data-animated="true">' +
|
||||||
|
"</a>" +
|
||||||
|
"</div>",
|
||||||
|
),
|
||||||
|
'<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">' +
|
||||||
|
'<img data-original-dimensions="3264x2448" src="/user_uploads/thumbnail/path/to/image.png/300x200.webp" data-animated="true">' +
|
||||||
|
"</a>" +
|
||||||
|
"</div>",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
|
@ -23,7 +23,6 @@ mock_cjs("clipboard", Clipboard);
|
||||||
|
|
||||||
const realm_playground = mock_esm("../src/realm_playground");
|
const realm_playground = mock_esm("../src/realm_playground");
|
||||||
const copied_tooltip = mock_esm("../src/copied_tooltip");
|
const copied_tooltip = mock_esm("../src/copied_tooltip");
|
||||||
const thumbnail = mock_esm("../src/thumbnail");
|
|
||||||
user_settings.emojiset = "apple";
|
user_settings.emojiset = "apple";
|
||||||
|
|
||||||
const rm = zrequire("rendered_markdown");
|
const rm = zrequire("rendered_markdown");
|
||||||
|
@ -139,14 +138,6 @@ const get_content_element = () => {
|
||||||
$content.set_find_results("div.spoiler-header", $array([]));
|
$content.set_find_results("div.spoiler-header", $array([]));
|
||||||
$content.set_find_results("div.codehilite", $array([]));
|
$content.set_find_results("div.codehilite", $array([]));
|
||||||
$content.set_find_results(".message_inline_video video", $array([]));
|
$content.set_find_results(".message_inline_video video", $array([]));
|
||||||
$content.set_find_results(
|
|
||||||
'div.message_inline_image > a > img[src^="/user_uploads/thumbnail/"]',
|
|
||||||
$array([]),
|
|
||||||
);
|
|
||||||
$content.set_find_results(
|
|
||||||
"div.message_inline_image img, div.message_inline_image video",
|
|
||||||
$array([]),
|
|
||||||
);
|
|
||||||
|
|
||||||
set_message_for_message_content($content, undefined);
|
set_message_for_message_content($content, undefined);
|
||||||
|
|
||||||
|
@ -201,87 +192,6 @@ run_test("message_inline_video", () => {
|
||||||
window.GestureEvent = false;
|
window.GestureEvent = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
run_test("message_inline_animated_image_still", ({override}) => {
|
|
||||||
const $content = get_content_element();
|
|
||||||
const $elem = $.create("img");
|
|
||||||
|
|
||||||
$elem.attr("data-animated", "false");
|
|
||||||
$elem.attr("src", "/path/to/image.png");
|
|
||||||
|
|
||||||
$content.set_find_results(
|
|
||||||
'div.message_inline_image > a > img[src^="/user_uploads/thumbnail/"]',
|
|
||||||
$array([$elem]),
|
|
||||||
);
|
|
||||||
|
|
||||||
const $stub = $.create("div.message_inline_image");
|
|
||||||
|
|
||||||
$elem.closest = (closest_opts) => {
|
|
||||||
assert.equal(closest_opts, ".message_inline_image");
|
|
||||||
return $stub;
|
|
||||||
};
|
|
||||||
|
|
||||||
const thumbnail_formats = [
|
|
||||||
{
|
|
||||||
name: "840x560-anim.webp",
|
|
||||||
max_width: 840,
|
|
||||||
max_height: 560,
|
|
||||||
format: "webp",
|
|
||||||
animated: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "840x560.webp",
|
|
||||||
max_width: 840,
|
|
||||||
max_height: 560,
|
|
||||||
format: "webp",
|
|
||||||
animated: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "300x200-anim.webp",
|
|
||||||
max_width: 300,
|
|
||||||
max_height: 200,
|
|
||||||
format: "webp",
|
|
||||||
animated: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "300x200.webp",
|
|
||||||
max_width: 300,
|
|
||||||
max_height: 200,
|
|
||||||
format: "webp",
|
|
||||||
animated: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "300x200.jpg",
|
|
||||||
max_width: 300,
|
|
||||||
max_height: 200,
|
|
||||||
format: "jpg",
|
|
||||||
animated: false,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
// TODO: Initialize the real thumbnail.ts rather than mocking it.
|
|
||||||
override(thumbnail, "preferred_format", thumbnail_formats[1]);
|
|
||||||
override(thumbnail, "animated_format", thumbnail_formats[0]);
|
|
||||||
|
|
||||||
rm.update_elements($content);
|
|
||||||
assert.equal($elem.attr("src"), "/path/to/840x560.webp");
|
|
||||||
|
|
||||||
// Now verify the behavior for animated images.
|
|
||||||
$elem.attr("data-animated", "true");
|
|
||||||
override(user_settings, "web_animate_image_previews", "always");
|
|
||||||
rm.update_elements($content);
|
|
||||||
assert.equal($elem.attr("src"), "/path/to/840x560-anim.webp");
|
|
||||||
|
|
||||||
// And verify the different behavior for other values of the animation setting.
|
|
||||||
override(user_settings, "web_animate_image_previews", "on_hover");
|
|
||||||
rm.update_elements($content);
|
|
||||||
assert.equal($elem.attr("src"), "/path/to/840x560.webp");
|
|
||||||
assert.equal($stub.hasClass("message_inline_animated_image_still"), true);
|
|
||||||
|
|
||||||
override(user_settings, "web_animate_image_previews", "never");
|
|
||||||
rm.update_elements($content);
|
|
||||||
assert.equal($elem.attr("src"), "/path/to/840x560.webp");
|
|
||||||
assert.equal($stub.hasClass("message_inline_animated_image_still"), true);
|
|
||||||
});
|
|
||||||
|
|
||||||
run_test("user-mention", () => {
|
run_test("user-mention", () => {
|
||||||
// Setup
|
// Setup
|
||||||
const $content = get_content_element();
|
const $content = get_content_element();
|
||||||
|
|
Loading…
Reference in New Issue