/
githubmirror
/
zulip
Обзор
Документация
Войти
/
githubmirror
/
zulip
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
web/src/clipboard_handler.ts
78 строк
3 KB
Evy Kassirer
topic_link_util: Refactor to return unescaped links.
07 фев 2026, 05:36
07 фев 2026, 05:36
04c4513
Код
Авторство
О чём код?
import assert from "minimalistic-assert"; import * as hash_util from "./hash_util.ts"; import * as popover_menus from "./popover_menus.ts"; import * as stream_data from "./stream_data.ts"; import * as topic_link_util from "./topic_link_util.ts"; // The standard Clipboard API do not support custom mime types like // text/x-gfm, but this approach does, except on Safari. export function execute_copy( handle_copy_event: (e: ClipboardEvent) => void, fallback_text: string, ): void { // On Safari, the copy command only works if there's a current // selection, so we create a selection, with the link set as // fallback text for it. const dummy = document.createElement("input"); document.body.append(dummy); dummy.value = fallback_text; dummy.select(); document.addEventListener("copy", handle_copy_event); // eslint-disable-next-line @typescript-eslint/no-deprecated document.execCommand("copy"); document.removeEventListener("copy", handle_copy_event); dummy.remove(); } export async function copy_link_to_clipboard(link: string): Promise<void> { // The caller is responsible for making sure what it is passes in // to this function is a Zulip internal link. return new Promise((resolve) => { const stream_topic_details = hash_util.decode_stream_topic_from_url(link); function handle_copy_event(e: ClipboardEvent): void { if (stream_topic_details === null) { e.clipboardData?.setData("text/plain", link); } else { const stream = stream_data.get_sub_by_id(stream_topic_details.stream_id); assert(stream !== undefined); const {label_text_markdown} = topic_link_util.get_topic_link_content_with_stream_name({ stream_name: stream.name, topic_name: stream_topic_details.topic_name, message_id: stream_topic_details.message_id, }); const copy_in_html_syntax = topic_link_util.as_html_link_syntax_unsafe( label_text_markdown, link, ); const copy_in_markdown_syntax = topic_link_util.as_markdown_link_syntax( label_text_markdown, link, ); e.clipboardData?.setData("text/plain", link); e.clipboardData?.setData("text/html", copy_in_html_syntax); e.clipboardData?.setData("text/x-gfm", copy_in_markdown_syntax); } e.preventDefault(); resolve(); } execute_copy(handle_copy_event, link); }); } /* istanbul ignore next */ export async function popover_copy_link_to_clipboard( instance: typeof popover_menus.popover_instances.message_actions, $element: JQuery, ): Promise<void> { // Wrapper for copy_link_to_clipboard handling closing a popover // and error handling. const clipboard_text = String($element.attr("data-clipboard-text")); await copy_link_to_clipboard(clipboard_text); popover_menus.hide_current_popover_if_visible(instance); }