From 241bcab7f92e0ad505baea6d6b31254f220f10dd Mon Sep 17 00:00:00 2001 From: fantasticit Date: Sun, 8 Jan 2023 20:01:00 +0800 Subject: [PATCH] fix charset; use file-saver --- packages/client/package.json | 2 +- .../client/src/components/document/export/index.tsx | 11 +++++++---- .../tiptap/markdown/prosemirror-to-markdown/index.ts | 5 ++++- packages/client/src/tiptap/prose-utils/download.ts | 9 +++------ pnpm-lock.yaml | 12 ++++++------ 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/packages/client/package.json b/packages/client/package.json index a8c382ce..8262670e 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -64,7 +64,7 @@ "cross-env": "^7.0.3", "deep-equal": "^2.0.5", "dompurify": "^2.3.5", - "downloadjs": "^1.4.7", + "file-saver": "^2.0.5", "htmldiff-js": "^1.0.5", "interactjs": "^1.10.11", "katex": "^0.15.2", diff --git a/packages/client/src/components/document/export/index.tsx b/packages/client/src/components/document/export/index.tsx index c1937c84..186391e2 100644 --- a/packages/client/src/components/document/export/index.tsx +++ b/packages/client/src/components/document/export/index.tsx @@ -2,7 +2,7 @@ import { Badge, Button, Dropdown, Modal, Space, Typography } from '@douyinfe/sem import { IDocument } from '@think/domains'; import { IconJSON, IconMarkdown, IconPDF, IconWord } from 'components/icons'; import { useDocumentDetail } from 'data/document'; -import download from 'downloadjs'; +import FileSaver from 'file-saver'; import { safeJSONParse, safeJSONStringify } from 'helpers/json'; import { IsOnMobile } from 'hooks/use-on-mobile'; import { useToggle } from 'hooks/use-toggle'; @@ -40,18 +40,21 @@ export const DocumentExporter: React.FC = ({ document, render }) => { const exportMarkdown = useCallback(() => { const md = prosemirrorToMarkdown({ content: editor.state.doc.slice(0).content }); - download(md, `${document.title}.md`, 'text/plain'); + const blob = new Blob([md], { type: 'text/plain;charset=utf-8' }); + FileSaver.saveAs(blob, `${document.title}.md`); }, [document, editor]); const exportJSON = useCallback(() => { - download(safeJSONStringify(editor.getJSON()), `${document.title}.json`, 'text/plain'); + const blob = new Blob([safeJSONStringify(editor.getJSON())], { type: 'text/plain;charset=utf-8' }); + FileSaver.saveAs(blob, `${document.title}.json`); }, [document, editor]); const exportWord = useCallback(() => { const editorContent = editor.view.dom.closest('.ProseMirror'); if (editorContent) { exportDocx(editorContent.outerHTML).then((res) => { - download(Buffer.from(res as Buffer), `${document.title}.docx`); + const blob = new Blob([Buffer.from(res as Buffer)], { type: 'text/plain;charset=utf-8' }); + FileSaver.saveAs(blob, `${document.title}.docx`); }); } }, [editor, exportDocx, document]); diff --git a/packages/client/src/tiptap/markdown/prosemirror-to-markdown/index.ts b/packages/client/src/tiptap/markdown/prosemirror-to-markdown/index.ts index ab19f90e..b275cec8 100644 --- a/packages/client/src/tiptap/markdown/prosemirror-to-markdown/index.ts +++ b/packages/client/src/tiptap/markdown/prosemirror-to-markdown/index.ts @@ -159,7 +159,9 @@ const SerializerConfig = { [TaskList.name]: (state, node) => { state.renderList(node, ' ', () => (node.attrs.bullet || '*') + ' '); }, - [Text.name]: defaultMarkdownSerializer.nodes.text, + [Text.name]: (state, node) => { + state.text(node.text, false); + }, [Title.name]: renderHTMLNode('div', false, true, { class: 'title' }), }, }; @@ -171,6 +173,7 @@ const SerializerConfig = { */ export const prosemirrorToMarkdown = ({ content }) => { const serializer = new ProseMirrorMarkdownSerializer(SerializerConfig.nodes, SerializerConfig.marks); + const markdown = serializer.serialize(content, { tightLists: true, }); diff --git a/packages/client/src/tiptap/prose-utils/download.ts b/packages/client/src/tiptap/prose-utils/download.ts index a64eec4d..75a3c491 100644 --- a/packages/client/src/tiptap/prose-utils/download.ts +++ b/packages/client/src/tiptap/prose-utils/download.ts @@ -1,8 +1,5 @@ +import FileSaver from 'file-saver'; + export function download(url, name) { - const link = document.createElement('a'); - link.download = name; - link.href = url; - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); + FileSaver.saveAs(url, name); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 878bb61a..832c9791 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -102,7 +102,6 @@ importers: cross-env: ^7.0.3 deep-equal: ^2.0.5 dompurify: ^2.3.5 - downloadjs: ^1.4.7 eslint: ^8.14.0 eslint-config-prettier: ^8.5.0 eslint-plugin-import: ^2.26.0 @@ -110,6 +109,7 @@ importers: eslint-plugin-react: ^7.29.4 eslint-plugin-react-hooks: ^4.5.0 eslint-plugin-simple-import-sort: ^7.0.0 + file-saver: ^2.0.5 fs-extra: ^10.0.0 htmldiff-js: ^1.0.5 interactjs: ^1.10.11 @@ -213,7 +213,7 @@ importers: cross-env: 7.0.3 deep-equal: 2.0.5 dompurify: 2.3.5 - downloadjs: 1.4.7 + file-saver: 2.0.5 htmldiff-js: 1.0.5 interactjs: 1.10.11 katex: 0.15.2 @@ -5774,10 +5774,6 @@ packages: engines: {node: '>=10'} dev: false - /downloadjs/1.4.7: - resolution: {integrity: sha512-LN1gO7+u9xjU5oEScGFKvXhYf7Y/empUIIEAGBs1LzUq/rg5duiDrkuH5A2lQGd5jfMOb9X9usDa2oVXwJ0U/Q==} - dev: false - /duplexify/4.1.2: resolution: {integrity: sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==} dependencies: @@ -6509,6 +6505,10 @@ packages: flat-cache: 3.0.4 dev: true + /file-saver/2.0.5: + resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==} + dev: false + /file-uri-to-path/2.0.0: resolution: {integrity: sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==} engines: {node: '>= 6'}