From 7f1396de320e8ce500dde6556af1f7d6123b9275 Mon Sep 17 00:00:00 2001 From: roanster007 Date: Wed, 24 Jul 2024 22:39:08 +0530 Subject: [PATCH] lightbox: Update `canonical_url_of_media` to use URL pathname. This reworks canonical_url_of_media to work with HTMLMediaElement, making it possible to do cross-browser inspection of media sources. (Firefox and Chrome disagree on whether to return the "href" attribute as the path in the source, or a full URL). Additionally, we ensure non-empty cache keys on media so unexpected results from the DOM do not get cached. Co-Authored-By: Alex Vandiver Co-Authored-By: roanster007 --- web/src/lightbox.ts | 66 ++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/web/src/lightbox.ts b/web/src/lightbox.ts index 10a42c31df..83add091c6 100644 --- a/web/src/lightbox.ts +++ b/web/src/lightbox.ts @@ -204,24 +204,36 @@ export function clear_for_testing(): void { asset_map.clear(); } -export function canonical_url_of_media(media: HTMLElement): string { - let media_src = media.getAttribute("src"); - if (!media_src || media_src.startsWith("/user_uploads/thumbnail/")) { - media_src = media.parentElement!.getAttribute("href")!; +export function canonical_url_of_media(media: HTMLMediaElement): string { + let media_string = media.src; + if (!media_string) { + return ""; } - return media_src; + + const media_url = new URL(media_string); + + if ( + media_url.origin === window.location.origin && + media_url.pathname.startsWith("/user_uploads/thumbnail/") + ) { + assert(media.parentElement instanceof HTMLAnchorElement); + media_string = media.parentElement.href; + } + + return media_string; } export function render_lightbox_media_list(displayed_source: string): void { if (!is_open) { - const media_list = $( + const message_media_list = $( ".focused-message-list .message_inline_image img, .focused-message-list .message_inline_video video", ).toArray(); - const $media_list = $("#lightbox_overlay .image-list").empty(); - - for (const media of media_list) { - const src = canonical_url_of_media(media); - const className = displayed_source === src ? "image selected" : "image"; + const $lightbox_media_list = $("#lightbox_overlay .image-list").empty(); + const canonical_displayed_source = new URL(displayed_source, window.location.origin).href; + for (const media of message_media_list) { + const message_media_list_src = canonical_url_of_media(media); + const className = + message_media_list_src === canonical_displayed_source ? "image selected" : "image"; const is_video = media.tagName === "VIDEO"; // We parse the data for each image to show in the list, @@ -238,7 +250,7 @@ export function render_lightbox_media_list(displayed_source: string): void { .attr("data-url", payload.url); const $video = $("