From 22bdce6e83a9aa71f5f1a67b10bb9961adb5e10a Mon Sep 17 00:00:00 2001 From: purocean Date: Wed, 9 Feb 2022 22:21:28 +0800 Subject: [PATCH] feat: add copy rendered content panel --- src/renderer/plugins/copy-rendered-content.ts | 58 ----------- .../plugins/copy-rendered-content.tsx | 95 +++++++++++++++++++ src/renderer/plugins/markdown-macro.ts | 40 ++++---- src/share/i18n/languages/en.ts | 11 ++- src/share/i18n/languages/zh-CN.ts | 11 ++- 5 files changed, 134 insertions(+), 81 deletions(-) delete mode 100644 src/renderer/plugins/copy-rendered-content.ts create mode 100644 src/renderer/plugins/copy-rendered-content.tsx diff --git a/src/renderer/plugins/copy-rendered-content.ts b/src/renderer/plugins/copy-rendered-content.ts deleted file mode 100644 index efadd21d..00000000 --- a/src/renderer/plugins/copy-rendered-content.ts +++ /dev/null @@ -1,58 +0,0 @@ -import type { Plugin } from '@fe/context' - -export default { - name: 'copy-rendered-content', - register: (ctx) => { - async function copyHTML (inlineStyle: boolean) { - // TODO copy panel - const html = await ctx.view.getContentHtml({ inlineStyle, highlightCode: inlineStyle }) - ctx.utils.copyText(html) - } - - async function copyRTF (inlineStyle: boolean) { - try { - const html = await ctx.view.getContentHtml({ inlineStyle }) - await ctx.base.writeToClipboard('text/html', html) - ctx.ui.useToast().show('info', ctx.i18n.t('copied')) - } catch (error: any) { - console.error(error) - ctx.ui.useToast().show('warning', error.message) - } - } - - ctx.statusBar.tapMenus(menus => { - menus['status-bar-tool']?.list?.push( - { type: 'separator' }, - { - id: 'plugin.copy-rendered-content.copy-rtf', - type: 'normal', - title: ctx.i18n.t('status-bar.tool.copy-rtf'), - subTitle: 'Bare', - onClick: () => copyRTF(false) - }, - { - id: 'plugin.copy-rendered-content.copy-rtf', - type: 'normal', - title: ctx.i18n.t('status-bar.tool.copy-rtf'), - subTitle: 'Styled', - onClick: () => copyRTF(true) - }, - { type: 'separator' }, - { - id: 'plugin.copy-rendered-content.copy-html', - type: 'normal', - title: ctx.i18n.t('status-bar.tool.copy-html'), - subTitle: 'Bare', - onClick: () => copyHTML(false) - }, - { - id: 'plugin.copy-rendered-content.copy-html', - type: 'normal', - title: ctx.i18n.t('status-bar.tool.copy-html'), - subTitle: 'Styled', - onClick: () => copyHTML(true) - }, - ) - }) - } -} as Plugin diff --git a/src/renderer/plugins/copy-rendered-content.tsx b/src/renderer/plugins/copy-rendered-content.tsx new file mode 100644 index 00000000..cc1a4ebf --- /dev/null +++ b/src/renderer/plugins/copy-rendered-content.tsx @@ -0,0 +1,95 @@ +import type { Plugin } from '@fe/context' + +export default { + name: 'copy-rendered-content', + register: (ctx) => { + const options = ctx.lib.vue.reactive({ + inlineStyle: false, + inlineLocalImage: false, + highlightCode: false, + type: 'rtf' as 'html' | 'rtf', + }) + + const panel = ctx.lib.vue.defineComponent({ + setup () { + return () =>
+
+
{ctx.i18n.t('copy-rendered-content.options')}
+
+ + + +
+
+
+
{ctx.i18n.t('copy-rendered-content.type')}
+
+ + +
+
+
+ } + }) + + async function copyContent () { + if (await ctx.ui.useModal().confirm({ + title: ctx.i18n.t('status-bar.tool.copy-content'), + component: panel, + })) { + try { + const html = await ctx.view.getContentHtml(options) + + if (options.type === 'rtf') { + await ctx.base.writeToClipboard('text/html', html) + ctx.ui.useToast().show('info', ctx.i18n.t('copied')) + } else { + ctx.utils.copyText(html) + } + } catch (error: any) { + console.error(error) + ctx.ui.useToast().show('warning', error.message) + } + } + } + + ctx.statusBar.tapMenus(menus => { + menus['status-bar-tool']?.list?.push( + { type: 'separator' }, + { + id: 'plugin.copy-rendered-content.copy-content', + type: 'normal', + title: ctx.i18n.t('status-bar.tool.copy-content'), + onClick: () => copyContent() + }, + ) + }) + + ctx.theme.addStyles(` + .copy-rendered-content { + margin-top: 20px; + } + + .copy-rendered-content > div { + padding: 4px 12px; + display: flex; + } + + .copy-rendered-content > div > div { + display: flex; + flex-wrap: wrap; + } + + .copy-rendered-content .label { + width: 100px; + flex: none; + } + + .copy-rendered-content label { + margin-left: 12px; + white-space: nowrap; + margin-bottom: 8px; + } + `) + } +} as Plugin diff --git a/src/renderer/plugins/markdown-macro.ts b/src/renderer/plugins/markdown-macro.ts index 7a6a6689..ae34eba2 100644 --- a/src/renderer/plugins/markdown-macro.ts +++ b/src/renderer/plugins/markdown-macro.ts @@ -351,27 +351,29 @@ export default { }) }) - ctx.statusBar.tapMenus(menus => { - const list = menus['status-bar-tool']?.list - if (list) { - const id = 'plugin.markdown-macro.copy-markdown' - const menu: MenuItem = { - id, - type: 'normal', - hidden: !(ctx.view.getRenderEnv()?.attributes?.enableMacro), - title: ctx.i18n.t('status-bar.tool.macro-copy-markdown'), - onClick: () => { - ctx.utils.copyText(ctx.view.getRenderEnv()?.source) + ctx.registerHook('STARTUP', () => { + ctx.statusBar.tapMenus(menus => { + const list = menus['status-bar-tool']?.list + if (list) { + const id = 'plugin.markdown-macro.copy-markdown' + const menu: MenuItem = { + id, + type: 'normal', + hidden: !(ctx.view.getRenderEnv()?.attributes?.enableMacro), + title: ctx.i18n.t('status-bar.tool.macro-copy-markdown'), + onClick: () => { + ctx.utils.copyText(ctx.view.getRenderEnv()?.source) + } + } + + const item = list.find(x => x.type === 'normal' && x.id === id) + if (item) { + Object.assign(item, menu) + } else { + list.push(menu) } } - - const item = list.find(x => x.type === 'normal' && x.id === id) - if (item) { - Object.assign(item, menu) - } else { - list.push(menu) - } - } + }) }) ctx.registerHook('VIEW_RENDERED', () => { diff --git a/src/share/i18n/languages/en.ts b/src/share/i18n/languages/en.ts index 87652a59..7db1ff0b 100644 --- a/src/share/i18n/languages/en.ts +++ b/src/share/i18n/languages/en.ts @@ -217,8 +217,7 @@ const data = { 'tool': 'Tool', 'convert-img-link': 'Download Remote Image', 'macro-copy-markdown': 'Copy Markdown after Macro Replacement', - 'copy-rtf': 'Copy Rich Text', - 'copy-html': 'Copy Rendered HTML', + 'copy-content': 'Copy Rendered Content', 'doc-history': 'Document History' }, 'document-info': { @@ -476,6 +475,14 @@ const data = { 'hint': 'Input some message (optional)', }, }, + 'copy-rendered-content': { + 'options': 'Options: ', + 'type': 'Copy Type: ', + 'inline-style': 'Inline Style', + 'inline-image': 'Inline Local Image', + 'highlight-code': 'Highlight Code', + 'rtf': 'Rich Text Format', + }, } export type BaseLanguage = typeof data diff --git a/src/share/i18n/languages/zh-CN.ts b/src/share/i18n/languages/zh-CN.ts index 7f3c2e29..d6c5ddbc 100644 --- a/src/share/i18n/languages/zh-CN.ts +++ b/src/share/i18n/languages/zh-CN.ts @@ -218,8 +218,7 @@ const data: BaseLanguage = { 'tool': '工具', 'convert-img-link': '下载外链图片', 'macro-copy-markdown': '复制宏替换后的 Markdown', - 'copy-rtf': '拷贝富文本', - 'copy-html': '拷贝渲染后的 HTML', + 'copy-content': '复制渲染内容', 'doc-history': '文档历史版本' }, 'document-info': { @@ -477,6 +476,14 @@ const data: BaseLanguage = { 'hint': '输入一些信息(可选)', }, }, + 'copy-rendered-content': { + 'options': '选项: ', + 'type': '复制类型: ', + 'inline-style': '内联样式', + 'inline-image': '内联本地图片', + 'highlight-code': '高亮代码', + 'rtf': '富文本', + }, } export default data