diff --git a/web/src/rendered_markdown.js b/web/src/rendered_markdown.js index 42df0302e9..c583aec90c 100644 --- a/web/src/rendered_markdown.js +++ b/web/src/rendered_markdown.js @@ -17,6 +17,7 @@ import * as sub_store from "./sub_store"; import * as timerender from "./timerender"; import * as user_groups from "./user_groups"; import {user_settings} from "./user_settings"; +import * as util from "./util"; /* rendered_markdown @@ -78,6 +79,15 @@ export const update_elements = ($content) => { $content.addClass("rtl"); } + if (util.is_client_safari()) { + // Without this video thumbnail doesn't load on Safari. + $content.find(".message_inline_video video").each(function () { + // On Safari, one needs to manually load video elements. + // https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/load + this.load(); + }); + } + $content.find(".user-mention").each(function () { const user_id = get_user_id_for_mention_button(this); // We give special highlights to the mention buttons diff --git a/web/src/util.ts b/web/src/util.ts index a3c63650eb..244ddc6cf6 100644 --- a/web/src/util.ts +++ b/web/src/util.ts @@ -220,6 +220,13 @@ export function is_mobile(): boolean { ); } +export function is_client_safari(): boolean { + // Since GestureEvent is only supported on Safari, we can use it + // to detect if the browser is Safari including Safari on iOS. + // https://developer.mozilla.org/en-US/docs/Web/API/GestureEvent + return "GestureEvent" in window; +} + export function sorted_ids(ids: number[]): number[] { // This makes sure we don't mutate the list. const id_list = [...new Set(ids)]; diff --git a/web/tests/rendered_markdown.test.js b/web/tests/rendered_markdown.test.js index bc0e8d9fca..91323d6b61 100644 --- a/web/tests/rendered_markdown.test.js +++ b/web/tests/rendered_markdown.test.js @@ -100,6 +100,7 @@ const get_content_element = () => { $content.set_find_results(".emoji", $array([])); $content.set_find_results("div.spoiler-header", $array([])); $content.set_find_results("div.codehilite", $array([])); + $content.set_find_results(".message_inline_video video", $array([])); set_closest_dot_find_result($content, []); // Fend off dumb security bugs by forcing devs to be @@ -129,6 +130,22 @@ run_test("misc_helpers", () => { assert.equal($elem.text(), "Aaron, but silent"); }); +run_test("message_inline_video", () => { + const $content = get_content_element(); + const $elem = $.create("message_inline_video"); + + let load_called = false; + $elem.load = () => { + load_called = true; + }; + + $content.set_find_results(".message_inline_video video", $array([$elem])); + window.GestureEvent = true; + rm.update_elements($content); + assert.equal(load_called, true); + window.GestureEvent = false; +}); + run_test("user-mention", () => { // Setup const $content = get_content_element();