mirror of
https://github.com/doocs/cose.git
synced 2026-08-28 23:02:10 +08:00
feat: add popup page for extension installation guide (#236)
This commit is contained in:
@@ -63,7 +63,8 @@
|
||||
"48": "icons/cose_48.png",
|
||||
"128": "icons/cose_128.png"
|
||||
},
|
||||
"default_title": "COSE"
|
||||
"default_title": "COSE",
|
||||
"default_popup": "popup.html"
|
||||
},
|
||||
"background": {
|
||||
"service_worker": "bundles/background.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cose-extension",
|
||||
"version": "1.3.3",
|
||||
"version": "1.3.4",
|
||||
"description": "Create Once, Sync Everywhere. 一键将文章同步到多个平台",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -350,11 +350,6 @@ chrome.runtime.onStartup.addListener(() => {
|
||||
initDynamicRules()
|
||||
})
|
||||
|
||||
// 点击扩展图标时打开 md.doocs.org
|
||||
chrome.action.onClicked.addListener(() => {
|
||||
chrome.tabs.create({ url: 'https://md.doocs.org' })
|
||||
})
|
||||
|
||||
// 当前同步任务的 Tab Group ID
|
||||
let currentSyncGroupId = null
|
||||
// 存储平台用户信息
|
||||
@@ -1088,8 +1083,11 @@ async function syncToPlatform(platformId, content) {
|
||||
html = html.replace(/^> (.+)$/gm, '<blockquote>$1</blockquote>')
|
||||
|
||||
// 处理水平分割线
|
||||
html = html.replace(/^---$/gm, '<hr />')
|
||||
html = html.replace(/^\*\*\*$/gm, '<hr />')
|
||||
// 注意: X Articles 忽略 <hr> 标签,需要通过 Insert > Divider 菜单插入
|
||||
// 自动同步无法使用菜单,这里保留 hr 但用户可能需要手动调整
|
||||
// 或者可以考虑用视觉分隔符如 --- 文本替代
|
||||
html = html.replace(/^---$/gm, '<p>---</p>')
|
||||
html = html.replace(/^\*\*\*$/gm, '<p>***</p>')
|
||||
|
||||
// 处理图片
|
||||
html = html.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img src="$2" alt="$1" style="max-width: 100%;" />')
|
||||
@@ -1104,7 +1102,8 @@ async function syncToPlatform(platformId, content) {
|
||||
|
||||
// ========== 第三阶段:恢复保护的内容 ==========
|
||||
|
||||
// 恢复代码块(使用样式化的 pre/code)
|
||||
// 恢复代码块 - X Articles 不支持 <pre><code>,转换为 blockquote
|
||||
// 参考 x-article-publisher skill 的实现
|
||||
codeBlocks.forEach((block, index) => {
|
||||
const escapedCode = block.code
|
||||
.replace(/&/g, '&')
|
||||
@@ -1113,19 +1112,25 @@ async function syncToPlatform(platformId, content) {
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
|
||||
const langLabel = block.lang ? `<div style="background: #e1e4e8; padding: 4px 12px; font-size: 12px; color: #586069; border-radius: 6px 6px 0 0;">${block.lang}</div>` : ''
|
||||
const codeHtml = `<div style="margin: 16px 0;">${langLabel}<pre style="background: #f6f8fa; padding: 16px; border-radius: ${block.lang ? '0 0 6px 6px' : '6px'}; overflow-x: auto; font-family: 'SF Mono', Consolas, 'Liberation Mono', Menlo, monospace; font-size: 14px; line-height: 1.45; margin: 0; white-space: pre-wrap; word-wrap: break-word;"><code>${escapedCode}</code></pre></div>`
|
||||
// 将代码行用 <br> 连接,包装在 blockquote 中
|
||||
// X Articles 原生支持 blockquote,这是最可靠的代码块显示方式
|
||||
const lines = escapedCode.split('\n').filter(line => line.trim())
|
||||
const formattedCode = lines.join('<br>')
|
||||
const langPrefix = block.lang ? `<strong>${block.lang}</strong><br>` : ''
|
||||
const codeHtml = `<blockquote>${langPrefix}${formattedCode}</blockquote>`
|
||||
|
||||
html = html.replace(`__CODE_BLOCK_${index}__`, codeHtml)
|
||||
})
|
||||
|
||||
// 恢复行内代码
|
||||
// 恢复行内代码 - X Articles 对 inline style 支持有限
|
||||
// 使用简单的 <code> 标签,依赖平台默认样式
|
||||
inlineCodes.forEach((code, index) => {
|
||||
const escapedCode = code
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
const codeHtml = `<code style="background: #f6f8fa; padding: 2px 6px; border-radius: 3px; font-family: 'SF Mono', Consolas, monospace; font-size: 0.9em;">${escapedCode}</code>`
|
||||
// 简化为纯 code 标签,X Articles 会应用默认样式
|
||||
const codeHtml = `<code>${escapedCode}</code>`
|
||||
|
||||
html = html.replace(`__INLINE_CODE_${index}__`, codeHtml)
|
||||
})
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
width: 320px;
|
||||
padding: 20px;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background: #fff;
|
||||
color: #333;
|
||||
}
|
||||
.container {
|
||||
text-align: center;
|
||||
}
|
||||
h1 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
p {
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
p a {
|
||||
color: #FE5200;
|
||||
text-decoration: none;
|
||||
}
|
||||
p a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 10px 20px;
|
||||
background: #FE5200;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
transition: background 0.2s;
|
||||
border: 1px solid #e64a00;
|
||||
cursor: pointer;
|
||||
}
|
||||
.btn:hover {
|
||||
background: #e64a00;
|
||||
}
|
||||
.divider {
|
||||
margin: 16px 0;
|
||||
border-top: 1px solid #e5e5e5;
|
||||
}
|
||||
.hint {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>COSE - 多平台文章同步</h1>
|
||||
<p>插件安装完成!</p>
|
||||
<p>打开<a href="https://github.com/doocs/md" target="_blank">自托管的编辑器</a>即可自动检测到,无需多余配置。</p>
|
||||
<div class="divider"></div>
|
||||
<p class="hint">没有自托管编辑器?</p>
|
||||
<a href="https://md.doocs.org" target="_blank" class="btn" id="openOfficial">也可使用官网编辑器</a>
|
||||
</div>
|
||||
<script src="bundles/popup.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,6 @@
|
||||
// Popup script for COSE extension
|
||||
document.getElementById('openOfficial').addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
chrome.tabs.create({ url: 'https://md.doocs.org' })
|
||||
window.close()
|
||||
})
|
||||
@@ -21,6 +21,7 @@ export default defineConfig({
|
||||
content: resolve(__dirname, 'src/content.js'),
|
||||
inject: resolve(__dirname, 'src/inject.js'),
|
||||
offscreen: resolve(__dirname, 'src/offscreen.js'),
|
||||
popup: resolve(__dirname, 'src/popup.js'),
|
||||
},
|
||||
output: {
|
||||
entryFileNames: 'bundles/[name].js',
|
||||
@@ -42,6 +43,10 @@ export default defineConfig({
|
||||
src: 'src/offscreen.html',
|
||||
dest: '.',
|
||||
},
|
||||
{
|
||||
src: 'src/popup.html',
|
||||
dest: '.',
|
||||
},
|
||||
{
|
||||
src: 'assets',
|
||||
dest: '.',
|
||||
|
||||
Reference in New Issue
Block a user