diff --git a/plugins/file-manager/src/frontend/components/MarkdownRenderer.tsx b/plugins/file-manager/src/frontend/components/MarkdownRenderer.tsx index 9721a2d1b..fdc5733fa 100644 --- a/plugins/file-manager/src/frontend/components/MarkdownRenderer.tsx +++ b/plugins/file-manager/src/frontend/components/MarkdownRenderer.tsx @@ -48,75 +48,87 @@ export function MarkdownRenderer({ : "px-4 py-2 text-foreground"; return ( - - {String(children).replace(/\n$/, "")} - - ) : ( - - {children} - - ); - }, - h1: ({ children }) =>

{children}

, - h2: ({ children }) =>

{children}

, - h3: ({ children }) =>

{children}

, - h4: ({ children }) =>

{children}

, - p: ({ children }) =>

{children}

, - ul: ({ children }) => ( - - ), - ol: ({ children }) => ( -
    {children}
- ), - li: ({ children }) => ( -
  • {children}
  • - ), - blockquote: ({ children }) => ( -
    {children}
    - ), - table: ({ children }) => ( -
    - {children}
    -
    - ), - thead: ({ children }) => {children}, - tbody: ({ children }) => {children}, - tr: ({ children }) => ( - {children} - ), - th: ({ children }) => {children}, - td: ({ children }) => {children}, - a: ({ href, children }) => ( - - {children} - - ), +
    { + // Keep native text copying out of the file grid's global shortcuts. + if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === "c") + event.stopPropagation(); }} > - {content} - + + {String(children).replace(/\n$/, "")} + + ) : ( + + {children} + + ); + }, + h1: ({ children }) =>

    {children}

    , + h2: ({ children }) =>

    {children}

    , + h3: ({ children }) =>

    {children}

    , + h4: ({ children }) =>

    {children}

    , + p: ({ children }) =>

    {children}

    , + ul: ({ children }) => ( +
      {children}
    + ), + ol: ({ children }) => ( +
      {children}
    + ), + li: ({ children }) => ( +
  • {children}
  • + ), + blockquote: ({ children }) => ( +
    {children}
    + ), + table: ({ children }) => ( +
    + {children}
    +
    + ), + thead: ({ children }) => ( + {children} + ), + tbody: ({ children }) => {children}, + tr: ({ children }) => ( + {children} + ), + th: ({ children }) => {children}, + td: ({ children }) => {children}, + a: ({ href, children }) => ( + + {children} + + ), + }} + > + {content} +
    +
    ); } diff --git a/plugins/file-manager/tests/frontend/components/MarkdownRenderer.test.tsx b/plugins/file-manager/tests/frontend/components/MarkdownRenderer.test.tsx new file mode 100644 index 000000000..27fefea18 --- /dev/null +++ b/plugins/file-manager/tests/frontend/components/MarkdownRenderer.test.tsx @@ -0,0 +1,43 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; +import { cleanup, fireEvent, render, screen } from "@testing-library/react"; +import "@testing-library/jest-dom/vitest"; +import { MarkdownRenderer } from "../../../src/frontend/components/MarkdownRenderer"; + +afterEach(cleanup); + +describe("Markdown preview text copying", () => { + it.each([false, true])( + "supports copying in compact=%s previews", + (compact) => { + const fileShortcut = vi.fn(); + document.addEventListener("keydown", fileShortcut); + try { + const { container } = render( +
    + +
    , + ); + const preview = container.querySelector(".select-text")!; + preview.focus(); + expect(preview).toHaveFocus(); + expect( + screen.getByRole("heading", { name: "Preview" }), + ).toBeInTheDocument(); + for (const modifier of [{ ctrlKey: true }, { metaKey: true }]) { + expect(fireEvent.keyDown(preview, { key: "c", ...modifier })).toBe( + true, + ); + } + expect(fileShortcut).not.toHaveBeenCalled(); + fireEvent.keyDown(preview, { key: "Escape" }); + expect(fileShortcut).toHaveBeenCalledTimes(1); + expect(fireEvent.contextMenu(preview)).toBe(true); + } finally { + document.removeEventListener("keydown", fileShortcut); + } + }, + ); +});