add: template editor backup & share
This commit is contained in:
parent
ec457969e0
commit
a77026c151
|
|
@ -16,7 +16,7 @@
|
|||
persist="screenX screenY width height sizemode"
|
||||
>
|
||||
<head>
|
||||
<title locale-target="innerHTML">templateEditor.title</title>
|
||||
<title data-l10n-id="title"></title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="referrer" content="no-referrer" />
|
||||
<script>
|
||||
|
|
@ -65,11 +65,6 @@
|
|||
}
|
||||
.footer-container {
|
||||
padding: 5px;
|
||||
margin: 0;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: hidden;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
.list-viewport {
|
||||
|
|
@ -95,14 +90,6 @@
|
|||
width: calc(40% - 10px);
|
||||
padding: 5px;
|
||||
}
|
||||
.tool-button {
|
||||
width: 100px;
|
||||
max-width: 100px;
|
||||
min-width: 100px;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
margin: 0 10px 0 10px;
|
||||
}
|
||||
.markdown-body {
|
||||
box-sizing: border-box;
|
||||
min-width: 200px;
|
||||
|
|
@ -116,6 +103,7 @@
|
|||
type="text/css"
|
||||
href="chrome://__addonRef__/content/lib/css/github-markdown-light.min.css"
|
||||
/>
|
||||
<link rel="localization" href="__addonRef__-templateEditor.ftl" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="viewport-container">
|
||||
|
|
@ -124,9 +112,7 @@
|
|||
</div>
|
||||
<div class="viewport editor-viewport">
|
||||
<div style="display: flex">
|
||||
<div style="flex-shrink: 0" locale-target="innerHTML">
|
||||
templateEditor.templateName
|
||||
</div>
|
||||
<div style="flex-shrink: 0" data-l10n-id="templateName"></div>
|
||||
<input id="editor-name" type="text" style="width: 100%" />
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
|
|
@ -138,9 +124,7 @@
|
|||
</div>
|
||||
<div class="viewport preview-viewport">
|
||||
<div style="display: flex">
|
||||
<div style="flex-shrink: 0" locale-target="innerHTML">
|
||||
templateEditor.previewContainer
|
||||
</div>
|
||||
<div style="flex-shrink: 0" data-l10n-id="previewContainer"></div>
|
||||
</div>
|
||||
<article id="preview-container" class="markdown-body"></article>
|
||||
</div>
|
||||
|
|
@ -148,62 +132,30 @@
|
|||
<div
|
||||
class="footer-container"
|
||||
style="justify-content: flex-start; padding: 10px"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
>
|
||||
<button id="create" data-l10n-id="create"></button>
|
||||
<button id="save" data-l10n-id="save"></button>
|
||||
<button id="delete" data-l10n-id="delete"></button>
|
||||
<button id="reset" data-l10n-id="reset"></button>
|
||||
<button id="more" data-l10n-id="more"></button>
|
||||
<button
|
||||
class="tool-button"
|
||||
id="create"
|
||||
locale-target="innerHTML,title"
|
||||
title="templateEditor.createDetail"
|
||||
id="options"
|
||||
data-l10n-id="options"
|
||||
tabindex="-1"
|
||||
type="menu"
|
||||
wantdropmarker="true"
|
||||
>
|
||||
templateEditor.create
|
||||
</button>
|
||||
<button
|
||||
class="tool-button"
|
||||
id="import"
|
||||
locale-target="innerHTML,title"
|
||||
title="templateEditor.importDetail"
|
||||
>
|
||||
templateEditor.import
|
||||
</button>
|
||||
<button
|
||||
class="tool-button"
|
||||
id="more"
|
||||
locale-target="innerHTML,title"
|
||||
title="templateEditor.moreDetail"
|
||||
>
|
||||
templateEditor.more
|
||||
</button>
|
||||
<button
|
||||
class="tool-button"
|
||||
id="save"
|
||||
locale-target="innerHTML,title"
|
||||
title="templateEditor.saveDetail"
|
||||
>
|
||||
templateEditor.save
|
||||
</button>
|
||||
<button
|
||||
class="tool-button"
|
||||
id="delete"
|
||||
locale-target="innerHTML,title"
|
||||
title="templateEditor.deleteDetail"
|
||||
>
|
||||
templateEditor.delete
|
||||
</button>
|
||||
<button
|
||||
class="tool-button"
|
||||
id="reset"
|
||||
locale-target="innerHTML,title"
|
||||
title="templateEditor.resetDetail"
|
||||
>
|
||||
templateEditor.reset
|
||||
</button>
|
||||
<button
|
||||
class="tool-button"
|
||||
id="help"
|
||||
locale-target="innerHTML,title"
|
||||
title="templateEditor.helpDetail"
|
||||
>
|
||||
templateEditor.help
|
||||
<menupopup>
|
||||
<menuitem id="import" data-l10n-id="import"></menuitem>
|
||||
<menuseparator />
|
||||
<menuitem id="share" data-l10n-id="share"></menuitem>
|
||||
<menuseparator />
|
||||
<menuitem id="backup" data-l10n-id="backup"></menuitem>
|
||||
<menuitem id="restore" data-l10n-id="restore"></menuitem>
|
||||
<menuseparator />
|
||||
<menuitem id="help" data-l10n-id="help"></menuitem>
|
||||
</menupopup>
|
||||
</button>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -28,16 +28,7 @@ menuAddReaderNote-newTemplateNote = New Item Note from Template
|
|||
|
||||
menuEditor-resizeImage = Resize Image
|
||||
|
||||
templateEditor-title = Template Editor
|
||||
templateEditor-templateName = Template Name
|
||||
templateEditor-previewContainer = Preview
|
||||
templateEditor-create = New
|
||||
templateEditor-import = Import Note
|
||||
templateEditor-more = More Templates
|
||||
templateEditor-save = Save
|
||||
templateEditor-delete = Delete
|
||||
templateEditor-reset = Reset
|
||||
templateEditor-help = Help
|
||||
|
||||
tab-name = Note Workspace
|
||||
tab-openInWindow = Drag and drop here to open workspace in new window
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
title = Template Editor
|
||||
previewContainer =
|
||||
.label = Preview
|
||||
create =
|
||||
.label = New
|
||||
save =
|
||||
.label = Save
|
||||
delete =
|
||||
.label = Delete
|
||||
reset =
|
||||
.label = Reset
|
||||
more =
|
||||
.label = More Templates
|
||||
.title = Get more templates online
|
||||
|
||||
options =
|
||||
.label = Options
|
||||
import =
|
||||
.label = Import note as template
|
||||
share =
|
||||
.label = Copy share code
|
||||
backup =
|
||||
.label = Export backup file
|
||||
restore =
|
||||
.label = Restore from backup file
|
||||
help =
|
||||
.label = Help
|
||||
|
|
@ -28,16 +28,7 @@ menuAddReaderNote-newTemplateNote=Новая элементная заметка
|
|||
|
||||
menuEditor-resizeImage=Изменить размер изображения
|
||||
|
||||
templateEditor-title=Редактор шаблонов
|
||||
templateEditor-templateName=Имя шаблона
|
||||
templateEditor-previewContainer=Предпросмотр
|
||||
templateEditor-create=Новая
|
||||
templateEditor-import=Импортировать заметку
|
||||
templateEditor-more=Больше шаблонов
|
||||
templateEditor-save=Сохранить
|
||||
templateEditor-delete=Удалить
|
||||
templateEditor-reset=Сброс
|
||||
templateEditor-help=Помощь
|
||||
templateEditor-templateName = Имя шаблона
|
||||
|
||||
tab-name=Рабочее пространство заметок
|
||||
tab-openInWindow=Перетащите сюда для открытия раб. пространства в новом окне
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
title = Редактор шаблонов
|
||||
previewContainer =
|
||||
.label = Предпросмотр
|
||||
create =
|
||||
.label = Новая
|
||||
save =
|
||||
.label = Сохранить
|
||||
delete =
|
||||
.label = Удалить
|
||||
reset =
|
||||
.label = Сброс
|
||||
more =
|
||||
.label = Больше шаблонов
|
||||
.title = Get more templates online
|
||||
|
||||
options =
|
||||
.label = Options
|
||||
import =
|
||||
.label = Import note as template
|
||||
share =
|
||||
.label = Copy share code
|
||||
backup =
|
||||
.label = Export backup file
|
||||
restore =
|
||||
.label = Restore from backup file
|
||||
help =
|
||||
.label = Помощь
|
||||
|
|
@ -28,16 +28,7 @@ menuAddReaderNote-newTemplateNote=从模板新建条目子笔记
|
|||
|
||||
menuEditor-resizeImage=缩放图片
|
||||
|
||||
templateEditor-title=模板编辑器
|
||||
templateEditor-templateName=模板名称
|
||||
templateEditor-previewContainer=预览
|
||||
templateEditor-create=新建
|
||||
templateEditor-import=导入笔记
|
||||
templateEditor-more=更多模板
|
||||
templateEditor-save=保存
|
||||
templateEditor-delete=删除
|
||||
templateEditor-reset=重置
|
||||
templateEditor-help=帮助
|
||||
templateEditor-templateName = 模板名称
|
||||
|
||||
tab-name=笔记工作区
|
||||
tab-openInWindow=拖放到此处以在新窗口打开
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
title = 模板编辑器
|
||||
previewContainer =
|
||||
.label = 预览
|
||||
create =
|
||||
.label = 新建
|
||||
save =
|
||||
.label = 保存
|
||||
delete =
|
||||
.label = 删除
|
||||
reset =
|
||||
.label = 重置
|
||||
more =
|
||||
.label = 更多模板
|
||||
|
||||
options =
|
||||
.label = 选项
|
||||
import =
|
||||
.label = 导入笔记
|
||||
share =
|
||||
.label = 复制分享代码
|
||||
backup =
|
||||
.label = 导出模板备份文件
|
||||
restore =
|
||||
.label = 从备份文件恢复
|
||||
help =
|
||||
.label = 帮助
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import YAML = require("yamljs");
|
||||
import { config } from "../../../package.json";
|
||||
import { showHint } from "../../utils/hint";
|
||||
import { itemPicker } from "../../utils/itemPicker";
|
||||
import { getString } from "../../utils/locale";
|
||||
import { localeWindow } from "../../utils/window";
|
||||
|
||||
export async function showTemplateEditor() {
|
||||
if (
|
||||
|
|
@ -17,12 +17,11 @@ export async function showTemplateEditor() {
|
|||
const _window = window.openDialog(
|
||||
`chrome://${config.addonRef}/content/templateEditor.xhtml`,
|
||||
`${config.addonRef}-templateEditor`,
|
||||
`chrome,centerscreen,resizable,status,width=800,height=400,dialog=no`,
|
||||
`chrome,centerscreen,resizable,status,width=600,height=400,dialog=no`,
|
||||
windowArgs
|
||||
)!;
|
||||
addon.data.templateEditor.window = _window;
|
||||
await windowArgs._initPromise.promise;
|
||||
localeWindow(_window);
|
||||
updateData();
|
||||
addon.data.templateEditor.tableHelper = new ztoolkit.VirtualizedTable(
|
||||
_window!
|
||||
|
|
@ -35,7 +34,7 @@ export async function showTemplateEditor() {
|
|||
columns: [
|
||||
{
|
||||
dataKey: "name",
|
||||
label: "templateEditor.templateName",
|
||||
label: "templateEditor-templateName",
|
||||
fixedWidth: false,
|
||||
},
|
||||
].map((column) =>
|
||||
|
|
@ -109,6 +108,21 @@ export async function showTemplateEditor() {
|
|||
?.addEventListener("click", (ev) => {
|
||||
resetSelectedTemplate();
|
||||
});
|
||||
_window.document
|
||||
.querySelector("#share")
|
||||
?.addEventListener("click", (ev) => {
|
||||
shareSelectedTemplate();
|
||||
});
|
||||
_window.document
|
||||
.querySelector("#backup")
|
||||
?.addEventListener("click", (ev) => {
|
||||
backupTemplates();
|
||||
});
|
||||
_window.document
|
||||
.querySelector("#restore")
|
||||
?.addEventListener("click", (ev) => {
|
||||
restoreTemplates(_window);
|
||||
});
|
||||
}
|
||||
addon.data.templateEditor.window?.focus();
|
||||
}
|
||||
|
|
@ -290,3 +304,79 @@ function resetSelectedTemplate() {
|
|||
showHint(`Template ${name} is reset. Please save before leaving.`);
|
||||
}
|
||||
}
|
||||
|
||||
function shareSelectedTemplate() {
|
||||
const name = getSelectedTemplateName();
|
||||
if (!name) {
|
||||
return;
|
||||
}
|
||||
saveSelectedTemplate();
|
||||
const content = addon.api.template.getTemplateText(name);
|
||||
const yaml = `# This template is specifically for importing/sharing, using better
|
||||
# notes 'import from clipboard': copy the content and
|
||||
# goto Zotero menu bar, click Edit->New Template from Clipboard.
|
||||
# Do not copy-paste this to better notes template editor directly.
|
||||
name: "${name}"
|
||||
content: |-
|
||||
${content
|
||||
.split("\n")
|
||||
.map((line) => ` ${line}`)
|
||||
.join("\n")}
|
||||
`;
|
||||
new ztoolkit.Clipboard().addText(yaml, "text/unicode").copy();
|
||||
showHint(
|
||||
`Template ${name} is copied to clipboard. To import it, goto Zotero menu bar, click Edit->New Template from Clipboard. `
|
||||
);
|
||||
}
|
||||
|
||||
async function backupTemplates() {
|
||||
const time = new Date().toISOString().replace(/:/g, "-");
|
||||
const filepath = await new ztoolkit.FilePicker(
|
||||
"Save backup file",
|
||||
"save",
|
||||
[["yaml", "*.yaml"]],
|
||||
`bn-template-backup-${time}.yaml`
|
||||
).open();
|
||||
if (!filepath) {
|
||||
return;
|
||||
}
|
||||
const keys = addon.api.template.getTemplateKeys().map((t) => t.name);
|
||||
const templates = keys.map((key) => {
|
||||
return {
|
||||
name: key,
|
||||
text: addon.api.template.getTemplateText(key),
|
||||
};
|
||||
});
|
||||
const yaml = YAML.stringify(templates);
|
||||
await Zotero.File.putContentsAsync(filepath, yaml);
|
||||
}
|
||||
|
||||
async function restoreTemplates(win: Window) {
|
||||
const filepath = await new ztoolkit.FilePicker(
|
||||
"Open backup file",
|
||||
"open",
|
||||
[["yaml", "*.yaml"]],
|
||||
undefined,
|
||||
win,
|
||||
"text"
|
||||
).open();
|
||||
if (!filepath) {
|
||||
return;
|
||||
}
|
||||
const yaml = (await Zotero.File.getContentsAsync(filepath)) as string;
|
||||
const templates = YAML.parse(yaml) as NoteTemplate[];
|
||||
const existingNames = addon.api.template.getTemplateKeys().map((t) => t.name);
|
||||
|
||||
for (const t of templates) {
|
||||
if (existingNames.includes(t.name)) {
|
||||
const overwrite = win.confirm(
|
||||
`Template ${t.name} already exists. Overwrite?`
|
||||
);
|
||||
if (!overwrite) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
addon.api.template.setTemplate(t);
|
||||
}
|
||||
await refresh();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue