From 238cf657c0949bcc949cf9ecd677d1dd99cf8791 Mon Sep 17 00:00:00 2001 From: Antonio Musolino Date: Fri, 17 Feb 2023 08:33:42 +0100 Subject: [PATCH] fix(techdocs): copy to clipboard works in usecure context Signed-off-by: Antonio Musolino --- .changeset/spotty-turtles-reply.md | 5 +++++ .../reader/transformers/copyToClipboard.test.ts | 16 +++++++++++++++- .../src/reader/transformers/copyToClipboard.tsx | 6 ++++-- 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 .changeset/spotty-turtles-reply.md diff --git a/.changeset/spotty-turtles-reply.md b/.changeset/spotty-turtles-reply.md new file mode 100644 index 0000000000..2dfc12a176 --- /dev/null +++ b/.changeset/spotty-turtles-reply.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Copy to clipboard now works in a not secure context. diff --git a/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts b/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts index 9c4ee08346..cac7f76a0e 100644 --- a/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts +++ b/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts @@ -18,6 +18,7 @@ import { createTestShadowDom } from '../../test-utils'; import { copyToClipboard } from './copyToClipboard'; import { lightTheme } from '@backstage/theme'; import { waitFor } from '@testing-library/react'; +import useCopyToClipboard from 'react-use/lib/useCopyToClipboard'; const clipboardSpy = jest.fn(); Object.defineProperty(window.navigator, 'clipboard', { @@ -26,8 +27,21 @@ Object.defineProperty(window.navigator, 'clipboard', { }, }); +jest.mock('react-use/lib/useCopyToClipboard', () => { + const original = jest.requireActual('react-use/lib/useCopyToClipboard'); + + return { + __esModule: true, + default: jest.fn().mockImplementation(original.default), + }; +}); + describe('copyToClipboard', () => { it('calls navigator.clipboard.writeText when clipboard button has been clicked', async () => { + const spy = useCopyToClipboard as jest.Mock; + const copy = jest.fn(); + spy.mockReturnValue([{}, copy]); + const expectedClipboard = 'function foo() {return "bar";}'; const shadowDom = await createTestShadowDom( ` @@ -51,7 +65,7 @@ describe('copyToClipboard', () => { expect(tooltip).toHaveTextContent('Copied to clipboard'); }); - expect(clipboardSpy).toHaveBeenCalledWith(expectedClipboard); + expect(copy).toHaveBeenCalledWith(expectedClipboard); }); it('only gets applied to code blocks', async () => { diff --git a/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx b/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx index a90c4ca116..422bbb10ce 100644 --- a/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx +++ b/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx @@ -25,6 +25,7 @@ import { } from '@material-ui/core'; import Button from '@material-ui/core/Button'; import type { Transformer } from './transformer'; +import useCopyToClipboard from 'react-use/lib/useCopyToClipboard'; const CopyToClipboardTooltip = withStyles(theme => ({ tooltip: { @@ -49,11 +50,12 @@ type CopyToClipboardButtonProps = { const CopyToClipboardButton = ({ text }: CopyToClipboardButtonProps) => { const [open, setOpen] = useState(false); + const [, copyToClipboard] = useCopyToClipboard(); const handleClick = useCallback(() => { - window.navigator.clipboard.writeText(text); + copyToClipboard(text); setOpen(true); - }, [text]); + }, [text, copyToClipboard]); const handleClose = useCallback(() => { setOpen(false);