commit
cd648d3352
|
|
@ -49,6 +49,16 @@
|
|||
preference="__prefsPrefix__.syncPeriodSeconds"
|
||||
></html:input>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<html:label
|
||||
for="__addonRef__-sync-attachmentFolder"
|
||||
data-l10n-id="sync-attachmentFolder-label"
|
||||
></html:label>
|
||||
<html:input
|
||||
id="__addonRef__-sync-attachmentFolder"
|
||||
preference="__prefsPrefix__.syncAttachmentFolder"
|
||||
></html:input>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<button
|
||||
onclick="Zotero.__addonInstance__.hooks.onShowSyncManager()"
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ editor-toolbar-settings-copyLinkAtSection = Copy Note Link at Section ({ $sectio
|
|||
editor-toolbar-settings-openParent = Open Attachment
|
||||
editor-toolbar-settings-export = Export Current Note...
|
||||
editor-toolbar-settings-refreshSyncing = Sync Now
|
||||
editor-toolbar-settings-updateRelatedNotes = Update Related Notes
|
||||
editor-toolbar-link-title = Link current note to workspace
|
||||
editor-toolbar-link-popup-nodata = Workspace note is invalid
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ workspace-autoUpdateRelatedNotes =
|
|||
.label = Automatically update related
|
||||
sync-title = Sync
|
||||
sync-period-label = Auto-sync period (seconds)
|
||||
sync-attachmentFolder-label = Attachment folder
|
||||
sync-manager =
|
||||
.label = Open Sync Manager
|
||||
template-title = Template
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ editor-toolbar-settings-copyLinkAtSection = Copia link della nota alla sezione (
|
|||
editor-toolbar-settings-openParent = Apri allegato
|
||||
editor-toolbar-settings-export = Esporta nota corrente...
|
||||
editor-toolbar-settings-refreshSyncing = Sincronizza ora
|
||||
editor-toolbar-settings-updateRelatedNotes = Update Related Notes
|
||||
editor-toolbar-link-title = Collega la nota corrente alla nota di lavoro
|
||||
editor-toolbar-link-popup-nodata = La nota di lavoro non è valida
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ workspace-autoUpdateRelatedNotes =
|
|||
.label = Aggiorna automaticamente le note correlate
|
||||
sync-title = Sincronizzazione
|
||||
sync-period-label = Intervallo della sincronizzazione automatica (secondi)
|
||||
sync-attachmentFolder-label = Attachment folder
|
||||
sync-manager =
|
||||
.label = Apri Manager di sincronizzazione
|
||||
template-title = Template
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ editor-toolbar-settings-copyLinkAtSection = Копировать Ссылку н
|
|||
editor-toolbar-settings-openParent=Открыть вложение
|
||||
editor-toolbar-settings-export=Экспортировать текущую заметку...
|
||||
editor-toolbar-settings-refreshSyncing=Синхронизировать сейчас
|
||||
editor-toolbar-settings-updateRelatedNotes = Update Related Notes
|
||||
editor-toolbar-link-title=Ссылка текущей заметки в рабочее пространство
|
||||
editor-toolbar-link-popup-nodata=Невалидная Заметка раб. пространства
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ workspace-autoUpdateRelatedNotes =
|
|||
.label = Автообновление связанных заметок
|
||||
sync-title = Синк
|
||||
sync-period-label = Авто-синк период (сек)
|
||||
sync-attachmentFolder-label = Attachment folder
|
||||
sync-manager =
|
||||
.label = Открыть Синк менеджер
|
||||
template-title = Шаблон
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ editor-toolbar-settings-copyLinkAtSection=复制当前节({ $section })笔记链
|
|||
editor-toolbar-settings-openParent=打开附件
|
||||
editor-toolbar-settings-export=导出当前笔记...
|
||||
editor-toolbar-settings-refreshSyncing=立即同步
|
||||
editor-toolbar-settings-updateRelatedNotes = 更新关联笔记
|
||||
editor-toolbar-link-title=链接当前笔记到工作区
|
||||
editor-toolbar-link-popup-nodata=工作区笔记不可用
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ workspace-autoUpdateRelatedNotes =
|
|||
.label = 自动更新"相关"
|
||||
sync-title = 同步
|
||||
sync-period-label = 自动同步周期 (秒)
|
||||
sync-attachmentFolder-label = 附件文件夹
|
||||
sync-manager =
|
||||
.label = 打开同步管理器
|
||||
template-title = 模板
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ pref("__prefsPrefix__.recentMainNoteIds", "");
|
|||
|
||||
pref("__prefsPrefix__.syncNoteIds", "");
|
||||
pref("__prefsPrefix__.syncPeriodSeconds", 30);
|
||||
pref("__prefsPrefix__.syncAttachmentFolder", "attachments");
|
||||
|
||||
pref("__prefsPrefix__.autoAnnotation", false);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "zotero-better-notes",
|
||||
"version": "1.1.4-31",
|
||||
"version": "1.1.4-36",
|
||||
"description": "Everything about note management. All in Zotero.",
|
||||
"config": {
|
||||
"addonName": "Better Notes for Zotero",
|
||||
|
|
@ -98,6 +98,6 @@
|
|||
"release-it": "^16.1.5",
|
||||
"replace-in-file": "^7.0.1",
|
||||
"typescript": "^5.2.2",
|
||||
"zotero-types": "^1.3.2"
|
||||
"zotero-types": "^1.3.5"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
19
src/hooks.ts
19
src/hooks.ts
|
|
@ -26,9 +26,7 @@ import {
|
|||
import { registerNotify } from "./modules/notify";
|
||||
import { showWorkspaceWindow } from "./modules/workspace/window";
|
||||
import {
|
||||
checkReaderAnnotationButton,
|
||||
registerReaderInitializer,
|
||||
unregisterReaderInitializer,
|
||||
registerReaderAnnotationButton,
|
||||
} from "./modules/reader";
|
||||
import { setSyncing, callSyncing } from "./modules/sync/hooks";
|
||||
import {
|
||||
|
|
@ -70,6 +68,8 @@ async function onStartup() {
|
|||
|
||||
registerPrefsWindow();
|
||||
|
||||
registerReaderAnnotationButton();
|
||||
|
||||
initSyncList();
|
||||
|
||||
setSyncing();
|
||||
|
|
@ -88,19 +88,15 @@ async function onMainWindowLoad(win: Window): Promise<void> {
|
|||
|
||||
registerWorkspaceTab();
|
||||
|
||||
registerReaderInitializer();
|
||||
|
||||
initTemplates();
|
||||
}
|
||||
|
||||
async function onMainWindowUnload(win: Window): Promise<void> {
|
||||
ztoolkit.unregisterAll();
|
||||
unregisterReaderInitializer();
|
||||
}
|
||||
|
||||
function onShutdown(): void {
|
||||
ztoolkit.unregisterAll();
|
||||
unregisterReaderInitializer();
|
||||
// Remove addon object
|
||||
addon.data.alive = false;
|
||||
unregisterWorkspaceTab();
|
||||
|
|
@ -150,15 +146,6 @@ function onNotify(
|
|||
});
|
||||
}
|
||||
}
|
||||
// Reader annotation buttons update
|
||||
if (event === "add" && type === "item") {
|
||||
const annotationItems = Zotero.Items.get(ids as number[]).filter((item) =>
|
||||
item.isAnnotation(),
|
||||
);
|
||||
if (annotationItems.length !== 0) {
|
||||
checkReaderAnnotationButton(annotationItems);
|
||||
}
|
||||
}
|
||||
// Insert annotation when assigning tag starts with @
|
||||
if (event === "add" && type === "item-tag") {
|
||||
annotationTagAction(ids as number[], extraData);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import {
|
|||
getNoteLinkParams,
|
||||
} from "../../utils/link";
|
||||
import { parseAnnotationHTML } from "../../utils/annotation";
|
||||
import { getPref } from "../../utils/prefs";
|
||||
|
||||
export {
|
||||
md2note,
|
||||
|
|
@ -79,7 +80,7 @@ async function note2md(
|
|||
await processN2MRehypeImageNodes(
|
||||
getN2MRehypeImageNodes(rehype),
|
||||
noteItem.libraryID,
|
||||
jointPath(dir, "attachments"),
|
||||
jointPath(dir, getPref("syncAttachmentFolder") as string),
|
||||
options.skipSavingImages,
|
||||
false,
|
||||
NodeMode.direct,
|
||||
|
|
@ -134,7 +135,7 @@ async function md2note(
|
|||
const _note = rehype2note(_rehype as HRoot);
|
||||
const rehype = note2rehype(_note);
|
||||
|
||||
// Check if image already belongs to note
|
||||
// Check if image citation already belongs to note
|
||||
processM2NRehypeMetaImageNodes(getM2NRehypeImageNodes(rehype));
|
||||
|
||||
processM2NRehypeHighlightNodes(getM2NRehypeHighlightNodes(rehype));
|
||||
|
|
@ -441,8 +442,7 @@ function md2remark(str: string) {
|
|||
.replace(/!\[\[(.*)\]\]/g, (s: string) => `})`)
|
||||
.replace(
|
||||
/!\[(.*)\]\((.*)\)/g,
|
||||
(match, altText, imageURL) =>
|
||||
`})`,
|
||||
(match, altText, imageURL) => `})`,
|
||||
);
|
||||
const remark = unified()
|
||||
.use(remarkGfm)
|
||||
|
|
@ -945,7 +945,10 @@ async function processN2MRehypeImageNodes(
|
|||
newFile = formatPath(
|
||||
absolutePath
|
||||
? newFile
|
||||
: `attachments/${PathUtils.split(newFile).pop()}`,
|
||||
: jointPath(
|
||||
getPref("syncAttachmentFolder") as string,
|
||||
PathUtils.split(newFile).pop() || "",
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
ztoolkit.log(e);
|
||||
|
|
@ -1119,7 +1122,6 @@ function processM2NRehypeNoteLinkNodes(nodes: string | any[]) {
|
|||
}
|
||||
|
||||
async function processM2NRehypeImageNodes(
|
||||
this: any,
|
||||
nodes: any[],
|
||||
noteItem: Zotero.Item,
|
||||
fileDir: string,
|
||||
|
|
@ -1129,26 +1131,36 @@ async function processM2NRehypeImageNodes(
|
|||
return;
|
||||
}
|
||||
|
||||
let attKeys = [] as string[];
|
||||
if (isImport) {
|
||||
attKeys = Zotero.Items.get(noteItem.getAttachments()).map(
|
||||
(item) => item.key,
|
||||
);
|
||||
}
|
||||
|
||||
for (const node of nodes) {
|
||||
if (isImport) {
|
||||
// We encode the src in md2remark and decode it here.
|
||||
let src = formatPath(decodeURIComponent(node.properties.src));
|
||||
const srcType = (src as string).startsWith("data:")
|
||||
? "b64"
|
||||
: (src as string).startsWith("http")
|
||||
? "url"
|
||||
: "file";
|
||||
if (srcType === "file") {
|
||||
if (!PathUtils.isAbsolute(src)) {
|
||||
src = jointPath(fileDir, src);
|
||||
}
|
||||
if (!(await fileExists(src))) {
|
||||
ztoolkit.log("parse image, path invalid", src);
|
||||
continue;
|
||||
// If image is already an attachment of note, skip import
|
||||
if (!attKeys.includes(node.properties.dataAttachmentKey)) {
|
||||
// We encode the src in md2remark and decode it here.
|
||||
let src = formatPath(decodeURIComponent(node.properties.src));
|
||||
const srcType = (src as string).startsWith("data:")
|
||||
? "b64"
|
||||
: (src as string).startsWith("http")
|
||||
? "url"
|
||||
: "file";
|
||||
if (srcType === "file") {
|
||||
if (!PathUtils.isAbsolute(src)) {
|
||||
src = jointPath(fileDir, src);
|
||||
}
|
||||
if (!(await fileExists(src))) {
|
||||
ztoolkit.log("parse image, path invalid", src);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const key = await importImageToNote(noteItem, src, srcType);
|
||||
node.properties.dataAttachmentKey = key;
|
||||
}
|
||||
const key = await importImageToNote(noteItem, src, srcType);
|
||||
node.properties.dataAttachmentKey = key;
|
||||
}
|
||||
delete node.properties.src;
|
||||
node.properties.ztype && delete node.properties.ztype;
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ export async function initEditorToolbar(editor: Zotero.EditorInstance) {
|
|||
},
|
||||
{
|
||||
id: makeId("settings-updateRelatedNotes"),
|
||||
text: getString("editor.toolbar.settings.updateRelatedNotes"),
|
||||
text: getString("editor-toolbar-settings-updateRelatedNotes"),
|
||||
callback: (e) => {
|
||||
addon.api.note.updateRelatedNotes(e.editor._item.id);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { showHintWithLink } from "../../utils/hint";
|
||||
import { getPref } from "../../utils/prefs";
|
||||
import { formatPath, jointPath } from "../../utils/str";
|
||||
|
||||
export async function saveMD(
|
||||
|
|
@ -10,12 +11,15 @@ export async function saveMD(
|
|||
},
|
||||
) {
|
||||
const noteItem = Zotero.Items.get(noteId);
|
||||
const dir = jointPath(
|
||||
...PathUtils.split(formatPath(filename)).slice(0, -1),
|
||||
);
|
||||
const dir = jointPath(...PathUtils.split(formatPath(filename)).slice(0, -1));
|
||||
await IOUtils.makeDirectory(dir);
|
||||
const hasImage = noteItem.getNote().includes("<img");
|
||||
if (hasImage) {
|
||||
await Zotero.File.createDirectoryIfMissingAsync(dir);
|
||||
const attachmentsDir = jointPath(
|
||||
dir,
|
||||
getPref("syncAttachmentFolder") as string,
|
||||
);
|
||||
await IOUtils.makeDirectory(attachmentsDir);
|
||||
}
|
||||
await Zotero.File.putContentsAsync(
|
||||
filename,
|
||||
|
|
@ -29,13 +33,16 @@ export async function saveMD(
|
|||
|
||||
export async function syncMDBatch(saveDir: string, noteIds: number[]) {
|
||||
const noteItems = Zotero.Items.get(noteIds);
|
||||
await Zotero.File.createDirectoryIfMissingAsync(saveDir);
|
||||
const attachmentsDir = jointPath(saveDir, "attachments");
|
||||
await IOUtils.makeDirectory(saveDir);
|
||||
const attachmentsDir = jointPath(
|
||||
saveDir,
|
||||
getPref("syncAttachmentFolder") as string,
|
||||
);
|
||||
const hasImage = noteItems.some((noteItem) =>
|
||||
noteItem.getNote().includes("<img"),
|
||||
);
|
||||
if (hasImage) {
|
||||
await Zotero.File.createDirectoryIfMissingAsync(attachmentsDir);
|
||||
await IOUtils.makeDirectory(attachmentsDir);
|
||||
}
|
||||
for (const noteItem of noteItems) {
|
||||
const filename = await addon.api.sync.getMDFileName(noteItem.id, saveDir);
|
||||
|
|
|
|||
|
|
@ -1,153 +1,72 @@
|
|||
import { TagElementProps } from "zotero-plugin-toolkit/dist/tools/ui";
|
||||
import { config } from "../../package.json";
|
||||
import { ICONS } from "../utils/config";
|
||||
import { getNoteLink, getNoteLinkParams } from "../utils/link";
|
||||
import { addLineToNote } from "../utils/note";
|
||||
|
||||
export function registerReaderInitializer() {
|
||||
ztoolkit.ReaderInstance.register(
|
||||
"initialized",
|
||||
`${config.addonRef}-annotationButtons`,
|
||||
initializeReaderAnnotationButton,
|
||||
export function registerReaderAnnotationButton() {
|
||||
Zotero.Reader.registerEventListener(
|
||||
"renderSidebarAnnotationHeader",
|
||||
(event) => {
|
||||
const { doc, append, params } = event;
|
||||
const annotationData = params.annotation;
|
||||
const annotationItem = Zotero.Items.getByLibraryAndKey(
|
||||
annotationData.libraryID,
|
||||
annotationData.id,
|
||||
) as Zotero.Item;
|
||||
|
||||
if (!annotationItem) {
|
||||
return;
|
||||
}
|
||||
const itemID = annotationItem.id;
|
||||
append(
|
||||
ztoolkit.UI.createElement(doc, "div", {
|
||||
tag: "div",
|
||||
classList: ["icon"],
|
||||
properties: {
|
||||
innerHTML: ICONS.readerQuickNote,
|
||||
},
|
||||
listeners: [
|
||||
{
|
||||
type: "click",
|
||||
listener: (e) => {
|
||||
createNoteFromAnnotation(
|
||||
itemID,
|
||||
(e as MouseEvent).shiftKey ? "standalone" : "auto",
|
||||
);
|
||||
e.preventDefault();
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "mouseover",
|
||||
listener: (e) => {
|
||||
(e.target as HTMLElement).style.backgroundColor = "#F0F0F0";
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "mouseout",
|
||||
listener: (e) => {
|
||||
(e.target as HTMLElement).style.removeProperty(
|
||||
"background-color",
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
enableElementRecord: true,
|
||||
}),
|
||||
);
|
||||
},
|
||||
config.addonID,
|
||||
);
|
||||
// Force re-initialize
|
||||
Zotero.Reader._readers.forEach((r) => {
|
||||
initializeReaderAnnotationButton(r);
|
||||
});
|
||||
}
|
||||
|
||||
export function unregisterReaderInitializer() {
|
||||
Zotero.Reader._readers.forEach((r) => {
|
||||
unInitializeReaderAnnotationButton(r);
|
||||
});
|
||||
}
|
||||
|
||||
export async function checkReaderAnnotationButton(items: Zotero.Item[]) {
|
||||
const hitSet = new Set<number>();
|
||||
let t = 0;
|
||||
const period = 100;
|
||||
const wait = 5000;
|
||||
while (items.length > hitSet.size && t < wait) {
|
||||
for (const instance of Zotero.Reader._readers) {
|
||||
const hitItems = await initializeReaderAnnotationButton(instance);
|
||||
hitItems.forEach((item) => hitSet.add(item.id));
|
||||
}
|
||||
await Zotero.Promise.delay(period);
|
||||
t += period;
|
||||
}
|
||||
}
|
||||
|
||||
async function initializeReaderAnnotationButton(
|
||||
instance: _ZoteroTypes.ReaderInstance,
|
||||
): Promise<Zotero.Item[]> {
|
||||
if (!instance) {
|
||||
return [];
|
||||
}
|
||||
await instance._initPromise;
|
||||
await instance._waitForReader();
|
||||
const _document = instance._iframeWindow?.document;
|
||||
if (!_document) {
|
||||
return [];
|
||||
}
|
||||
const hitItems: Zotero.Item[] = [];
|
||||
for (const moreButton of Array.from(_document.querySelectorAll(".more"))) {
|
||||
if (moreButton.getAttribute("_betternotesInitialized") === "true") {
|
||||
continue;
|
||||
}
|
||||
moreButton.setAttribute("_betternotesInitialized", "true");
|
||||
|
||||
let annotationWrapper = moreButton;
|
||||
while (!annotationWrapper.getAttribute("data-sidebar-annotation-id")) {
|
||||
annotationWrapper = annotationWrapper.parentElement!;
|
||||
}
|
||||
const itemKey =
|
||||
annotationWrapper.getAttribute("data-sidebar-annotation-id") || "";
|
||||
if (!instance.itemID) {
|
||||
continue;
|
||||
}
|
||||
const libraryID = Zotero.Items.get(instance.itemID).libraryID;
|
||||
const annotationItem = (await Zotero.Items.getByLibraryAndKeyAsync(
|
||||
libraryID,
|
||||
itemKey,
|
||||
)) as Zotero.Item;
|
||||
|
||||
if (!annotationItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hitItems.push(annotationItem);
|
||||
|
||||
const annotationButtons: TagElementProps[] = [
|
||||
{
|
||||
tag: "div",
|
||||
classList: ["icon"],
|
||||
properties: {
|
||||
innerHTML: ICONS.readerQuickNote,
|
||||
},
|
||||
listeners: [
|
||||
{
|
||||
type: "click",
|
||||
listener: (e) => {
|
||||
createNoteFromAnnotation(
|
||||
annotationItem,
|
||||
(e as MouseEvent).shiftKey ? "standalone" : "auto",
|
||||
);
|
||||
e.preventDefault();
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "mouseover",
|
||||
listener: (e) => {
|
||||
(e.target as HTMLElement).style.backgroundColor = "#F0F0F0";
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "mouseout",
|
||||
listener: (e) => {
|
||||
(e.target as HTMLElement).style.removeProperty(
|
||||
"background-color",
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
enableElementRecord: true,
|
||||
},
|
||||
];
|
||||
|
||||
ztoolkit.UI.insertElementBefore(
|
||||
{
|
||||
tag: "fragment",
|
||||
children: annotationButtons,
|
||||
},
|
||||
moreButton,
|
||||
);
|
||||
}
|
||||
return hitItems;
|
||||
}
|
||||
|
||||
async function unInitializeReaderAnnotationButton(
|
||||
instance: _ZoteroTypes.ReaderInstance,
|
||||
): Promise<void> {
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
await instance._initPromise;
|
||||
await instance._waitForReader();
|
||||
const _document = instance._iframeWindow?.document;
|
||||
if (!_document) {
|
||||
return;
|
||||
}
|
||||
for (const moreButton of Array.from(_document.querySelectorAll(".more"))) {
|
||||
if (moreButton.getAttribute("_betternotesInitialized") === "true") {
|
||||
moreButton.removeAttribute("_betternotesInitialized");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function createNoteFromAnnotation(
|
||||
annotationItem: Zotero.Item,
|
||||
itemID: number,
|
||||
openMode: "standalone" | "auto" = "auto",
|
||||
) {
|
||||
const annotationItem = Zotero.Items.get(itemID);
|
||||
if (!annotationItem) {
|
||||
return;
|
||||
}
|
||||
const annotationTags = annotationItem.getTags().map((_) => _.tag);
|
||||
const linkRegex = new RegExp("^zotero://note/(.*)$");
|
||||
for (const tag of annotationTags) {
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ async function runItemTemplate(
|
|||
|
||||
async function getItemTemplateData() {
|
||||
// If topItems are pre-defined, use it without asking
|
||||
if (addon.data.template.picker.data.topItemIds?.length !== 0) {
|
||||
if (addon.data.template.picker.data.topItemIds?.length > 0) {
|
||||
return addon.data.template.picker.data.topItemIds;
|
||||
}
|
||||
const librarySelectedIds = addon.data.template.picker.data
|
||||
|
|
|
|||
|
|
@ -91,7 +91,9 @@ export async function fileExists(path: string): Promise<boolean> {
|
|||
|
||||
export function jointPath(...paths: string[]) {
|
||||
try {
|
||||
return formatPath(pathHelper.join(...paths));
|
||||
return formatPath(
|
||||
pathHelper.join(...paths.map((p) => p.replaceAll("\\", "/"))),
|
||||
);
|
||||
} catch (e) {
|
||||
ztoolkit.log("[jointPath]", e);
|
||||
return "";
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ import { VirtualizedTableHelper } from "zotero-plugin-toolkit/dist/helpers/virtu
|
|||
import { LibraryTabPanelManager } from "zotero-plugin-toolkit/dist/managers/libraryTabPanel";
|
||||
import { MenuManager } from "zotero-plugin-toolkit/dist/managers/menu";
|
||||
import { PromptManager } from "zotero-plugin-toolkit/dist/managers/prompt";
|
||||
import { ReaderInstanceManager } from "zotero-plugin-toolkit/dist/managers/readerInstance";
|
||||
import { ReaderTabPanelManager } from "zotero-plugin-toolkit/dist/managers/readerTabPanel";
|
||||
import { LargePrefHelper } from "zotero-plugin-toolkit/dist/helpers/largePref";
|
||||
|
||||
|
|
@ -47,7 +46,6 @@ class MyToolkit extends BasicTool {
|
|||
Prompt: PromptManager;
|
||||
LibraryTabPanel: LibraryTabPanelManager;
|
||||
ReaderTabPanel: ReaderTabPanelManager;
|
||||
ReaderInstance: ReaderInstanceManager;
|
||||
Menu: MenuManager;
|
||||
PreferencePane: PreferencePaneManager;
|
||||
Clipboard: typeof ClipboardHelper;
|
||||
|
|
@ -63,7 +61,6 @@ class MyToolkit extends BasicTool {
|
|||
this.Prompt = new PromptManager(this);
|
||||
this.LibraryTabPanel = new LibraryTabPanelManager(this);
|
||||
this.ReaderTabPanel = new ReaderTabPanelManager(this);
|
||||
this.ReaderInstance = new ReaderInstanceManager(this);
|
||||
this.Menu = new MenuManager(this);
|
||||
this.PreferencePane = new PreferencePaneManager(this);
|
||||
this.Clipboard = ClipboardHelper;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,4 @@ declare const addon: import("../src/addon").default;
|
|||
|
||||
declare const __env__: "production" | "development";
|
||||
|
||||
declare const ChromeUtils: any;
|
||||
|
||||
declare class Localization {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue