From 7859df48c0055d490eeab7248d0d4cf8ac2544ac Mon Sep 17 00:00:00 2001
From: windingwind <33902321+windingwind@users.noreply.github.com>
Date: Sat, 9 Nov 2024 20:48:14 +0100
Subject: [PATCH] update: rework export window
---
addon/chrome/content/exportNotes.xhtml | 102 +++++++++
addon/chrome/content/preferences.xhtml | 5 +
addon/chrome/content/styles/exportNotes.css | 8 +
addon/locale/en-US/addon.ftl | 2 -
addon/locale/en-US/export.ftl | 25 ---
addon/locale/en-US/exportNotes.ftl | 37 ++++
addon/locale/en-US/preferences.ftl | 2 +
addon/locale/it-IT/addon.ftl | 2 -
addon/locale/it-IT/export.ftl | 25 ---
addon/locale/it-IT/exportNotes.ftl | 37 ++++
addon/locale/it-IT/preferences.ftl | 2 +
addon/locale/ru-RU/addon.ftl | 2 -
addon/locale/ru-RU/exportNotes.ftl | 37 ++++
addon/locale/ru-RU/preferences.ftl | 2 +
addon/locale/tr-TR/addon.ftl | 2 -
addon/locale/tr-TR/export.ftl | 25 ---
addon/locale/tr-TR/exportNotes.ftl | 37 ++++
addon/locale/tr-TR/preferences.ftl | 2 +
addon/locale/zh-CN/addon.ftl | 2 -
addon/locale/zh-CN/export.ftl | 25 ---
addon/locale/zh-CN/exportNotes.ftl | 37 ++++
addon/locale/zh-CN/preferences.ftl | 2 +
addon/prefs.js | 1 +
src/extras/exportNotes.ts | 185 ++++++++++++++++
src/hooks.ts | 5 +-
src/modules/export/exportWindow.ts | 229 ++------------------
src/modules/exportItems.ts | 26 +++
src/modules/menu.ts | 13 --
src/modules/viewItems.ts | 2 +-
src/utils/note.ts | 3 +-
src/utils/relation.ts | 20 +-
31 files changed, 568 insertions(+), 336 deletions(-)
create mode 100644 addon/chrome/content/exportNotes.xhtml
create mode 100644 addon/chrome/content/styles/exportNotes.css
delete mode 100644 addon/locale/en-US/export.ftl
create mode 100644 addon/locale/en-US/exportNotes.ftl
delete mode 100644 addon/locale/it-IT/export.ftl
create mode 100644 addon/locale/it-IT/exportNotes.ftl
create mode 100644 addon/locale/ru-RU/exportNotes.ftl
delete mode 100644 addon/locale/tr-TR/export.ftl
create mode 100644 addon/locale/tr-TR/exportNotes.ftl
delete mode 100644 addon/locale/zh-CN/export.ftl
create mode 100644 addon/locale/zh-CN/exportNotes.ftl
create mode 100644 src/extras/exportNotes.ts
create mode 100644 src/modules/exportItems.ts
diff --git a/addon/chrome/content/exportNotes.xhtml b/addon/chrome/content/exportNotes.xhtml
new file mode 100644
index 00000000..cc5e5b48
--- /dev/null
+++ b/addon/chrome/content/exportNotes.xhtml
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addon/chrome/content/preferences.xhtml b/addon/chrome/content/preferences.xhtml
index de003179..5412d923 100644
--- a/addon/chrome/content/preferences.xhtml
+++ b/addon/chrome/content/preferences.xhtml
@@ -16,6 +16,11 @@
native="true"
preference="__prefsPrefix__.openNote.defaultAsWindow"
/>
+
diff --git a/addon/chrome/content/styles/exportNotes.css b/addon/chrome/content/styles/exportNotes.css
new file mode 100644
index 00000000..8d1ff4aa
--- /dev/null
+++ b/addon/chrome/content/styles/exportNotes.css
@@ -0,0 +1,8 @@
+dialog {
+ -moz-window-dragging: drag;
+}
+
+#markdown-autoSync {
+ margin-inline-start: 18px;
+ margin-block-end: 24px;
+}
diff --git a/addon/locale/en-US/addon.ftl b/addon/locale/en-US/addon.ftl
index 6df150e5..c9acf259 100644
--- a/addon/locale/en-US/addon.ftl
+++ b/addon/locale/en-US/addon.ftl
@@ -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
diff --git a/addon/locale/en-US/export.ftl b/addon/locale/en-US/export.ftl
deleted file mode 100644
index 23482214..00000000
--- a/addon/locale/en-US/export.ftl
+++ /dev/null
@@ -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.
- }
\ No newline at end of file
diff --git a/addon/locale/en-US/exportNotes.ftl b/addon/locale/en-US/exportNotes.ftl
new file mode 100644
index 00000000..aba431ea
--- /dev/null
+++ b/addon/locale/en-US/exportNotes.ftl
@@ -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
diff --git a/addon/locale/en-US/preferences.ftl b/addon/locale/en-US/preferences.ftl
index f092161a..e2636846 100644
--- a/addon/locale/en-US/preferences.ftl
+++ b/addon/locale/en-US/preferences.ftl
@@ -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
diff --git a/addon/locale/it-IT/addon.ftl b/addon/locale/it-IT/addon.ftl
index cf1e742a..00dde5d2 100644
--- a/addon/locale/it-IT/addon.ftl
+++ b/addon/locale/it-IT/addon.ftl
@@ -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
diff --git a/addon/locale/it-IT/export.ftl b/addon/locale/it-IT/export.ftl
deleted file mode 100644
index 2e077e45..00000000
--- a/addon/locale/it-IT/export.ftl
+++ /dev/null
@@ -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
- }
\ No newline at end of file
diff --git a/addon/locale/it-IT/exportNotes.ftl b/addon/locale/it-IT/exportNotes.ftl
new file mode 100644
index 00000000..7a2680c6
--- /dev/null
+++ b/addon/locale/it-IT/exportNotes.ftl
@@ -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
diff --git a/addon/locale/it-IT/preferences.ftl b/addon/locale/it-IT/preferences.ftl
index d5a2f2d0..f7b674c0 100644
--- a/addon/locale/it-IT/preferences.ftl
+++ b/addon/locale/it-IT/preferences.ftl
@@ -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
diff --git a/addon/locale/ru-RU/addon.ftl b/addon/locale/ru-RU/addon.ftl
index c7580dd0..203df513 100644
--- a/addon/locale/ru-RU/addon.ftl
+++ b/addon/locale/ru-RU/addon.ftl
@@ -1,7 +1,5 @@
pref-title=Better Notes
-menuItem-exportNote=Экспорт заметки
-
menuEdit-exportTemplate=Экспорт шаблона в файл...
menuEdit-templateEditor=Редактор шаблонов
menuEdit-importTemplate=Новый шаблон из буфера обмена
diff --git a/addon/locale/ru-RU/exportNotes.ftl b/addon/locale/ru-RU/exportNotes.ftl
new file mode 100644
index 00000000..0c98730b
--- /dev/null
+++ b/addon/locale/ru-RU/exportNotes.ftl
@@ -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 = Автоматически генерировать имя файла
diff --git a/addon/locale/ru-RU/preferences.ftl b/addon/locale/ru-RU/preferences.ftl
index c590da75..bd9b3152 100644
--- a/addon/locale/ru-RU/preferences.ftl
+++ b/addon/locale/ru-RU/preferences.ftl
@@ -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 расширить до уровня заголовка
diff --git a/addon/locale/tr-TR/addon.ftl b/addon/locale/tr-TR/addon.ftl
index 99bd53c3..3a8a6010 100644
--- a/addon/locale/tr-TR/addon.ftl
+++ b/addon/locale/tr-TR/addon.ftl
@@ -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
diff --git a/addon/locale/tr-TR/export.ftl b/addon/locale/tr-TR/export.ftl
deleted file mode 100644
index 1fd9edd7..00000000
--- a/addon/locale/tr-TR/export.ftl
+++ /dev/null
@@ -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
- }
diff --git a/addon/locale/tr-TR/exportNotes.ftl b/addon/locale/tr-TR/exportNotes.ftl
new file mode 100644
index 00000000..62df0b8c
--- /dev/null
+++ b/addon/locale/tr-TR/exportNotes.ftl
@@ -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
diff --git a/addon/locale/tr-TR/preferences.ftl b/addon/locale/tr-TR/preferences.ftl
index 1114d944..2ddc68ff 100644
--- a/addon/locale/tr-TR/preferences.ftl
+++ b/addon/locale/tr-TR/preferences.ftl
@@ -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
diff --git a/addon/locale/zh-CN/addon.ftl b/addon/locale/zh-CN/addon.ftl
index 161ff0da..dfd8b43e 100644
--- a/addon/locale/zh-CN/addon.ftl
+++ b/addon/locale/zh-CN/addon.ftl
@@ -1,7 +1,5 @@
pref-title=Better Notes
-menuItem-exportNote=导出笔记
-
menuEdit-exportTemplate=运行模板并导出为文件...
menuEdit-templateEditor=模板编辑器
menuEdit-importTemplate=从剪贴板导入笔记模板
diff --git a/addon/locale/zh-CN/export.ftl b/addon/locale/zh-CN/export.ftl
deleted file mode 100644
index 4205890a..00000000
--- a/addon/locale/zh-CN/export.ftl
+++ /dev/null
@@ -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}个
- }
\ No newline at end of file
diff --git a/addon/locale/zh-CN/exportNotes.ftl b/addon/locale/zh-CN/exportNotes.ftl
new file mode 100644
index 00000000..c7114001
--- /dev/null
+++ b/addon/locale/zh-CN/exportNotes.ftl
@@ -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 = 自动生成文件名
diff --git a/addon/locale/zh-CN/preferences.ftl b/addon/locale/zh-CN/preferences.ftl
index 2f3b1434..8c077c38 100644
--- a/addon/locale/zh-CN/preferences.ftl
+++ b/addon/locale/zh-CN/preferences.ftl
@@ -3,6 +3,8 @@ basic-openNote-takeover =
.label = 接管打开笔记
basic-openNote-defaultAsWindow =
.label = 默认在窗口打开笔记
+basic-exportNotes-takeover =
+ .label = 接管导出笔记
editor-title = 笔记编辑器
editor-expandLevel-label = 大纲展开至标题层级
diff --git a/addon/prefs.js b/addon/prefs.js
index f9a51bba..f8fdc5d5 100644
--- a/addon/prefs.js
+++ b/addon/prefs.js
@@ -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);
diff --git a/src/extras/exportNotes.ts b/src/extras/exportNotes.ts
new file mode 100644
index 00000000..47688153
--- /dev/null
+++ b/src/extras/exportNotes.ts
@@ -0,0 +1,185 @@
+import { getPref, setPref } from "../utils/prefs";
+
+let io: {
+ targetData: {
+ left: number;
+ title: string;
+ };
+ accepted: boolean;
+ useBuiltInExport: boolean;
+ deferred: _ZoteroTypes.DeferredPromise;
+ 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();
+}
diff --git a/src/hooks.ts b/src/hooks.ts
index 0412c278..eb57d3e8 100644
--- a/src/hooks.ts
+++ b/src/hooks.ts
@@ -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 {
+async function onMainWindowLoad(win: _ZoteroTypes.MainWindow): Promise {
await waitUtilAsync(() => win.document.readyState === "complete");
Services.scriptloader.loadSubScript(
@@ -99,6 +100,8 @@ async function onMainWindowLoad(win: Window): Promise {
patchViewItems(win);
+ patchExportItems(win);
+
restoreNoteTabs();
showUserGuide(win);
diff --git a/src/modules/export/exportWindow.ts b/src/modules/export/exportWindow.ts
index 50ddd5f1..68e461c1 100644
--- a/src/modules/export/exportWindow.ts
+++ b/src/modules/export/exportWindow.ts
@@ -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 = {},
@@ -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,
- );
- 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, overwriteOptions),
+ Object.assign(io as any, overwriteOptions),
);
- dataKeys.forEach((key) => {
- setPref(`export.${key}`, Boolean(data[key]));
- });
}
-}
-
-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,
- },
- ]
- : [],
- },
- ],
- };
+ 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();
+ }
}
diff --git a/src/modules/exportItems.ts b/src/modules/exportItems.ts
new file mode 100644
index 00000000..b9754c06
--- /dev/null
+++ b/src/modules/exportItems.ts
@@ -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,
+ });
+}
diff --git a/src/modules/menu.ts b/src/modules/menu.ts
index 0ccaf16f..808610b5 100644
--- a/src/modules/menu.ts
+++ b/src/modules/menu.ts
@@ -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", {
diff --git a/src/modules/viewItems.ts b/src/modules/viewItems.ts
index c82ee88f..9c13d9ff 100644
--- a/src/modules/viewItems.ts
+++ b/src/modules/viewItems.ts
@@ -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({
diff --git a/src/utils/note.ts b/src/utils/note.ts
index bf64596d..84d1a04f 100644
--- a/src/utils/note.ts
+++ b/src/utils/note.ts
@@ -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")}`,
);
}
diff --git a/src/utils/relation.ts b/src/utils/relation.ts
index 98369d5d..66c8613c 100644
--- a/src/utils/relation.ts
+++ b/src/utils/relation.ts
@@ -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 {