@lancc/cmark 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +37 -5
- package/assets/index-B17NCAw4.js +758 -0
- package/assets/index-eB_q_VA3.css +1 -0
- package/export-file/github-markdown.css +549 -549
- package/export-file/index.html +32 -32
- package/index.html +2 -2
- package/logo.png +0 -0
- package/package.json +1 -1
- package/plugin.json +8 -218
- package/preload/branch-bar.js +44 -2
- package/preload/export-css.js +59 -0
- package/preload/git-panel.js +73 -18
- package/preload/git-service.js +64 -4
- package/preload/host.js +130 -0
- package/preload/remote-setup.js +392 -0
- package/preload/remote-wizard.js +328 -0
- package/preload/rename-note.js +4 -5
- package/preload/services.js +6 -15
- package/preload/settings-panel.js +468 -356
- package/preload/ws-prefs.js +55 -0
- package/preload.js +261 -6
- package/assets/index-BLONSItV.css +0 -1
- package/assets/index-Cz6qaZbV.js +0 -744
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* remote-wizard.js —— 一键建仓向导(GitHub Device Flow / Gitee 私人令牌)
|
|
3
|
+
*
|
|
4
|
+
* 界面约束(ZTools 插件里不能用的东西):
|
|
5
|
+
* - 不用 window.confirm / alert:原生模态会抢焦点,宿主随即隐藏插件窗口
|
|
6
|
+
* - 不用 location.reload()
|
|
7
|
+
* 所以确认与进度都在自建遮罩层里完成。
|
|
8
|
+
*/
|
|
9
|
+
module.exports = function attachRemoteWizard (win) {
|
|
10
|
+
const doc = win.document
|
|
11
|
+
if (!doc) return
|
|
12
|
+
if (!doc.body) { setTimeout(function () { try { attachRemoteWizard(win) } catch (e) {} }, 60); return }
|
|
13
|
+
|
|
14
|
+
const R = function () { return win.__CMARK_REMOTE }
|
|
15
|
+
const LABEL = { github: 'GitHub', gitee: 'Gitee' }
|
|
16
|
+
|
|
17
|
+
function injectCss () {
|
|
18
|
+
if (doc.getElementById('crw-css')) return
|
|
19
|
+
const st = doc.createElement('style')
|
|
20
|
+
st.id = 'crw-css'
|
|
21
|
+
st.textContent = `
|
|
22
|
+
.crw-mask{position:fixed;inset:0;z-index:99999;background:rgba(0,0,0,.45);
|
|
23
|
+
display:flex;align-items:center;justify-content:center;}
|
|
24
|
+
.crw-card{width:min(460px,calc(100vw - 48px));max-height:86vh;overflow:auto;
|
|
25
|
+
background:var(--zgp-bg,#fff);color:var(--zgp-fg,#1f2328);
|
|
26
|
+
border:1px solid var(--zgp-bd,#e3e6ea);border-radius:12px;
|
|
27
|
+
box-shadow:var(--zgp-shadow,0 8px 32px rgba(0,0,0,.18));padding:18px;}
|
|
28
|
+
.crw-h{font-size:14px;font-weight:600;margin:0 0 4px;display:flex;align-items:center;justify-content:space-between;}
|
|
29
|
+
.crw-x{cursor:pointer;border:none;background:transparent;color:var(--zgp-fg3,#8b949e);font-size:18px;line-height:1;}
|
|
30
|
+
.crw-desc{font-size:12px;line-height:1.75;color:var(--zgp-fg2,#57606a);}
|
|
31
|
+
.crw-code{font-family:Consolas,Menlo,monospace;font-size:26px;letter-spacing:.28em;
|
|
32
|
+
text-align:center;padding:14px 0;margin:10px 0;border-radius:10px;
|
|
33
|
+
background:var(--zgp-bg3,#eef0f4);color:var(--zgp-fg,#1f2328);user-select:all;}
|
|
34
|
+
.crw-row{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap;}
|
|
35
|
+
.crw-row.end{justify-content:flex-end;}
|
|
36
|
+
.crw-b{padding:6px 14px;border-radius:7px;border:1px solid var(--zgp-bd2,#d0d7de);
|
|
37
|
+
background:var(--zgp-bg,#fff);color:var(--zgp-fg2,#57606a);font-size:12.5px;cursor:pointer;}
|
|
38
|
+
.crw-b:hover{border-color:var(--zgp-acc,#2563eb);color:var(--zgp-acc,#2563eb);}
|
|
39
|
+
.crw-b.primary{background:var(--zgp-acc,#2563eb);border-color:var(--zgp-acc,#2563eb);color:#fff;}
|
|
40
|
+
.crw-b[disabled]{opacity:.5;cursor:not-allowed;}
|
|
41
|
+
.crw-url{flex:1;min-width:0;font-family:Consolas,Menlo,monospace;font-size:11.5px;line-height:1.5;
|
|
42
|
+
padding:7px 9px;border-radius:6px;background:var(--zgp-bg3,#eef0f4);
|
|
43
|
+
color:var(--zgp-fg2,#57606a);word-break:break-all;user-select:all;}
|
|
44
|
+
.crw-in{width:100%;box-sizing:border-box;padding:7px 10px;border-radius:7px;
|
|
45
|
+
border:1px solid var(--zgp-bd2,#d0d7de);background:var(--zgp-bg,#fff);
|
|
46
|
+
color:var(--zgp-fg,#1f2328);font-size:12.5px;font-family:inherit;}
|
|
47
|
+
.crw-in:focus{outline:none;border-color:var(--zgp-acc,#2563eb);}
|
|
48
|
+
.crw-sel{width:100%;box-sizing:border-box;padding:7px 10px;border-radius:7px;
|
|
49
|
+
border:1px solid var(--zgp-bd2,#d0d7de);background:var(--zgp-bg,#fff);
|
|
50
|
+
color:var(--zgp-fg,#1f2328);font-size:12.5px;}
|
|
51
|
+
.crw-msg{font-size:12px;margin-top:10px;line-height:1.7;}
|
|
52
|
+
.crw-ok{color:var(--zgp-ok,#1a7f37);}
|
|
53
|
+
.crw-err{color:var(--zgp-err,#cf222e);}
|
|
54
|
+
.crw-dim{color:var(--zgp-fg3,#8b949e);}
|
|
55
|
+
.crw-step{font-size:11.5px;color:var(--zgp-fg3,#8b949e);margin-bottom:8px;}
|
|
56
|
+
`
|
|
57
|
+
try { (doc.head || doc.documentElement).appendChild(st) } catch (e) {}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function open (provider) {
|
|
61
|
+
const api = R()
|
|
62
|
+
if (!api) return
|
|
63
|
+
injectCss()
|
|
64
|
+
if (doc.getElementById('crw-mask')) doc.getElementById('crw-mask').remove()
|
|
65
|
+
|
|
66
|
+
const mask = doc.createElement('div')
|
|
67
|
+
mask.className = 'crw-mask'
|
|
68
|
+
mask.id = 'crw-mask'
|
|
69
|
+
mask.innerHTML = `
|
|
70
|
+
<div class="crw-card">
|
|
71
|
+
<div class="crw-h"><span>绑定 ${LABEL[provider] || ''}</span><button class="crw-x" id="crw-close">×</button></div>
|
|
72
|
+
<div class="crw-step" id="crw-step"></div>
|
|
73
|
+
<div id="crw-body"></div>
|
|
74
|
+
</div>`
|
|
75
|
+
doc.body.appendChild(mask)
|
|
76
|
+
const $ = function (id) { return mask.querySelector('#' + id) }
|
|
77
|
+
const body = $('crw-body')
|
|
78
|
+
const stepEl = $('crw-step')
|
|
79
|
+
const close = function () {
|
|
80
|
+
try { if (typeof stopPoll === 'function') stopPoll() } catch (e) {}
|
|
81
|
+
try { mask.remove() } catch (e) {}
|
|
82
|
+
// 注意:这里不写 Git 开关。取消/关闭不等于建仓成功,只有成功分支才置为开启
|
|
83
|
+
try { win.dispatchEvent(new CustomEvent('cmark-git-changed')) } catch (e) {}
|
|
84
|
+
}
|
|
85
|
+
mask.addEventListener('click', function (e) { if (e.target === mask) close() })
|
|
86
|
+
$('crw-close').onclick = close
|
|
87
|
+
|
|
88
|
+
const state = { provider: provider, token: '', login: '', repos: [], timer: null }
|
|
89
|
+
|
|
90
|
+
function stopPoll () { if (state.timer) { clearTimeout(state.timer); state.timer = null } }
|
|
91
|
+
|
|
92
|
+
// 打开外部窗口前先提示:宿主的窗口策略是失焦即隐藏,授权页一开插件就收起
|
|
93
|
+
function confirmExternal (url) {
|
|
94
|
+
const box = doc.createElement('div')
|
|
95
|
+
box.className = 'crw-mask'
|
|
96
|
+
box.style.zIndex = '100001'
|
|
97
|
+
box.innerHTML = '<div class="crw-card">' +
|
|
98
|
+
'<div class="crw-h"><span>即将打开外部窗口</span><button class="crw-x" id="ce-x">×</button></div>' +
|
|
99
|
+
'<div class="crw-desc">CMark 窗口可能会被隐藏。<br>完成授权后重新呼出 CMark(快捷键),授权进度会保留,可以继续完成设置。</div>' +
|
|
100
|
+
'<div class="crw-row end"><button class="crw-b" id="ce-cancel">取消</button>' +
|
|
101
|
+
'<button class="crw-b primary" id="ce-ok">继续打开</button></div></div>'
|
|
102
|
+
doc.body.appendChild(box)
|
|
103
|
+
const closeBox = function () { try { box.remove() } catch (e) {} }
|
|
104
|
+
box.querySelector('#ce-x').onclick = closeBox
|
|
105
|
+
box.querySelector('#ce-cancel').onclick = closeBox
|
|
106
|
+
box.querySelector('#ce-ok').onclick = function () { closeBox(); api.openUrl(url) }
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// ---- GitHub:申请设备码并轮询 ----
|
|
110
|
+
function ghAuth () {
|
|
111
|
+
stepEl.textContent = '第 1 步 / 共 2 步:授权 GitHub'
|
|
112
|
+
body.innerHTML = '<div class="crw-desc">正在向 GitHub 申请设备码…</div>'
|
|
113
|
+
api.ghStart().then(function (r) {
|
|
114
|
+
if (!r.ok) {
|
|
115
|
+
body.innerHTML = '<div class="crw-msg crw-err">' + esc(r.message) + '</div>'
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
const secs = Math.round((r.expiresIn || 900) / 60)
|
|
119
|
+
body.innerHTML = `
|
|
120
|
+
<div class="crw-desc">在浏览器里打开下面的地址,输入这串代码并确认授权(${secs} 分钟内有效):</div>
|
|
121
|
+
<div class="crw-code">${esc(r.userCode)}</div>
|
|
122
|
+
<div class="crw-row">
|
|
123
|
+
<button class="crw-b" id="crw-copy">复制代码</button>
|
|
124
|
+
<button class="crw-b primary" id="crw-open">打开授权页面</button>
|
|
125
|
+
</div>
|
|
126
|
+
<div class="crw-msg crw-dim" id="crw-wait">等待你在浏览器里确认…(授权完成会自动继续)</div>`
|
|
127
|
+
const openBtn = mask.querySelector('#crw-open')
|
|
128
|
+
if (openBtn) openBtn.onclick = function () { confirmExternal(r.verificationUri) }
|
|
129
|
+
const copyBtn = mask.querySelector('#crw-copy')
|
|
130
|
+
if (copyBtn) {
|
|
131
|
+
copyBtn.onclick = function () {
|
|
132
|
+
try {
|
|
133
|
+
if (win.navigator && win.navigator.clipboard) win.navigator.clipboard.writeText(r.userCode)
|
|
134
|
+
else if (win.ztools && win.ztools.copyText) win.ztools.copyText(r.userCode)
|
|
135
|
+
copyBtn.textContent = '已复制'
|
|
136
|
+
} catch (e) {}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const tick = function () {
|
|
140
|
+
api.ghPoll(r.deviceCode).then(function (p) {
|
|
141
|
+
if (p.ok) {
|
|
142
|
+
state.token = p.token
|
|
143
|
+
return afterToken()
|
|
144
|
+
}
|
|
145
|
+
if (p.message) {
|
|
146
|
+
const w = mask.querySelector('#crw-wait')
|
|
147
|
+
if (w) { w.className = 'crw-msg crw-err'; w.textContent = p.message }
|
|
148
|
+
return
|
|
149
|
+
}
|
|
150
|
+
const w = mask.querySelector('#crw-wait')
|
|
151
|
+
if (w) w.textContent = '等待你在浏览器里确认…(授权完成会自动继续)'
|
|
152
|
+
state.timer = setTimeout(tick, (r.interval || 5) * 1000)
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
state.timer = setTimeout(tick, (r.interval || 5) * 1000)
|
|
156
|
+
})
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ---- Gitee:粘贴私人令牌 ----
|
|
160
|
+
function giteeAuth () {
|
|
161
|
+
stepEl.textContent = '第 1 步 / 共 2 步:填写 Gitee 私人令牌'
|
|
162
|
+
const TOKEN_URL = 'https://gitee.com/profile/personal_access_tokens'
|
|
163
|
+
body.innerHTML = `
|
|
164
|
+
<div class="crw-desc">打开下面的地址生成私人令牌(勾选 <b>projects</b> 权限),复制后粘贴到下方。</div>
|
|
165
|
+
<div class="crw-row" style="margin-top:10px;align-items:center;gap:8px">
|
|
166
|
+
<span class="crw-url" id="crw-token-url">${TOKEN_URL}</span>
|
|
167
|
+
<button class="crw-b" id="crw-copy-token-url" style="flex:0 0 auto">复制</button>
|
|
168
|
+
</div>
|
|
169
|
+
<div class="crw-row" style="margin-top:12px"><input class="crw-in" id="crw-tk" placeholder="粘贴私人令牌" /></div>
|
|
170
|
+
<div class="crw-row end"><button class="crw-b primary" id="crw-verify">验证并继续</button></div>
|
|
171
|
+
<div class="crw-msg" id="crw-tkmsg"></div>`
|
|
172
|
+
const copyUrlBtn = mask.querySelector('#crw-copy-token-url')
|
|
173
|
+
if (copyUrlBtn) {
|
|
174
|
+
copyUrlBtn.onclick = function () {
|
|
175
|
+
let ok = false
|
|
176
|
+
try {
|
|
177
|
+
if (win.ztools && typeof win.ztools.copyText === 'function') { win.ztools.copyText(TOKEN_URL); ok = true }
|
|
178
|
+
else if (win.navigator && win.navigator.clipboard) { win.navigator.clipboard.writeText(TOKEN_URL); ok = true }
|
|
179
|
+
} catch (e) { ok = false }
|
|
180
|
+
copyUrlBtn.textContent = ok ? '已复制' : '复制失败'
|
|
181
|
+
setTimeout(function () { copyUrlBtn.textContent = '复制' }, 1600)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const btn = mask.querySelector('#crw-verify')
|
|
185
|
+
btn.onclick = function () {
|
|
186
|
+
const tk = (mask.querySelector('#crw-tk').value || '').trim()
|
|
187
|
+
if (!tk) return
|
|
188
|
+
btn.disabled = true
|
|
189
|
+
const m = mask.querySelector('#crw-tkmsg')
|
|
190
|
+
m.className = 'crw-msg crw-dim'
|
|
191
|
+
m.textContent = '验证中…'
|
|
192
|
+
api.giteeVerify(tk).then(function (r) {
|
|
193
|
+
btn.disabled = false
|
|
194
|
+
if (!r.ok) {
|
|
195
|
+
m.className = 'crw-msg crw-err'
|
|
196
|
+
m.textContent = r.message
|
|
197
|
+
return
|
|
198
|
+
}
|
|
199
|
+
state.token = tk
|
|
200
|
+
afterToken()
|
|
201
|
+
})
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// ---- 授权完成:列仓库 + 新建/选择 ----
|
|
206
|
+
function afterToken () {
|
|
207
|
+
stopPoll()
|
|
208
|
+
stepEl.textContent = '第 2 步 / 共 2 步:选择仓库'
|
|
209
|
+
body.innerHTML = '<div class="crw-desc">正在读取你的仓库列表…</div>'
|
|
210
|
+
const listFn = state.provider === 'github' ? api.ghListRepos : api.giteeListRepos
|
|
211
|
+
const userFn = state.provider === 'github' ? api.ghUser : api.giteeVerify
|
|
212
|
+
userFn(state.token).then(function (u) {
|
|
213
|
+
if (!u.ok) {
|
|
214
|
+
body.innerHTML = '<div class="crw-msg crw-err">' + esc(u.message) + '</div>'
|
|
215
|
+
return
|
|
216
|
+
}
|
|
217
|
+
state.login = u.login || ''
|
|
218
|
+
return listFn(state.token).then(function (r) {
|
|
219
|
+
if (!r.ok) {
|
|
220
|
+
body.innerHTML = '<div class="crw-msg crw-err">' + esc(r.message) + '</div>'
|
|
221
|
+
return
|
|
222
|
+
}
|
|
223
|
+
state.repos = r.repos || []
|
|
224
|
+
renderPick()
|
|
225
|
+
})
|
|
226
|
+
})
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function renderPick () {
|
|
230
|
+
const opts = state.repos.map(function (x) {
|
|
231
|
+
return '<option value="' + esc(x.url) + '">' + esc(x.fullName) + (x.private ? '(私有)' : '') + '</option>'
|
|
232
|
+
}).join('')
|
|
233
|
+
// 建仓目标是工作区(仓库根),不是笔记子目录
|
|
234
|
+
let ws = ''
|
|
235
|
+
try { ws = (win.__CMARK && win.__CMARK.repoDir ? win.__CMARK.repoDir() : '') || '' } catch (e) {}
|
|
236
|
+
if (!ws) ws = win.__ZNOTES_WS || ''
|
|
237
|
+
body.innerHTML = `
|
|
238
|
+
<div class="crw-desc">已授权 <b>${esc(state.login)}</b>。当前笔记目录:<br><span class="crw-dim">${esc(ws || '未设置')}</span></div>
|
|
239
|
+
<div class="crw-row" style="margin-top:14px">
|
|
240
|
+
<label class="crw-desc"><input type="radio" name="crw-mode" value="new" checked> 新建仓库</label>
|
|
241
|
+
<label class="crw-desc"><input type="radio" name="crw-mode" value="existing"> 使用已有仓库</label>
|
|
242
|
+
</div>
|
|
243
|
+
<div id="crw-new" class="crw-row"><input class="crw-in" id="crw-name" placeholder="仓库名,如 cmark-notes" value="cmark-notes" /></div>
|
|
244
|
+
<div id="crw-old" class="crw-row" style="display:none"><select class="crw-sel" id="crw-repolist">${opts || '<option value="">(没有可用仓库)</option>'}</select></div>
|
|
245
|
+
<div class="crw-row end"><button class="crw-b primary" id="crw-go">绑定并同步</button></div>
|
|
246
|
+
<div class="crw-msg" id="crw-go-msg"></div>`
|
|
247
|
+
const radios = mask.querySelectorAll('input[name=crw-mode]')
|
|
248
|
+
for (let i = 0; i < radios.length; i++) {
|
|
249
|
+
radios[i].onchange = function () {
|
|
250
|
+
const isNew = mask.querySelector('input[name=crw-mode]:checked').value === 'new'
|
|
251
|
+
mask.querySelector('#crw-new').style.display = isNew ? 'flex' : 'none'
|
|
252
|
+
mask.querySelector('#crw-old').style.display = isNew ? 'none' : 'flex'
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
mask.querySelector('#crw-go').onclick = function () {
|
|
256
|
+
const goBtn = mask.querySelector('#crw-go')
|
|
257
|
+
const msg = mask.querySelector('#crw-go-msg')
|
|
258
|
+
const isNew = mask.querySelector('input[name=crw-mode]:checked').value === 'new'
|
|
259
|
+
if (!ws) {
|
|
260
|
+
msg.className = 'crw-msg crw-err'
|
|
261
|
+
msg.textContent = '还没有笔记目录,请先在设置里选择目录'
|
|
262
|
+
return
|
|
263
|
+
}
|
|
264
|
+
goBtn.disabled = true
|
|
265
|
+
msg.className = 'crw-msg crw-dim'
|
|
266
|
+
msg.textContent = isNew ? '正在创建远程仓库…' : '正在绑定已有仓库…'
|
|
267
|
+
const createFn = state.provider === 'github' ? api.ghCreateRepo : api.giteeCreateRepo
|
|
268
|
+
const start = isNew
|
|
269
|
+
? createFn(state.token, (mask.querySelector('#crw-name').value || 'cmark-notes').trim(), true)
|
|
270
|
+
: Promise.resolve({ ok: true, url: mask.querySelector('#crw-repolist').value })
|
|
271
|
+
start.then(function (c) {
|
|
272
|
+
if (!c.ok) {
|
|
273
|
+
goBtn.disabled = false
|
|
274
|
+
msg.className = 'crw-msg crw-err'
|
|
275
|
+
msg.textContent = c.message || '创建仓库失败'
|
|
276
|
+
return
|
|
277
|
+
}
|
|
278
|
+
msg.textContent = '正在初始化本地仓库并推送…'
|
|
279
|
+
return api.bind({
|
|
280
|
+
provider: state.provider,
|
|
281
|
+
url: c.url,
|
|
282
|
+
token: state.token,
|
|
283
|
+
dir: ws,
|
|
284
|
+
existing: !isNew
|
|
285
|
+
}).then(function (b) {
|
|
286
|
+
goBtn.disabled = false
|
|
287
|
+
if (!b.ok) {
|
|
288
|
+
msg.className = 'crw-msg crw-err'
|
|
289
|
+
msg.textContent = (b.message || '绑定失败') + (b.steps && b.steps.length ? '(已完成:' + b.steps.join(' / ') + ')' : '')
|
|
290
|
+
return
|
|
291
|
+
}
|
|
292
|
+
// 建仓真的成功了:打开 Git 集成开关(按当前工作区落盘),再锁定界面
|
|
293
|
+
try { if (win.__CMARK_GIT && win.__CMARK_GIT.set) win.__CMARK_GIT.set(true) } catch (e) {}
|
|
294
|
+
// git 服务是在插件启动时探测仓库的;刚建好的仓库要让它重新探测一次,
|
|
295
|
+
// 否则设置面板会一直显示「本地仓库未绑定」,直到重启插件
|
|
296
|
+
try { if (win.__znotesGit && win.__znotesGit.rediscover) win.__znotesGit.rediscover() } catch (e) {}
|
|
297
|
+
// 成功即锁定:清空可选仓库/输入,只留一个「完成按钮」,避免继续改配置把状态搞乱
|
|
298
|
+
stopPoll()
|
|
299
|
+
stepEl.textContent = '已完成'
|
|
300
|
+
body.innerHTML = `
|
|
301
|
+
<div class="crw-desc"><b>${state.provider === 'github' ? 'GitHub' : 'Gitee'}</b> 仓库已绑定</div>
|
|
302
|
+
<div class="crw-code" style="font-size:12.5px;letter-spacing:0;padding:12px;word-break:break-all;text-align:left">${esc(c.url)}</div>
|
|
303
|
+
<dl class="crw-kv" style="display:grid;grid-template-columns:56px 1fr;gap:6px 10px;font-size:12px;color:var(--zgp-fg2,#57606a)">
|
|
304
|
+
<dt>目录</dt><dd style="margin:0">${esc(ws)}</dd>
|
|
305
|
+
<dt>步骤</dt><dd style="margin:0">${esc((b.steps || []).join(' / ') || '已完成')}</dd>
|
|
306
|
+
</dl>
|
|
307
|
+
<div class="crw-msg crw-dim" style="margin-top:10px">这个窗口可以关掉了。之后的改动按设置里的自动同步策略推送。</div>
|
|
308
|
+
<div class="crw-row end"><button class="crw-b primary" id="crw-done">完成</button></div>`
|
|
309
|
+
const doneBtn = mask.querySelector('#crw-done')
|
|
310
|
+
if (doneBtn) doneBtn.onclick = close
|
|
311
|
+
return
|
|
312
|
+
})
|
|
313
|
+
})
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (provider === 'github') ghAuth()
|
|
318
|
+
else giteeAuth()
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function esc (s) {
|
|
322
|
+
return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) {
|
|
323
|
+
return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]
|
|
324
|
+
})
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
win.__CMARK_OPEN_WIZARD = open
|
|
328
|
+
}
|
package/preload/rename-note.js
CHANGED
|
@@ -24,11 +24,10 @@ module.exports = function (win, findInstance) {
|
|
|
24
24
|
#${ID} button{padding:6px 14px;border-radius:6px;border:1px solid rgba(128,128,128,.36);
|
|
25
25
|
background:transparent;color:inherit;font-size:12.5px;cursor:pointer;}
|
|
26
26
|
#${ID} button.primary{background:#3f7ef7;border-color:#3f7ef7;color:#fff;}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
27
|
+
:root[data-theme='dark'] #${ID} .zrn-card{background:#2b2f36;color:#e6e6e6;box-shadow:0 16px 40px rgba(0,0,0,.5);}
|
|
28
|
+
:root[data-theme='dark'] #${ID} input{border-color:rgba(255,255,255,.22);}
|
|
29
|
+
:root[data-theme='dark'] #${ID} button{border-color:rgba(255,255,255,.2);}
|
|
30
|
+
|
|
32
31
|
`
|
|
33
32
|
try { (doc.head || doc.body || doc.documentElement).appendChild(st) } catch (e) {}
|
|
34
33
|
}
|
package/preload/services.js
CHANGED
|
@@ -43,6 +43,8 @@ function ensureDir(dir) {
|
|
|
43
43
|
return dir
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
|
|
47
|
+
const { exportDocCss } = require('./export-css')
|
|
46
48
|
function attachmentCacheDir(win) {
|
|
47
49
|
const base = path.join(win.ztools.getPath('temp') || os.tmpdir(), 'cmark.attachments')
|
|
48
50
|
return ensureDir(base)
|
|
@@ -286,7 +288,7 @@ module.exports = function installServices(win) {
|
|
|
286
288
|
},
|
|
287
289
|
|
|
288
290
|
/** 导出 HTML:套一层文档壳,样式内联 */
|
|
289
|
-
writeHtmlFile(dir, name, html, attachmentPaths, withKatex) {
|
|
291
|
+
writeHtmlFile(dir, name, html, attachmentPaths, withKatex, selfContained, theme) {
|
|
290
292
|
const base = safeName(name, Date.now())
|
|
291
293
|
const katexCss = withKatex
|
|
292
294
|
? '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.css">'
|
|
@@ -300,16 +302,7 @@ module.exports = function installServices(win) {
|
|
|
300
302
|
'<title>' + base + '</title>',
|
|
301
303
|
katexCss,
|
|
302
304
|
'<style>',
|
|
303
|
-
|
|
304
|
-
'.markdown-body{box-sizing:border-box;max-width:980px;margin:0 auto;padding:45px}',
|
|
305
|
-
'@media (max-width:767px){.markdown-body{padding:16px}}',
|
|
306
|
-
'.markdown-body h1,.markdown-body h2{border-bottom:1px solid #eaecef;padding-bottom:.3em}',
|
|
307
|
-
'.markdown-body code{background:#f6f8fa;border-radius:4px;padding:.2em .4em;font-size:.9em}',
|
|
308
|
-
'.markdown-body pre{background:#f6f8fa;border-radius:8px;padding:14px;overflow:auto}',
|
|
309
|
-
'.markdown-body pre code{background:none;padding:0}',
|
|
310
|
-
'.markdown-body blockquote{margin:0;padding:0 1em;color:#57606a;border-left:.25em solid #d0d7de}',
|
|
311
|
-
'.markdown-body table{border-collapse:collapse}.markdown-body th,.markdown-body td{border:1px solid #d0d7de;padding:6px 12px}',
|
|
312
|
-
'.markdown-body img{max-width:100%}',
|
|
305
|
+
exportDocCss(theme),
|
|
313
306
|
'</style>',
|
|
314
307
|
'</head>',
|
|
315
308
|
'<body><article class="markdown-body">',
|
|
@@ -339,7 +332,7 @@ module.exports = function installServices(win) {
|
|
|
339
332
|
* 导出 PDF / 图片:开隐藏窗口渲染 HTML,再抓图或打印
|
|
340
333
|
* type: 'pdf' | 'image'
|
|
341
334
|
*/
|
|
342
|
-
exportFile(type, html, extraCss, cb, outDir) {
|
|
335
|
+
exportFile(type, html, extraCss, cb, outDir, theme) {
|
|
343
336
|
const done = typeof cb === 'function' ? cb : () => {}
|
|
344
337
|
if (!win.ztools.createBrowserWindow) {
|
|
345
338
|
done(new Error('当前平台不支持静默渲染,请改用导出 HTML'))
|
|
@@ -349,9 +342,7 @@ module.exports = function installServices(win) {
|
|
|
349
342
|
'<!doctype html><html><head><meta charset="utf-8"/>',
|
|
350
343
|
'<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.css">',
|
|
351
344
|
'<style>',
|
|
352
|
-
|
|
353
|
-
'.markdown-body{box-sizing:border-box;max-width:980px;margin:0 auto;padding:45px;',
|
|
354
|
-
'color:#24292f;font:16px/1.7 -apple-system,"Segoe UI",system-ui,"Microsoft YaHei",sans-serif}',
|
|
345
|
+
exportDocCss(theme),
|
|
355
346
|
extraCss || '',
|
|
356
347
|
'</style></head><body><article class="markdown-body"></article></body></html>',
|
|
357
348
|
].join('\n')
|