From c5dd5eac0d8f773180df1d3556e0c7805d2b662a Mon Sep 17 00:00:00 2001 From: Erik Michelson Date: Fri, 1 Nov 2024 20:21:16 +0100 Subject: [PATCH] feat(frontend): add basic print functionality Co-authored-by: Philip Molares Signed-off-by: Erik Michelson Signed-off-by: Philip Molares --- frontend/global-styles/github-markdown.scss | 6 -- frontend/global-styles/index.scss | 1 + frontend/global-styles/markdown-tweaks.scss | 4 +- frontend/global-styles/print.scss | 73 +++++++++++++++++++ frontend/locales/en.json | 9 ++- .../copy-to-clipboard-button.spec.tsx.snap | 12 +-- .../copy-to-clipboard-button.tsx | 2 + .../style.module.scss | 11 +++ .../highlighted-code.module.scss | 7 ++ ...render-page-url-on-iframe-load-callback.ts | 6 +- .../renderer-iframe/renderer-iframe.tsx | 17 +++-- .../common/renderer-iframe/style.module.scss | 6 ++ .../editor-page/editor-page-content.tsx | 6 +- .../hooks/use-print-keyboard-shortcut.ts | 38 ++++++++++ .../print-warning/print-warning.tsx | 27 +++++++ .../src/components/editor-page/print.scss | 15 ++++ ...renderer-communicator-context-provider.tsx | 9 ++- .../editor-page/sidebar/sidebar.tsx | 2 +- .../entries/export-print-sidebar-entry.tsx | 24 ++++++ .../export-sidebar-menu.tsx | 9 ++- .../note-info-line-word-count.tsx | 4 +- .../__snapshots__/splitter.spec.tsx.snap | 15 ++++ .../splitter/split-divider/split-divider.tsx | 2 +- .../editor-page/splitter/splitter.tsx | 10 ++- .../editor-page/utils/print-iframe.ts | 58 +++++++++++++++ .../click-shield/click-shield.module.scss | 11 ++- .../click-shield/click-shield.tsx | 34 ++++++--- .../click-shield/print-link.tsx | 26 +++++++ .../markdown-toc-button.module.scss | 6 ++ .../render-page/render-page-content.tsx | 13 +++- .../document/document-markdown-renderer.tsx | 2 +- .../document/markdown-document.module.scss | 7 ++ .../hooks/use-editor-receive-handler.ts | 6 +- .../hooks/use-send-to-renderer.ts | 4 +- .../rendering-message.ts | 10 ++- .../iframe-capsule-replacer.tsx | 5 +- .../abcjs/abc.module.scss | 16 +++- .../asciinema-frame.spec.tsx.snap | 2 +- .../asciinema/asciinema-frame.tsx | 5 +- .../asciinema/replace-asciinema-link.ts | 2 +- .../gist/gist-frame.tsx | 6 +- .../__snapshots__/vimeo-frame.spec.tsx.snap | 2 +- .../vimeo/vimeo-frame.tsx | 5 +- .../__snapshots__/youtube-frame.spec.tsx.snap | 2 +- .../youtube/youtube-frame.tsx | 5 +- .../hooks/dark-mode/use-dark-mode-state.ts | 12 ++- frontend/src/redux/index.ts | 4 +- .../src/redux/print-mode/initial-state.ts | 6 ++ frontend/src/redux/print-mode/methods.ts | 12 +++ frontend/src/redux/print-mode/slice.ts | 21 ++++++ frontend/src/test-utils/mock-app-state.ts | 3 +- 51 files changed, 520 insertions(+), 80 deletions(-) create mode 100644 frontend/global-styles/print.scss create mode 100644 frontend/src/components/common/copyable/copy-to-clipboard-button/style.module.scss create mode 100644 frontend/src/components/editor-page/hooks/use-print-keyboard-shortcut.ts create mode 100644 frontend/src/components/editor-page/print-warning/print-warning.tsx create mode 100644 frontend/src/components/editor-page/print.scss create mode 100644 frontend/src/components/editor-page/sidebar/specific-sidebar-entries/export-sidebar-menu/entries/export-print-sidebar-entry.tsx create mode 100644 frontend/src/components/editor-page/utils/print-iframe.ts create mode 100644 frontend/src/components/markdown-renderer/replace-components/click-shield/print-link.tsx create mode 100644 frontend/src/redux/print-mode/initial-state.ts create mode 100644 frontend/src/redux/print-mode/methods.ts create mode 100644 frontend/src/redux/print-mode/slice.ts diff --git a/frontend/global-styles/github-markdown.scss b/frontend/global-styles/github-markdown.scss index 13175a407..4006d6eab 100644 --- a/frontend/global-styles/github-markdown.scss +++ b/frontend/global-styles/github-markdown.scss @@ -107,12 +107,6 @@ font-size: 1em; } - hr { - box-sizing: initial; - height: 0; - overflow: visible; - } - input { font: inherit; margin: 0; diff --git a/frontend/global-styles/index.scss b/frontend/global-styles/index.scss index db7b98ca5..b61bd7742 100644 --- a/frontend/global-styles/index.scss +++ b/frontend/global-styles/index.scss @@ -17,6 +17,7 @@ @import "./github-markdown"; @import "./markdown-tweaks"; @import "./reveal"; +@import "./print"; .text-black, body[data-bs-theme=dark] .text-black { color: $black; diff --git a/frontend/global-styles/markdown-tweaks.scss b/frontend/global-styles/markdown-tweaks.scss index 5d8782155..e1b7e96ea 100644 --- a/frontend/global-styles/markdown-tweaks.scss +++ b/frontend/global-styles/markdown-tweaks.scss @@ -1,5 +1,5 @@ -/* - * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) +/*! + * SPDX-FileCopyrightText: 2024 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ diff --git a/frontend/global-styles/print.scss b/frontend/global-styles/print.scss new file mode 100644 index 000000000..a99a905cd --- /dev/null +++ b/frontend/global-styles/print.scss @@ -0,0 +1,73 @@ +/*! + * SPDX-FileCopyrightText: 2024 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +@media print { + .heading-anchor, .footnote-backref { + display: none; + } + + a[href] { + border-bottom: none; + text-decoration: none; + + &::after { + content: ' (' attr(href) ')'; + font-size: 0.75em; + } + } + + nav.table-of-contents, sup.footnote-ref { + a[href]::after { + display: none; + content: ''; + } + } + + sup.footnote-ref { + a[href] { + color: unset; + } + } + + abbr[title] { + border-bottom: none !important; + text-decoration: none !important; + } + + mark { + print-color-adjust: exact; + -webkit-print-color-adjust: exact; + } + + h1, h2, h3, h4, h5 { + break-after: avoid; + page-break-after: avoid; + } + + table, figure, p, img, ul, ol, pre, code { + break-inside: avoid; + page-break-inside: avoid; + } + + @page { + padding: 1.5cm; + margin: 1cm auto; + } + + .print-only { + display: inline; + } + + hr { + background-color: transparent !important; + border-bottom: 2px solid #bbbcbf; + } +} + +@media screen { + .print-only { + display: none; + } +} diff --git a/frontend/locales/en.json b/frontend/locales/en.json index 3734a7e01..1b40a936f 100644 --- a/frontend/locales/en.json +++ b/frontend/locales/en.json @@ -370,7 +370,8 @@ } }, "rawHtml": "Raw HTML", - "markdown-file": "Markdown file" + "markdown-file": "Markdown file", + "print": "Print" }, "import": { "clipboard": "Clipboard", @@ -971,5 +972,11 @@ "example": "```markdown=12\nline1\n```\n```markdown=+\nline2\n```\n```markdown=\nline3\n```" } } + }, + "print": { + "warning": { + "title": "Warning!", + "text": "To print this note, please use the print button in the export menu in the sidebar. Printing this page directly will not work as expected." + } } } diff --git a/frontend/src/components/common/copyable/copy-to-clipboard-button/__snapshots__/copy-to-clipboard-button.spec.tsx.snap b/frontend/src/components/common/copyable/copy-to-clipboard-button/__snapshots__/copy-to-clipboard-button.spec.tsx.snap index 12f2e8282..12b168954 100644 --- a/frontend/src/components/common/copyable/copy-to-clipboard-button/__snapshots__/copy-to-clipboard-button.spec.tsx.snap +++ b/frontend/src/components/common/copyable/copy-to-clipboard-button/__snapshots__/copy-to-clipboard-button.spec.tsx.snap @@ -3,7 +3,7 @@ exports[`Copy to clipboard button show an error text if clipboard api isn't available 1`] = `