mirror of
https://github.com/purocean/yn.git
synced 2026-09-24 15:46:02 +08:00
feat: add copy rendered content panel
This commit is contained in:
@@ -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
|
||||
@@ -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 () => <div class="copy-rendered-content">
|
||||
<div>
|
||||
<div class="label">{ctx.i18n.t('copy-rendered-content.options')}</div>
|
||||
<div>
|
||||
<label><input v-model={options.inlineStyle} type="checkbox" /> {ctx.i18n.t('copy-rendered-content.inline-style')} </label>
|
||||
<label><input v-model={options.inlineLocalImage} type="checkbox" /> {ctx.i18n.t('copy-rendered-content.inline-image')} </label>
|
||||
<label><input v-model={options.highlightCode} type="checkbox" /> {ctx.i18n.t('copy-rendered-content.highlight-code')} </label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="label">{ctx.i18n.t('copy-rendered-content.type')}</div>
|
||||
<div>
|
||||
<label><input v-model={options.type} type="radio" value="rtf" /> {ctx.i18n.t('copy-rendered-content.rtf')}</label>
|
||||
<label><input v-model={options.type} type="radio" value="html" /> HTML </label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
})
|
||||
|
||||
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
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user