update: rework export window

This commit is contained in:
windingwind 2024-11-09 20:48:14 +01:00
parent fccdd28677
commit 7859df48c0
31 changed files with 568 additions and 336 deletions

View File

@ -0,0 +1,102 @@
<?xml version="1.0"?>
<!-- prettier-ignore -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!-- prettier-ignore -->
<?xml-stylesheet href="chrome://zotero/skin/zotero.css" type="text/css"?>
<!-- prettier-ignore -->
<?xml-stylesheet href="chrome://zotero-platform/content/zotero.css" type="text/css"?>
<!-- prettier-ignore -->
<?xml-stylesheet href="chrome://__addonRef__/content/styles/exportNotes.css" type="text/css"?>
<!-- prettier-ignore -->
<!DOCTYPE window>
<window
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
id="bn-export-notes"
data-l10n-id="title"
windowtype="__addonRef__-export-notes"
persist="screenX screenY width height sizemode"
style="min-width: 10em"
drawintitlebar-platforms="mac"
>
<xul:linkset>
<html:link rel="localization" href="browser/menubar.ftl" />
<html:link rel="localization" href="browser/browserSets.ftl" />
<html:link rel="localization" href="toolkit/global/textActions.ftl" />
<html:link rel="localization" href="zotero.ftl" />
<html:link rel="localization" href="__addonRef__-exportNotes.ftl" />
</xul:linkset>
<xul:commandset id="mainCommandSet">
<xul:command id="cmd_close" oncommand="window.close();" />
</xul:commandset>
<xul:keyset id="mainKeyset">
<xul:key
id="key_close"
data-l10n-id="close-shortcut"
command="cmd_close"
modifiers="accel"
reserved="true"
/>
</xul:keyset>
<script src="chrome://zotero/content/include.js"></script>
<script src="chrome://zotero/content/titlebar.js"></script>
<script src="chrome://zotero/content/customElements.js"></script>
<script src="chrome://__addonRef__/content/scripts/exportNotes.js"></script>
<dialog
buttons="accept, cancel, extra1"
buttonlabelextra1="Use System Export..."
>
<vbox>
<hbox>
<label id="target" data-l10n-id="target"></label>
</hbox>
<hbox align="center">
<label data-l10n-id="format" for="format"></label>
<menulist id="format" native="true">
<menupopup>
<menuitem
value="markdown"
data-l10n-id="format-markdown"
></menuitem>
<menuitem value="msword" data-l10n-id="format-msword"></menuitem>
<menuitem value="pdf" data-l10n-id="format-pdf"></menuitem>
<menuitem
value="freemind"
data-l10n-id="format-freemind"
></menuitem>
<menuitem value="note" data-l10n-id="format-note"></menuitem>
</menupopup>
</menulist>
</hbox>
<vbox>
<radiogroup id="linkMode" orient="vertical">
<radio value="keep" data-l10n-id="links-keep"></radio>
<radio value="embed" data-l10n-id="links-embed"></radio>
<radio value="standalone" data-l10n-id="links-standalone"></radio>
<!-- <radio value="remove" data-l10n-id="links-remove"></radio> -->
</radiogroup>
</vbox>
<vbox id="markdown-options">
<checkbox
id="markdown-autoSync"
data-l10n-id="markdown-autoSync"
native="true"
></checkbox>
<checkbox
id="markdown-withYAMLHeader"
data-l10n-id="markdown-withYAMLHeader"
native="true"
></checkbox>
<checkbox
id="markdown-autoFilename"
data-l10n-id="markdown-autoFilename"
native="true"
></checkbox>
</vbox>
</vbox>
</dialog>
</window>

View File

@ -16,6 +16,11 @@
native="true"
preference="__prefsPrefix__.openNote.defaultAsWindow"
/>
<checkbox
data-l10n-id="basic-exportNotes-takeover"
native="true"
preference="__prefsPrefix__.exportNotes.takeover"
/>
</groupbox>
<groupbox>
<label><html:h2 data-l10n-id="editor-title"></html:h2></label>

View File

@ -0,0 +1,8 @@
dialog {
-moz-window-dragging: drag;
}
#markdown-autoSync {
margin-inline-start: 18px;
margin-block-end: 24px;
}

View File

@ -1,7 +1,5 @@
pref-title = Better Notes
menuItem-exportNote = Export Note
menuEdit-exportTemplate = Export Template to File...
menuEdit-templateEditor = Template Editor
menuEdit-importTemplate = New Template from Clipboard

View File

@ -1,25 +0,0 @@
title = Export Notes
options-linkMode = Linked Notes Mode
options-MD = MarkDown(.md)
options-Docx = MS Word(.docx)
options-PDF = PDF(.pdf)
options-mm = Mind Map
options-note = Zotero Note
embedLink = All Embedded in One Export
standaloneLink = Each Converted to Standalone Exports
keepLink = Keep Zotero Links(zotero://note/)
exportMD = Export MD File(s)
setAutoSync = Set Auto-Sync
.title = Auto-Sync is available for "Each Converted to Standalone Exports" mode.
withYAMLHeader = With YAML Header
autoMDFileName = Auto Generate MD File Name
exportDocx = Export Docx File
exportPDF = Export PDF File
exportFreeMind = Export FreeMind File
exportNote = Export to New Zotero Note Item
confirm = Export
cancel = Close
target = Target: {$title}{ $left ->
[0]{ "" }
*[other] { " " }and {$left} more.
}

View File

@ -0,0 +1,37 @@
title =
.title = Export Notes with Better Notes
target =
.value = Target: {$title}{ $left ->
[0]{ "" }
*[other] { " " }and {$left} more.
}
format =
.value = Format:
format-markdown =
.label = MarkDown(.md)
format-msword =
.label = MS Word(.docx)
format-pdf =
.label = PDF(.pdf)
format-freemind =
.label = Mind Map
format-note =
.label = Zotero Note
links-keep =
.label = Keep note links(zotero://note/)
links-embed =
.label = Embed linked notes in the content
links-standalone =
.label = Convert linked notes to standalone exports
links-remove =
.label = Remove note links
markdown-autoSync =
.label = Set auto-sync for each note
.title = Auto-sync is available for "Convert linked notes to standalone exports" mode.
markdown-withYAMLHeader =
.label = With YAML header
markdown-autoFilename =
.label = Auto generate file name

View File

@ -3,6 +3,8 @@ basic-openNote-takeover =
.label = Take over opening note
basic-openNote-defaultAsWindow =
.label = Open note as window by default
basic-exportNotes-takeover =
.label = Take over exporting notes
editor-title = Note Editor
editor-expandLevel-label = Outline expand to heading level

View File

@ -1,7 +1,5 @@
pref-title = Better Notes
menuItem-exportNote = Esporta nota
menuEdit-exportTemplate = Esporta il template su file...
menuEdit-templateEditor = Editor dei template
menuEdit-importTemplate = Nuovo template dagli appunti

View File

@ -1,25 +0,0 @@
title = Esporta note
options-linkMode = Modalità note collegate
options-MD = MarkDown(.md)
options-Docx = MS Word(.docx)
options-PDF = PDF(.pdf)
options-mm = Mappa mentale
options-note = Nota Zotero
embedLink = Tutte incorporate in un'unica esportazione
standaloneLink = Ciascuna convertita in esportazioni indipendenti
keepLink = Mantieni i link Zotero (zotero://note/)
exportMD = Esporta file MD
setAutoSync = Imposta sincronizzazione automatica
.title = La sincronizzazione automatica è disponibile per la modalità "Ciascuna convertita in esportazioni indipendenti".
withYAMLHeader = Con header YAML
autoMDFileName = Genera automaticamente il nome del file MD
exportDocx = Esporta file Docx
exportPDF = Esporta file PDF
exportFreeMind = Esporta file FreeMind
exportNote = Esporta in una nuova nota dell'elemento Zotero
confirm = Esporta
cancel = Chiudi
target = Oggetto: {$title}{ $left ->
[0]{ "" }
*[other] { " " }e {$left} altri
}

View File

@ -0,0 +1,37 @@
title =
.title = Esporta Note con Better Notes
target =
.value = Destinazione: {$title}{ $left ->
[0]{ "" }
*[other] { " " }e {$left} in più.
}
format =
.value = Formato:
format-markdown =
.label = MarkDown(.md)
format-msword =
.label = MS Word(.docx)
format-pdf =
.label = PDF(.pdf)
format-freemind =
.label = Mappa Mentale
format-note =
.label = Nota Zotero
links-keep =
.label = Mantieni collegamenti alle note(zotero://note/)
links-embed =
.label = Incorpora note collegate nel contenuto
links-standalone =
.label = Converti note collegate in esportazioni autonome
links-remove =
.label = Rimuovi collegamenti alle note
markdown-autoSync =
.label = Imposta sincronizzazione automatica per ogni nota
.title = La sincronizzazione automatica è disponibile per la modalità "Converti note collegate in esportazioni autonome".
markdown-withYAMLHeader =
.label = Con intestazione YAML
markdown-autoFilename =
.label = Genera automaticamente il nome del file

View File

@ -3,6 +3,8 @@ basic-openNote-takeover =
.label = Gestisci l'apertura delle note
basic-openNote-defaultAsWindow =
.label = Apri note come finestra per impostazione predefinita
basic-exportNotes-takeover =
.label = Take over exporting notes
editor-title = Editor delle note
editor-expandLevel-label = Espansione dello schema al livello delle intestazioni

View File

@ -1,7 +1,5 @@
pref-title=Better Notes
menuItem-exportNote=Экспорт заметки
menuEdit-exportTemplate=Экспорт шаблона в файл...
menuEdit-templateEditor=Редактор шаблонов
menuEdit-importTemplate=Новый шаблон из буфера обмена

View File

@ -0,0 +1,37 @@
title =
.title = Экспорт заметок с Better Notes
target =
.value = Цель: {$title}{ $left ->
[0]{ "" }
*[other] { " " }и еще {$left}.
}
format =
.value = Формат:
format-markdown =
.label = MarkDown(.md)
format-msword =
.label = MS Word(.docx)
format-pdf =
.label = PDF(.pdf)
format-freemind =
.label = Карта разума
format-note =
.label = Заметка Zotero
links-keep =
.label = Сохранить ссылки на заметки(zotero://note/)
links-embed =
.label = Встроить связанные заметки в содержимое
links-standalone =
.label = Преобразовать связанные заметки в автономные экспорты
links-remove =
.label = Удалить ссылки на заметки
markdown-autoSync =
.label = Установить авто-синхронизацию для каждой заметки
.title = Авто-синхронизация доступна в режиме "Преобразовать связанные заметки в автономные экспорты".
markdown-withYAMLHeader =
.label = С YAML заголовком
markdown-autoFilename =
.label = Автоматически генерировать имя файла

View File

@ -3,6 +3,8 @@ basic-openNote-takeover =
.label = Take over opening note
basic-openNote-defaultAsWindow =
.label = Open note as window by default
basic-exportNotes-takeover =
.label = Take over exporting notes
editor-title = Note Editor
editor-expandLevel-label = Outline расширить до уровня заголовка

View File

@ -1,7 +1,5 @@
pref-title = Better Notes
menuItem-exportNote = Notu Dışa Aktar
menuEdit-exportTemplate = Şablonu Dosya Olarak Dışa Aktar...
menuEdit-templateEditor = Şablon Düzenleyici
menuEdit-importTemplate = Panodan Yeni Şablon Al

View File

@ -1,25 +0,0 @@
title = Notları Dışa Aktar
options-linkMode = Bağlantılı Notlar Modu
options-MD = MarkDown(.md)
options-Docx = MS Word(.docx)
options-PDF = PDF(.pdf)
options-mm = Zihin Haritası
options-note = Zotero Notu
embedLink = Hepsi Tek Bir Dışarı Aktarma İçerisinde
standaloneLink = Her Biri Bağımsız Olarak Dışa Aktarıldı
keepLink = Zotero Linkleri Kalsın (zotero://note/)
exportMD = MD Dosya(lar)sını Dışa Aktar
setAutoSync = Otomatik Eşitlemeye Ayarla
.title = Otomatik Eşitleme "Her Birini Bağımsız Dışa Aktar" seçeneği için kullanılabilir.
withYAMLHeader = YAML Başlığı İle
autoMDFileName = MD Dosya Adını Otomatik Oluştur
exportDocx = Docx Dosyası Olarak Dışa Aktar
exportPDF = PDF Dosyası Olarak Dışa Aktar
exportFreeMind = FreeMind Dosyası Olarak Dışa Aktar
exportNote = Yeni Zotero Notuna Aktar
confirm = Dışa Aktar
cancel = Kapat
target = Hedef: {$title}{ $left ->
[0]{ "" }
*[other] { " " }and {$left} more
}

View File

@ -0,0 +1,37 @@
title =
.title = Notları Better Notes ile Dışa Aktar
target =
.value = Hedef: {$title}{ $left ->
[0]{ "" }
*[other] { " " }ve {$left} daha.
}
format =
.value = Biçim:
format-markdown =
.label = MarkDown(.md)
format-msword =
.label = MS Word(.docx)
format-pdf =
.label = PDF(.pdf)
format-freemind =
.label = Zihin Haritası
format-note =
.label = Zotero Notu
links-keep =
.label = Not bağlantılarını koru(zotero://note/)
links-embed =
.label = Bağlantılı notları içeriğe göm
links-standalone =
.label = Bağlantılı notları bağımsız dışa aktarımlara dönüştür
links-remove =
.label = Not bağlantılarını kaldır
markdown-autoSync =
.label = Her not için otomatik senkronizasyon ayarla
.title = Otomatik senkronizasyon "Bağlantılı notları bağımsız dışa aktarımlara dönüştür" modu için kullanılabilir.
markdown-withYAMLHeader =
.label = YAML başlığı ile
markdown-autoFilename =
.label = Dosya adını otomatik oluştur

View File

@ -3,6 +3,8 @@ basic-openNote-takeover =
.label = Notları açmayı devral
basic-openNote-defaultAsWindow =
.label = Notları her zaman pencere olarak aç
basic-exportNotes-takeover =
.label = Take over exporting notes
editor-title = Not Düzenleyici
editor-expandLevel-label = Anahatta gösterilecek başlık düzeyleri

View File

@ -1,7 +1,5 @@
pref-title=Better Notes
menuItem-exportNote=导出笔记
menuEdit-exportTemplate=运行模板并导出为文件...
menuEdit-templateEditor=模板编辑器
menuEdit-importTemplate=从剪贴板导入笔记模板

View File

@ -1,25 +0,0 @@
title=导出笔记
options-linkMode=链接笔记模式
options-MD=MarkDown(.md)
options-Docx=MS Word(.docx)
options-PDF=PDF(.pdf)
options-mm=思维导图
options-note=Zotero笔记
embedLink=全部嵌入为一个导出
standaloneLink=分别单独导出
keepLink=保留Zotero链接(zotero://note/)
exportMD=导出MD文件
setAutoSync=设置自动同步
.title=自动同步仅能在"分别单独导出模式"使用
withYAMLHeader=带有YAML头
autoMDFileName=自动生成MD文件名
exportDocx=导出Word文件
exportPDF=导出PDF文件
exportFreeMind=导出FreeMind文件
exportNote=导出为Zotero笔记条目
confirm=导出
cancel=关闭
target=目标: {$title}{ $left ->
[0]{ "" }
*[other] { " " }和其他{$left}个
}

View File

@ -0,0 +1,37 @@
title =
.title = 使用 Better Notes 导出笔记
target =
.value = 目标: {$title}{ $left ->
[0]{ "" }
*[other] { " " } 以及其他 {$left} 个。
}
format =
.value = 格式:
format-markdown =
.label = MarkDown(.md)
format-msword =
.label = MS Word(.docx)
format-pdf =
.label = PDF(.pdf)
format-freemind =
.label = 思维导图
format-note =
.label = Zotero 笔记
links-keep =
.label = 保留笔记链接(zotero://note/)
links-embed =
.label = 嵌入链接的笔记内容
links-standalone =
.label = 将链接的笔记分别导出
links-remove =
.label = 移除笔记链接
markdown-autoSync =
.label = 为每个笔记设置自动同步
.title = 自动同步适用于“将链接的笔记分别导出”模式。
markdown-withYAMLHeader =
.label = 包含 YAML 头
markdown-autoFilename =
.label = 自动生成文件名

View File

@ -3,6 +3,8 @@ basic-openNote-takeover =
.label = 接管打开笔记
basic-openNote-defaultAsWindow =
.label = 默认在窗口打开笔记
basic-exportNotes-takeover =
.label = 接管导出笔记
editor-title = 笔记编辑器
editor-expandLevel-label = 大纲展开至标题层级

View File

@ -25,5 +25,6 @@ pref("__prefsPrefix__.editor.noteLinkPreviewType", "hover");
pref("__prefsPrefix__.openNote.takeover", true);
pref("__prefsPrefix__.openNote.defaultAsWindow", false);
pref("__prefsPrefix__.exportNotes.takeover", true);
pref("__prefsPrefix__.annotationNote.enableTagSync", true);

185
src/extras/exportNotes.ts Normal file
View File

@ -0,0 +1,185 @@
import { getPref, setPref } from "../utils/prefs";
let io: {
targetData: {
left: number;
title: string;
};
accepted: boolean;
useBuiltInExport: boolean;
deferred: _ZoteroTypes.DeferredPromise<void>;
embedLink: boolean;
standaloneLink: boolean;
exportNote: boolean;
exportMD: boolean;
setAutoSync: boolean;
autoMDFileName: boolean;
withYAMLHeader: boolean;
exportDocx: boolean;
exportPDF: boolean;
exportFreeMind: boolean;
};
window.onload = async function () {
if (document.readyState === "complete") {
setTimeout(init, 0);
return;
}
document.addEventListener("DOMContentLoaded", init, { once: true });
};
window.onunload = function () {
io.deferred && io.deferred.resolve();
};
function init() {
const dialog = document.querySelector("dialog")!;
Zotero.UIProperties.registerRoot(dialog);
io = window.arguments[0];
window.addEventListener("dialogaccept", doAccept);
window.addEventListener("dialogextra1", () => doUseBuiltInExport());
document
.querySelector("#format")!
.addEventListener("command", onFormatChange);
document
.querySelector("#linkMode")!
.addEventListener("command", updateMarkdownOptions);
document
.querySelector("#markdown-autoSync")!
.addEventListener("command", updateMarkdownOptions);
(document.querySelector("#target") as XULElement).dataset.l10nArgs =
JSON.stringify(io.targetData);
restore();
onFormatChange();
updateMarkdownOptions();
}
function restore() {
let format = getPref("export.format") as string;
if (!["markdown", "msword", "pdf", "freemind", "note"].includes(format)) {
format = "markdown";
}
(document.querySelector("#format") as XULMenuListElement).value = format;
let linkMode = getPref("export.linkMode") as string;
if (!["keep", "embed", "standalone", "remove"].includes(linkMode)) {
linkMode = "keep";
}
(document.querySelector("#linkMode") as XULRadioGroupElement).value =
linkMode;
const markdownPrefs = ["autoSync", "withYAMLHeader", "autoFilename"];
for (const pref of markdownPrefs) {
(
document.querySelector(`#markdown-${pref}`) as XULCheckboxElement
).checked = getPref(`export.markdown-${pref}`) as boolean;
}
}
function cache() {
setPref(
"export.format",
(document.querySelector("#format") as XULMenuListElement).value,
);
setPref(
"export.linkMode",
(document.querySelector("#linkMode") as XULRadioGroupElement).value,
);
const markdownPrefs = ["autoSync", "withYAMLHeader", "autoFilename"];
for (const pref of markdownPrefs) {
setPref(
`export.markdown-${pref}`,
(document.querySelector(`#markdown-${pref}`) as XULCheckboxElement)
.checked,
);
}
}
function onFormatChange() {
const format = (document.querySelector("#format") as XULMenuListElement)
.value;
const isMD = format === "markdown";
(document.querySelector("#markdown-options") as XULBoxElement).hidden = !isMD;
window.sizeToContent();
}
function updateMarkdownOptions() {
const linkModeRadio = document.querySelector(
"#linkMode",
) as XULRadioGroupElement;
const autoSyncRadio = document.querySelector(
"#markdown-autoSync",
) as XULCheckboxElement;
if (linkModeRadio.value !== "standalone") {
autoSyncRadio.checked = false;
autoSyncRadio.disabled = true;
} else {
autoSyncRadio.disabled = false;
}
const autoFilename = document.querySelector(
"#markdown-autoFilename",
) as XULCheckboxElement;
const withYAMLHeader = document.querySelector(
"#markdown-withYAMLHeader",
) as XULCheckboxElement;
if (autoSyncRadio.checked) {
autoFilename.checked = true;
autoFilename.disabled = true;
withYAMLHeader.checked = true;
withYAMLHeader.disabled = true;
} else {
autoFilename.disabled = false;
withYAMLHeader.disabled = false;
}
}
function doAccept() {
cache();
// Format
const format = (document.querySelector("#format") as XULMenuListElement)
.value;
io.exportMD = format === "markdown";
io.exportDocx = format === "msword";
io.exportPDF = format === "pdf";
io.exportFreeMind = format === "freemind";
io.exportNote = format === "note";
// Markdown options
io.autoMDFileName = (
document.querySelector("#markdown-autoFilename") as XULCheckboxElement
).checked;
io.withYAMLHeader = (
document.querySelector("#markdown-withYAMLHeader") as XULCheckboxElement
).checked;
io.setAutoSync = (
document.querySelector("#markdown-autoSync") as XULCheckboxElement
).checked;
// Link mode
const linkMode = (document.querySelector("#linkMode") as XULRadioGroupElement)
.value;
io.embedLink = linkMode === "embed";
io.standaloneLink = linkMode === "standalone";
io.accepted = true;
}
function doUseBuiltInExport() {
io.useBuiltInExport = true;
window.close();
}

View File

@ -47,6 +47,7 @@ import { registerNoteLinkSection } from "./modules/workspace/link";
import { showUserGuide } from "./modules/userGuide";
import { refreshTemplatesInNote } from "./modules/template/refresh";
import { closeParsingServer } from "./utils/parsing";
import { patchExportItems } from "./modules/exportItems";
async function onStartup() {
await Promise.all([
@ -81,7 +82,7 @@ async function onStartup() {
await onMainWindowLoad(Zotero.getMainWindow());
}
async function onMainWindowLoad(win: Window): Promise<void> {
async function onMainWindowLoad(win: _ZoteroTypes.MainWindow): Promise<void> {
await waitUtilAsync(() => win.document.readyState === "complete");
Services.scriptloader.loadSubScript(
@ -99,6 +100,8 @@ async function onMainWindowLoad(win: Window): Promise<void> {
patchViewItems(win);
patchExportItems(win);
restoreNoteTabs();
showUserGuide(win);

View File

@ -1,20 +1,6 @@
import { config } from "../../../package.json";
import { getPref, setPref } from "../../utils/prefs";
import { fill, slice } from "../../utils/str";
enum OPTIONS {
"embedLink",
"standaloneLink",
"keepLink",
"exportMD",
"setAutoSync",
"withYAMLHeader",
"exportDocx",
"exportPDF",
"exportFreeMind",
"exportNote",
}
export async function showExportNoteOptions(
noteIds: number[],
overwriteOptions: Record<string, any> = {},
@ -32,204 +18,37 @@ export async function showExportNoteOptions(
if (noteItems.length === 0) {
return;
}
const dataKeys = Object.keys(OPTIONS).filter(
(value) => typeof value === "string",
);
const data = dataKeys.reduce(
(acc, key) => {
acc[key] = getPref(`export.${key}`) as boolean;
return acc;
},
{} as Record<string, any>,
);
data.loadCallback = () => {
const doc = dialog.window.document;
const standaloneLinkRadio = doc.querySelector(
"#standaloneLink",
) as HTMLInputElement;
const autoSyncRadio = doc.querySelector("#setAutoSync") as HTMLInputElement;
function updateSyncCheckbox() {
const standaloneLinkEnabled = standaloneLinkRadio.checked;
if (!standaloneLinkEnabled) {
autoSyncRadio.checked = false;
autoSyncRadio.disabled = true;
} else {
autoSyncRadio.disabled = false;
}
}
Array.from(doc.querySelectorAll('input[name="linkMode"]')).forEach((elem) =>
(elem as HTMLInputElement).addEventListener("change", updateSyncCheckbox),
);
updateSyncCheckbox();
const io = {
targetData: {
left: noteItems.length - 1,
title: fill(slice(noteItems[0].getNoteTitle(), 40), 40),
},
deferred: Zotero.Promise.defer(),
accepted: false,
useBuiltInExport: false,
};
data.l10nFiles = `${config.addonRef}-export.ftl`;
Zotero.getMainWindow().openDialog(
`chrome://${config.addonRef}/content/exportNotes.xhtml`,
`${config.addonRef}-exportNotes`,
"chrome,centerscreen,resizable",
io,
);
const dialog = new ztoolkit.Dialog(18, 1)
.setDialogData(data)
.addCell(0, 0, {
tag: "div",
styles: {
display: "grid",
gridTemplateColumns: "1fr 20px",
rowGap: "10px",
columnGap: "5px",
},
children: [
{
tag: "label",
attributes: {
"data-l10n-id": `${config.addonRef}-target`,
"data-l10n-args": JSON.stringify({
left: noteItems.length - 1,
title: fill(slice(noteItems[0].getNoteTitle(), 40), 40),
}),
},
},
],
})
.addCell(1, 0, makeHeadingLine("options-linkMode"))
.addCell(2, 0, makeRadioLine("embedLink", "linkMode"))
.addCell(3, 0, makeRadioLine("standaloneLink", "linkMode"))
.addCell(4, 0, makeRadioLine("keepLink", "linkMode"))
.addCell(5, 0, makeHeadingLine("options-MD"))
.addCell(6, 0, makeCheckboxLine("exportMD"))
.addCell(7, 0, makeCheckboxLine("setAutoSync"))
.addCell(8, 0, makeCheckboxLine("withYAMLHeader"))
.addCell(9, 0, makeCheckboxLine("autoMDFileName"))
.addCell(10, 0, makeHeadingLine("options-Docx"))
.addCell(11, 0, makeCheckboxLine("exportDocx"))
.addCell(12, 0, makeHeadingLine("options-PDF"))
.addCell(13, 0, makeCheckboxLine("exportPDF"))
.addCell(14, 0, makeHeadingLine("options-mm"))
.addCell(15, 0, makeCheckboxLine("exportFreeMind"))
.addCell(16, 0, makeHeadingLine("options-note"))
.addCell(17, 0, makeCheckboxLine("exportNote"))
.addButton(`${config.addonRef}-confirm`, "confirm")
.addButton(`${config.addonRef}-cancel`, "cancel")
.open(`${config.addonRef}-title`, {
resizable: true,
centerscreen: true,
width: 350,
height: 600,
noDialogMode: true,
});
await io.deferred.promise;
await data.unloadLock?.promise;
if (data._lastButtonId === "confirm") {
if (io.accepted) {
await addon.api.$export.exportNotes(
noteItems,
Object.assign(data as Record<string, boolean>, overwriteOptions),
Object.assign(io as any, overwriteOptions),
);
dataKeys.forEach((key) => {
setPref(`export.${key}`, Boolean(data[key]));
});
}
if (io.useBuiltInExport) {
const exporter = new (Zotero.getMainWindow().Zotero_File_Exporter)();
exporter.items = Zotero.Items.get(noteIds);
if (!exporter.items || !exporter.items.length)
throw "no items currently selected";
exporter.save();
}
}
function makeHeadingLine(l10nID: string) {
return {
tag: "div",
styles: {
display: "grid",
gridTemplateColumns: "1fr 20px",
rowGap: "10px",
columnGap: "5px",
},
children: [
{
tag: "h3",
attributes: {
"data-l10n-id": `${config.addonRef}-${l10nID}`,
},
},
],
};
}
function makeCheckboxLine(dataKey: string, callback?: (ev: Event) => void) {
return {
tag: "div",
styles: {
display: "grid",
gridTemplateColumns: "1fr 20px",
rowGap: "10px",
columnGap: "5px",
},
children: [
{
tag: "label",
attributes: {
for: dataKey,
"data-l10n-id": `${config.addonRef}-${dataKey}`,
},
},
{
tag: "input",
id: dataKey,
attributes: {
"data-bind": dataKey,
"data-prop": "checked",
},
properties: {
type: "checkbox",
},
listeners: callback
? [
{
type: "change",
listener: callback,
},
]
: [],
},
],
};
}
function makeRadioLine(
dataKey: string,
radioName: string,
callback?: (ev: Event) => void,
) {
return {
tag: "div",
styles: {
display: "grid",
gridTemplateColumns: "1fr 20px",
rowGap: "10px",
columnGap: "5px",
},
children: [
{
tag: "label",
attributes: {
for: dataKey,
"data-l10n-id": `${config.addonRef}-${dataKey}`,
},
},
{
tag: "input",
id: dataKey,
attributes: {
"data-bind": dataKey,
"data-prop": "checked",
},
properties: {
type: "radio",
name: radioName,
value: dataKey,
},
listeners: callback
? [
{
type: "change",
listener: callback,
},
]
: [],
},
],
};
}

View File

@ -0,0 +1,26 @@
import { PatchHelper } from "zotero-plugin-toolkit";
import { getPref } from "../utils/prefs";
export function patchExportItems(win: _ZoteroTypes.MainWindow) {
const Zotero_File_Interface = win.Zotero_File_Interface;
new PatchHelper().setData({
target: Zotero_File_Interface,
funcSign: "exportItems",
patcher: (origin) =>
function () {
if (!getPref("exportNotes.takeover")) {
// @ts-ignore
return origin.apply(this);
}
const items = win.ZoteroPane.getSelectedItems();
if (items.every((item) => item.isNote())) {
return addon.hooks.onShowExportNoteOptions(
items.map((item) => item.id),
);
}
// @ts-ignore
return origin.apply(this);
},
enabled: true,
});
}

View File

@ -2,19 +2,6 @@ import { config } from "../../package.json";
import { getString } from "../utils/locale";
export function registerMenus(win: Window) {
// item
ztoolkit.Menu.register("item", { tag: "menuseparator" });
ztoolkit.Menu.register("item", {
tag: "menuitem",
label: getString("menuItem.exportNote"),
icon: `chrome://${config.addonRef}/content/icons/favicon.png`,
commandListener: (ev) => {
addon.hooks.onShowExportNoteOptions(
ZoteroPane.getSelectedItems().map((item) => item.id),
);
},
});
// menuTools
ztoolkit.Menu.register("menuTools", { tag: "menuseparator" });
ztoolkit.Menu.register("menuTools", {

View File

@ -1,7 +1,7 @@
import { PatchHelper } from "zotero-plugin-toolkit";
import { getPref } from "../utils/prefs";
export function patchViewItems(win: Window) {
export function patchViewItems(win: _ZoteroTypes.MainWindow) {
// @ts-ignore
const ZoteroPane = win.ZoteroPane;
new PatchHelper().setData({

View File

@ -58,7 +58,8 @@ async function setLinesToNote(note: Zotero.Item, lines: string[]) {
} else {
const noteHead = noteText.substring(0, containerIndex);
note.setNote(
`${noteHead}data-schema-version="${config.dataSchemaVersion
`${noteHead}data-schema-version="${
config.dataSchemaVersion
}">${lines.join("\n")}</div>`,
);
}

View File

@ -73,7 +73,9 @@ async function updateNoteLinkRelation(noteID: number) {
}
}
}
const result = await (await getRelationServer()).proxy.rebuildLinkForNote(fromLibID, fromKey, linkToData);
const result = await (
await getRelationServer()
).proxy.rebuildLinkForNote(fromLibID, fromKey, linkToData);
for (const link of result.oldOutboundLinks as LinkModel[]) {
const item = Zotero.Items.getByLibraryAndKey(link.toLibID, link.toKey);
@ -96,14 +98,18 @@ async function getNoteLinkOutboundRelation(noteID: number) {
const note = Zotero.Items.get(noteID);
const fromLibID = note.libraryID;
const fromKey = note.key;
return await (await getRelationServer()).proxy.getOutboundLinks(fromLibID, fromKey);
return await (
await getRelationServer()
).proxy.getOutboundLinks(fromLibID, fromKey);
}
async function getNoteLinkInboundRelation(noteID: number) {
const note = Zotero.Items.get(noteID);
const toLibID = note.libraryID;
const toKey = note.key;
return await (await getRelationServer()).proxy.getInboundLinks(toLibID, toKey);
return await (
await getRelationServer()
).proxy.getInboundLinks(toLibID, toKey);
}
function decodeHTMLEntities(text: string) {
@ -129,11 +135,15 @@ async function linkAnnotationToTarget(model: AnnotationModel) {
}
async function getLinkTargetByAnnotation(fromLibID: number, fromKey: string) {
return await (await getRelationServer()).proxy.getLinkTargetByAnnotation(fromLibID, fromKey);
return await (
await getRelationServer()
).proxy.getLinkTargetByAnnotation(fromLibID, fromKey);
}
async function getAnnotationByLinkTarget(toLibID: number, toKey: string) {
return await (await getRelationServer()).proxy.getAnnotationByLinkTarget(toLibID, toKey);
return await (
await getRelationServer()
).proxy.getAnnotationByLinkTarget(toLibID, toKey);
}
interface AnnotationModel {