add: UI locales

fix: menupopup bugs
This commit is contained in:
xiangyu 2023-01-04 23:30:04 +08:00
parent b27e14786d
commit b53149c8e0
14 changed files with 441 additions and 318 deletions

View File

@ -63,10 +63,10 @@
<menupopup id="menu_EditPopup">
<menu id="menu_insertTextTemplate_betternotes" class="menu-betternotes" label="&zotero.__addonRef__.workspace.menu.insertTextTemplate;">
<menupopup id="menu_insertTextTemplatePopup" onpopupshowing="Zotero.BetterNotes.ZoteroViews.updateTemplateMenu('Text');" />
<menupopup id="menu_insertTextTemplatePopup" onpopupshowing="Zotero.BetterNotes.ZoteroViews.updateTemplateMenu(arguments[0], 'Text');" />
</menu>
<menu id="menu_insertItemTemplate_betternotes" class="menu-betternotes" label="&zotero.__addonRef__.workspace.menu.insertItemTemplate;">
<menupopup id="menu_insertItemTemplatePopup" onpopupshowing="Zotero.BetterNotes.ZoteroViews.updateTemplateMenu('Item');" />
<menupopup id="menu_insertItemTemplatePopup" onpopupshowing="Zotero.BetterNotes.ZoteroViews.updateTemplateMenu(arguments[0], 'Item');" />
</menu>
<menuitem id="menu_editTemplate_betternotes" class="menu-betternotes" label="&zotero.__addonRef__.workspace.menu.editTemplate;" command="cmd_editTemplate_betternotes" />
<menu id="menu_citeSetting_betternotes" class="menu-type-betternotes menu-betternotes" label="&zotero.__addonRef__.workspace.menu.citeSetting;">

View File

@ -70,10 +70,10 @@
<menupopup id="menu_EditPopup">
<!-- <menuitem id="menu_insertNotes" label="&zotero.__addonRef__.workspace.menu.insertNotes;" key="key_insertNotes" accesskey="I" command="cmd_insertNotes" /> -->
<menu id="menu_insertTextTemplate" label="&zotero.__addonRef__.workspace.menu.insertTextTemplate;">
<menupopup id="menu_insertTextTemplatePopup" onpopupshowing="Zotero.BetterNotes.ZoteroViews.updateTemplateMenu('Text');" />
<menupopup id="menu_insertTextTemplatePopup" onpopupshowing="Zotero.BetterNotes.ZoteroViews.updateTemplateMenu(arguments[0], 'Text');" />
</menu>
<menu id="menu_insertItemTemplate" label="&zotero.__addonRef__.workspace.menu.insertItemTemplate;">
<menupopup id="menu_insertItemTemplatePopup" onpopupshowing="Zotero.BetterNotes.ZoteroViews.updateTemplateMenu('Item');" />
<menupopup id="menu_insertItemTemplatePopup" onpopupshowing="Zotero.BetterNotes.ZoteroViews.updateTemplateMenu(arguments[0], 'Item');" />
</menu>
<menuitem id="menu_editTemplate" label="&zotero.__addonRef__.workspace.menu.editTemplate;" command="cmd_editTemplate" />
<menu id="menu_citeSetting_betternotes" class="menu-type-betternotes" label="&zotero.__addonRef__.workspace.menu.citeSetting;">

View File

@ -0,0 +1,22 @@
library.workspace=Workspace
library.openWorkspace=Open Workspace
library.newMainNote=New Main Note
library.newMainNote.confirmHead=Will create a new note under collection
library.newMainNote.confirmTail=and set it the main note. Continue?
library.importMD=Import MarkDown as Note
editor.mainNote=Main Note
editor.recentMainNotes=Set Main Note from Recent
editor.refreshEditor=Refresh Editor
editor.previewInWorkspace=Preview in Workspace
editor.copyNoteLink=Copy Note Link
editor.copyNoteLinkOfLine=Copy Note Link of Current Line
editor.importMD=Import from MarkDown
editor.resizeImage=Resize Image
editor.resizeImage.prompt=Enter new width (px):
editor.previewImage=Preview Image
editor.insertAnchor=Insert Position Preview
editor.endOfNote=End of Note
menu.insertTextTemplate=Insert Note Template [Text]
menu.insertItemTemplate=Insert Note Template [Item]
export.withLinkedNotes.confirm=Export linked notes to markdown files?
export.withYAML.confirm=With YAML Front Matter?

View File

@ -7,9 +7,8 @@
<!ENTITY zotero.__addonRef__.workspace.menu.sync "Sync Main Note">
<!ENTITY zotero.__addonRef__.workspace.menu.syncmanager "Better Notes Sync Manager">
<!ENTITY zotero.__addonRef__.workspace.menu.insertNotes "Insert Notes...">
<!ENTITY zotero.__addonRef__.workspace.menu.insertTextTemplate "Insert Template">
<!ENTITY zotero.__addonRef__.workspace.menu.insertNoteTemplate "Insert Notes Using Template">
<!ENTITY zotero.__addonRef__.workspace.menu.insertItemTemplate "Insert Items Using Template">
<!ENTITY zotero.__addonRef__.workspace.menu.insertTextTemplate "Insert Note Template [Text]">
<!ENTITY zotero.__addonRef__.workspace.menu.insertItemTemplate "Insert Note Template [Item]">
<!ENTITY zotero.__addonRef__.workspace.menu.editTemplate "Note Template Editor">
<!ENTITY zotero.__addonRef__.workspace.menu.citeSetting "Citation Style in Notes">
<!ENTITY zotero.__addonRef__.workspace.menu.OCRSetting "Annotation Math OCR">

View File

@ -0,0 +1,22 @@
library.workspace=工作区
library.openWorkspace=打开工作区
library.newMainNote=新建笔记并设为主笔记
library.newMainNote.confirmHead=将在当前分类
library.newMainNote.confirmTail=创建新笔记并将它设为主笔记。确认继续吗?
library.importMD=导入Markdown为笔记
editor.mainNote=主笔记
editor.recentMainNotes=从最近笔记设置主笔记
editor.refreshEditor=刷新编辑器
editor.previewInWorkspace=在工作区中预览
editor.copyNoteLink=复制笔记链接
editor.copyNoteLinkOfLine=复制当前行的笔记链接
editor.importMD=从Markdown导入
editor.resizeImage=调整图片大小
editor.resizeImage.prompt=输入新的宽度(单位:像素):
editor.previewImage=预览图片
editor.insertAnchor=插入位置预览
editor.endOfNote=笔记结尾
menu.insertTextTemplate=插入笔记模板[文本/Text]
menu.insertItemTemplate=插入笔记模板[条目/Item]
export.withLinkedNotes.confirm=导出链接的子笔记到Markdown
export.withYAML.confirm=导出带有YAML Front Matter

View File

@ -7,9 +7,8 @@
<!ENTITY zotero.__addonRef__.workspace.menu.sync "同步主笔记">
<!ENTITY zotero.__addonRef__.workspace.menu.syncmanager "Better Notes同步管理">
<!ENTITY zotero.__addonRef__.workspace.menu.insertNotes "插入多条笔记...">
<!ENTITY zotero.__addonRef__.workspace.menu.insertTextTemplate "插入模板">
<!ENTITY zotero.__addonRef__.workspace.menu.insertNoteTemplate "使用模板插入多条笔记">
<!ENTITY zotero.__addonRef__.workspace.menu.insertItemTemplate "使用模板插入多个条目">
<!ENTITY zotero.__addonRef__.workspace.menu.insertTextTemplate "插入笔记模板[文本/Text]">
<!ENTITY zotero.__addonRef__.workspace.menu.insertItemTemplate "插入笔记模板[条目/Item]">
<!ENTITY zotero.__addonRef__.workspace.menu.editTemplate "笔记模板编辑器">
<!ENTITY zotero.__addonRef__.workspace.menu.citeSetting "笔记引用格式">
<!ENTITY zotero.__addonRef__.workspace.menu.OCRSetting "注释公式识别">

View File

@ -26,9 +26,11 @@ import EditorImageViewer from "./editor/imageViewerWindow";
import TemplateWindow from "./template/templateWindow";
import { SyncUtils } from "./sync/syncUtils";
import ZoteroToolkit from "zotero-plugin-toolkit";
import AddonLocale from "./zotero/locale";
class BetterNotes {
public env: "development" | "production";
public Locale: AddonLocale;
public ZoteroEvents: ZoteroEvents;
public ZoteroNotifies: ZoteroNotifies;
// Zotero UI
@ -65,6 +67,7 @@ class BetterNotes {
public toolkit: ZoteroToolkit;
constructor() {
this.Locale = new AddonLocale(this);
this.ZoteroEvents = new ZoteroEvents(this);
this.ZoteroNotifies = new ZoteroNotifies(this);
this.ZoteroViews = new ZoteroViews(this);

View File

@ -99,8 +99,9 @@ class EditorViews extends AddonBase {
_window.document,
"div"
) as HTMLDivElement;
titleNode.innerHTML = "Set Recent Main Notes";
titleNode.title = "Click item to set it main note";
titleNode.innerHTML = titleNode.title = this._Addon.Locale.getString(
"editor.recentMainNotes"
);
titleNode.style.textAlign = "center";
popup.childNodes[0].before(
titleNode,
@ -136,7 +137,7 @@ class EditorViews extends AddonBase {
"div"
) as HTMLDivElement;
header.setAttribute("title", "This is a Main Note");
header.innerHTML = "Main Note";
header.innerHTML = this._Addon.Locale.getString("editor.mainNote");
header.setAttribute("style", "font-size: medium");
addLinkDropDown.append(header);
} else {
@ -359,7 +360,9 @@ class EditorViews extends AddonBase {
"button"
) as HTMLButtonElement;
refreshButton.classList.add("option");
refreshButton.innerText = "Refresh Editor";
refreshButton.innerText = this._Addon.Locale.getString(
"editor.refreshEditor"
);
refreshButton.addEventListener("click", async (e) => {
if (
!confirm(
@ -388,7 +391,9 @@ class EditorViews extends AddonBase {
"button"
) as HTMLButtonElement;
previewButton.classList.add("option");
previewButton.innerText = "Preview in Workspace";
previewButton.innerText = this._Addon.Locale.getString(
"editor.previewInWorkspace"
);
previewButton.addEventListener("click", async (e) => {
await this._Addon.WorkspaceWindow.openWorkspaceWindow();
await this._Addon.WorkspaceWindow.setWorkspaceNote(
@ -401,7 +406,9 @@ class EditorViews extends AddonBase {
"button"
) as HTMLButtonElement;
copyLinkButton.classList.add("option");
copyLinkButton.innerText = "Copy Note Link";
copyLinkButton.innerText = this._Addon.Locale.getString(
"editor.copyNoteLink"
);
copyLinkButton.addEventListener("click", (e) => {
const linkText = this._Addon.NoteUtils.getNoteLink(noteItem);
const linkHTML = `<p><a href="${linkText}" rel="noopener noreferrer nofollow">${
@ -425,7 +432,9 @@ class EditorViews extends AddonBase {
"button"
) as HTMLButtonElement;
copyLinkAtLineButton.classList.add("option");
copyLinkAtLineButton.innerText = "Copy Note Link of Current Line";
copyLinkAtLineButton.innerText = this._Addon.Locale.getString(
"editor.copyNoteLinkOfLine"
);
copyLinkAtLineButton.addEventListener("click", (e) => {
const linkText = this._Addon.NoteUtils.getNoteLink(noteItem, {
withLine: true,
@ -451,7 +460,8 @@ class EditorViews extends AddonBase {
"button"
) as HTMLButtonElement;
importButton.classList.add("option");
importButton.innerText = "Import from MarkDown";
importButton.innerText =
this._Addon.Locale.getString("editor.importMD");
importButton.addEventListener("click", async (e) => {
await this._Addon.NoteImport.doImport(noteItem, {
ignoreVersion: true,
@ -893,6 +903,25 @@ class EditorViews extends AddonBase {
}
}
public openImagePreview(instance: Zotero.EditorInstance) {
const _window = instance._iframeWindow;
const imgs = _window.document
.querySelector(".primary-editor")
?.querySelectorAll("img");
this._Addon.EditorImageViewer.onInit(
Array.prototype.map.call(imgs, (e: HTMLImageElement) => e.src),
Array.prototype.indexOf.call(
imgs,
_window.document
.querySelector(".primary-editor")
.querySelector(".selected")
.querySelector("img")
),
instance._item.getNoteTitle(),
this._Addon.EditorImageViewer.pined
);
}
public updateEditorImagePopup(instance: Zotero.EditorInstance) {
const _window = instance._iframeWindow;
@ -904,21 +933,7 @@ class EditorViews extends AddonBase {
previewButton.innerHTML = `<div class="icon"><svg t="1668689809930" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8872" width="16" height="16"><path d="M978.346667 149.333333c0 11.776-9.557333 21.333333-21.333333 21.333333L167.68 170.666667l0 448c0 35.285333 28.714667 64 64 64l554.666667 0c35.285333 0 64-28.714667 64-42.666667l0-154.496L850.346667 356.309333 850.346667 277.930667c0-11.776 9.557333-21.333333 21.333333-21.333333s21.333333 9.557333 21.333333 21.333333l0 78.378667 0 129.194667L893.013333 640c0 37.504-47.829333 85.333333-106.666667 85.333333l-205.568 0 169.557333 169.514667c8.32 8.32 8.32 21.845333 0 30.165333-8.362667 8.362667-21.845333 8.362667-30.208 0L520.405333 725.333333l-16.810667 0-199.722667 199.68c-8.32 8.362667-21.845333 8.362667-30.165333 0-8.32-8.32-8.32-21.845333 0-30.165333L443.306667 725.333333 231.68 725.333333c-58.837333 0-106.666667-47.829333-106.666667-106.666667L125.013333 170.666667l-64 0c-11.776 0-21.333333-9.557333-21.333333-21.333333S49.194667 128 61.013333 128l405.333333 0L466.346667 85.333333l85.333333 0 0 42.666667 405.333333 0C968.789333 128 978.346667 137.557333 978.346667 149.333333zM618.666667 405.333333l-194.986667-128 0 256L618.666667 405.333333z" p-id="8873"></path></svg>Preview</div>`;
previewButton.id = "bn-image-preview";
previewButton.addEventListener("click", (e) => {
const imgs = _window.document
.querySelector(".primary-editor")
?.querySelectorAll("img");
this._Addon.EditorImageViewer.onInit(
Array.prototype.map.call(imgs, (e: HTMLImageElement) => e.src),
Array.prototype.indexOf.call(
imgs,
_window.document
.querySelector(".primary-editor")
.querySelector(".selected")
.querySelector("img")
),
instance._item.getNoteTitle(),
this._Addon.EditorImageViewer.pined
);
this.openImagePreview(instance);
});
_window.document.querySelector(".image-popup").append(previewButton);
}
@ -964,193 +979,245 @@ class EditorViews extends AddonBase {
);
};
const elementOptions = {
tag: "fragment",
subElementOptions: [
{
tag: "menuseparator",
id: "menupopup-betternotessplitter",
checkExistanceParent: instance._popup,
ignoreIfExists: true,
},
{
tag: "menuitem",
id: "menupopup-resizeImage",
checkExistanceParent: instance._popup,
ignoreIfExists: true,
attributes: { label: "Resize Image" },
customCheck: checkImageSelected,
listeners: [
{
type: "command",
listener: (e: Event) => {
const newWidth = parseFloat(
prompt(
"Enter new width (px):",
(instance._iframeWindow as any).wrappedJSObject
._currentEditorInstance._editorCore.view.state.selection
.node?.attrs?.width
)
);
if (newWidth && newWidth > 10) {
instance._iframeWindow.postMessage(
{ type: "resizeImage", width: newWidth },
"*"
);
}
},
},
],
},
{
tag: "menuseparator",
id: "menupopup-resizeimagesplitter",
checkExistanceParent: instance._popup,
customCheck: checkImageSelected,
ignoreIfExists: true,
},
{
tag: "menuitem",
id: "menupopup-copylink",
checkExistanceParent: instance._popup,
ignoreIfExists: true,
attributes: { label: "Copy Note Link" },
listeners: [
{
type: "command",
listener: (e: Event) => {
const linkText = this._Addon.NoteUtils.getNoteLink(noteItem);
const linkHTML = `<p><a href="${linkText}" rel="noopener noreferrer nofollow">${
noteItem.getNoteTitle().trim()
? noteItem.getNoteTitle().trim()
: linkText
}</a></p>`;
this._Addon.toolkit.Tool.getCopyHelper()
.addText(linkText, "text/unicode")
.addText(linkHTML, "text/html")
.copy();
this._Addon.ZoteroViews.showProgressWindow(
"Better Notes",
"Note Link Copied"
);
},
},
],
},
{
tag: "menuitem",
id: "menupopup-copylinkline",
checkExistanceParent: instance._popup,
ignoreIfExists: true,
attributes: { label: `Copy Note Link of Line ${lineIndex + 1}` },
listeners: [
{
type: "command",
listener: ((e: Event) => {
const linkText = this._Addon.NoteUtils.getNoteLink(noteItem, {
withLine: true,
});
const linkHTML = `<p><a href="${linkText}" rel="noopener noreferrer nofollow">${
noteItem.getNoteTitle().trim()
? noteItem.getNoteTitle().trim()
: linkText
}</a></p>`;
this._Addon.toolkit.Tool.getCopyHelper()
.addText(linkText, "text/unicode")
.addText(linkHTML, "text/html")
.copy();
this._Addon.ZoteroViews.showProgressWindow(
"Better Notes",
`Note Link of Line ${lineIndex + 1} Copied`
);
}) as EventListener,
},
],
},
{
tag: "menu",
id: "menupopup-insertTextTemplateMenu",
checkExistanceParent: instance._popup,
ignoreIfExists: true,
attributes: { label: "Insert Template (Text)" },
subElementOptions: [
{
tag: "menupopup",
id: `menu_insert${instance._item.id}TextTemplatePopup`,
ignoreIfExists: true,
attributes: {
onpopupshowing: `Zotero.BetterNotes.ZoteroViews.updateTemplateMenu('Text', Zotero.BetterNotes.EditorController.activeEditor._popup.ownerDocument, '${instance._item.id}', false);`,
},
},
],
},
{
tag: "menu",
id: "menupopup-insertItemTemplate",
checkExistanceParent: instance._popup,
ignoreIfExists: true,
attributes: { label: "Insert Template (Item)" },
subElementOptions: [
{
tag: "menupopup",
id: `menu_insert${instance._item.id}ItemTemplatePopup`,
ignoreIfExists: true,
attributes: {
onpopupshowing: `Zotero.BetterNotes.ZoteroViews.updateTemplateMenu('Item', Zotero.BetterNotes.EditorController.activeEditor._popup.ownerDocument, '${instance._item.id}', false);`,
},
},
],
},
{
tag: "menuseparator",
id: "menupopup-linepreviewsplitter",
checkExistanceParent: instance._popup,
ignoreIfExists: true,
},
{
tag: "menuitem",
id: "menupopup-lineprevious",
checkExistanceParent: instance._popup,
ignoreIfExists: true,
attributes: {
label: `L${lineIndex + 1}:${shorten(
lineElements[lineIndex].innerText,
25
)}`,
disabled: true,
},
},
{
tag: "menuitem",
id: "menupopup-insertposition",
checkExistanceParent: instance._popup,
ignoreIfExists: true,
attributes: { label: "<--- Insert Anchor", disabled: true },
},
{
tag: "menuitem",
id: "menupopup-linenext",
checkExistanceParent: instance._popup,
ignoreIfExists: true,
attributes: {
label:
lineIndex + 1 >= lineElements.length
? "End of Note"
: `L${lineIndex + 2}:${shorten(
lineElements[lineIndex + 1].innerText,
25
)}`,
disabled: true,
},
},
],
};
const prefix = `editormenu-betternotes-${instance.instanceID}-`;
const fragment = this._Addon.toolkit.UI.creatElementsFromJSON(
instance._popup.ownerDocument,
elementOptions
{
tag: "fragment",
namespace: "xul",
subElementOptions: [
{
tag: "menuseparator",
id: prefix + "splitter",
checkExistanceParent: instance._popup,
removeIfExists: true,
},
{
tag: "menuitem",
id: prefix + "resizeImage",
checkExistanceParent: instance._popup,
removeIfExists: true,
attributes: {
label: this._Addon.Locale.getString("editor.resizeImage"),
},
customCheck: checkImageSelected,
listeners: [
{
type: "command",
listener: (e: Event) => {
const newWidth = parseFloat(
prompt(
this._Addon.Locale.getString("editor.resizeImage.prompt"),
(instance._iframeWindow as any).wrappedJSObject
._currentEditorInstance._editorCore.view.state.selection
.node?.attrs?.width
)
);
if (newWidth && newWidth > 10) {
instance._iframeWindow.postMessage(
{ type: "resizeImage", width: newWidth },
"*"
);
}
},
},
],
},
{
tag: "menuitem",
id: prefix + "previewImage",
checkExistanceParent: instance._popup,
removeIfExists: true,
attributes: {
label: this._Addon.Locale.getString("editor.previewImage"),
},
customCheck: checkImageSelected,
listeners: [
{
type: "command",
listener: (e: Event) => {
this.openImagePreview(instance);
},
},
],
},
{
tag: "menuseparator",
id: prefix + "resizeimagesplitter",
checkExistanceParent: instance._popup,
customCheck: checkImageSelected,
removeIfExists: true,
},
{
tag: "menuitem",
id: prefix + "copylink",
checkExistanceParent: instance._popup,
removeIfExists: true,
attributes: {
label: this._Addon.Locale.getString("editor.copyNoteLink"),
},
listeners: [
{
type: "command",
listener: (e: Event) => {
const linkText = this._Addon.NoteUtils.getNoteLink(noteItem);
const linkHTML = `<p><a href="${linkText}" rel="noopener noreferrer nofollow">${
noteItem.getNoteTitle().trim()
? noteItem.getNoteTitle().trim()
: linkText
}</a></p>`;
this._Addon.toolkit.Tool.getCopyHelper()
.addText(linkText, "text/unicode")
.addText(linkHTML, "text/html")
.copy();
this._Addon.ZoteroViews.showProgressWindow(
"Better Notes",
"Note Link Copied"
);
},
},
],
},
{
tag: "menuitem",
id: prefix + "copylinkline",
checkExistanceParent: instance._popup,
removeIfExists: true,
attributes: {
label: `${this._Addon.Locale.getString(
"editor.copyNoteLinkOfLine"
)} ${lineIndex + 1}`,
},
listeners: [
{
type: "command",
listener: ((e: Event) => {
const linkText = this._Addon.NoteUtils.getNoteLink(noteItem, {
withLine: true,
});
const linkHTML = `<p><a href="${linkText}" rel="noopener noreferrer nofollow">${
noteItem.getNoteTitle().trim()
? noteItem.getNoteTitle().trim()
: linkText
}</a></p>`;
this._Addon.toolkit.Tool.getCopyHelper()
.addText(linkText, "text/unicode")
.addText(linkHTML, "text/html")
.copy();
this._Addon.ZoteroViews.showProgressWindow(
"Better Notes",
`Note Link of Line ${lineIndex + 1} Copied`
);
}) as EventListener,
},
],
},
{
tag: "menu",
id: prefix + "insertTextTemplateMenu",
checkExistanceParent: instance._popup,
removeIfExists: true,
attributes: {
label: this._Addon.Locale.getString("menu.insertTextTemplate"),
},
subElementOptions: [
{
tag: "menupopup",
ignoreIfExists: true,
listeners: [
{
type: "popupshowing",
listener: (e) => {
this._Addon.ZoteroViews.updateTemplateMenu(
e,
"Text",
false
);
},
},
],
},
],
},
{
tag: "menu",
id: prefix + "insertItemTemplate",
checkExistanceParent: instance._popup,
removeIfExists: true,
attributes: {
label: this._Addon.Locale.getString("menu.insertItemTemplate"),
},
subElementOptions: [
{
tag: "menupopup",
ignoreIfExists: true,
listeners: [
{
type: "popupshowing",
listener: (e) => {
this._Addon.ZoteroViews.updateTemplateMenu(
e,
"Item",
false
);
},
},
],
},
],
},
{
tag: "menuseparator",
id: prefix + "linepreviewsplitter",
checkExistanceParent: instance._popup,
removeIfExists: true,
},
{
tag: "menuitem",
id: prefix + "lineprevious",
checkExistanceParent: instance._popup,
removeIfExists: true,
attributes: {
label: `L${lineIndex + 1}:${shorten(
lineElements[lineIndex].innerText,
25
)}`,
disabled: true,
},
},
{
tag: "menuitem",
id: prefix + "insertposition",
checkExistanceParent: instance._popup,
removeIfExists: true,
attributes: {
label: `<--- ${this._Addon.Locale.getString(
"editor.insertAnchor"
)}`,
disabled: true,
},
},
{
tag: "menuitem",
id: prefix + "linenext",
checkExistanceParent: instance._popup,
removeIfExists: true,
attributes: {
label:
lineIndex + 1 >= lineElements.length
? this._Addon.Locale.getString("editor.endOfNote")
: `L${lineIndex + 2}:${shorten(
lineElements[lineIndex + 1].innerText,
25
)}`,
disabled: true,
},
},
],
}
);
if (fragment) {
instance._popup.append(fragment);

View File

@ -361,7 +361,7 @@ class NoteExport extends AddonBase {
const content: string = await this._Addon.NoteParse.parseNoteToMD(note, {
withMeta: withMeta,
});
console.log(
this._Addon.toolkit.Tool.log(
`Exporting MD file: ${filename}, content length: ${content.length}`
);
await Zotero.File.putContentsAsync(filename, content);

View File

@ -709,7 +709,10 @@ class NoteUtils extends AddonBase {
};
}
public async onSelectionChange(editor: Zotero.EditorInstance) {
public async onSelectionChange(
editor: Zotero.EditorInstance,
itemID: number
) {
// Update current line index
const _window = editor._iframeWindow;
const selection = _window.document.getSelection();
@ -772,12 +775,9 @@ class NoteUtils extends AddonBase {
}
}
}
this._Addon.toolkit.Tool.log(`line ${currentLineIndex} selected.`);
// Zotero.debug(
// `Current Element: ${focusNode.outerHTML}; Real Element: ${realElement.outerHTML}`
// );
this.currentLine[editor._item.id] = currentLineIndex;
// this._Addon.toolkit.Tool.log(realElement);
this._Addon.toolkit.Tool.log(`line ${currentLineIndex} of item ${itemID} selected.`);
// Don't use the instance._item.id, as it might not be updated.
this.currentLine[itemID] = currentLineIndex;
if (realElement.tagName === "A") {
let link = (realElement as HTMLLinkElement).href;
let linkedNote = (await this.getNoteFromLink(link)).item;

View File

@ -76,7 +76,7 @@ class WorkspaceWindow extends AddonBase {
Zotero_Tabs.jump(0);
let { id, container } = Zotero_Tabs.add({
type: "betternotes",
title: Zotero.locale.includes("zh") ? "工作区" : "Workspace",
title: this._Addon.Locale.getString("library.workspace"),
index: 1,
data: {},
select: select,

View File

@ -22,6 +22,7 @@ class ZoteroEvents extends AddonBase {
this._Addon.toolkit.Tool.logOptionsGlobal.disableConsole =
this._Addon.env === "production";
this._Addon.toolkit.Tool.log("init called");
this._Addon.Locale.initLocale();
this.initProxyHandler();
this.addEditorInstanceListener();
@ -91,6 +92,7 @@ class ZoteroEvents extends AddonBase {
"Recovering Note Workspace Failed",
e
);
this._Addon.toolkit.Tool.log(e);
}
await Zotero.Promise.delay(1000);
}
@ -130,18 +132,27 @@ class ZoteroEvents extends AddonBase {
await this._Addon.EditorViews.initEditor(instance);
this._Addon.toolkit.Tool.log("note editor initialized.");
const currentID = instance._item.id;
if (
instance._iframeWindow.document.body.getAttribute(
"betternotes-status"
) !== "initialized"
) !== String(currentID)
) {
// Put event listeners here to access Zotero instance
instance._iframeWindow.document.addEventListener(
"selectionchange",
async (e) => {
async (e: Event) => {
e.stopPropagation();
e.preventDefault();
await this._Addon.NoteUtils.onSelectionChange(instance);
await this._Addon.NoteUtils.onSelectionChange(
instance,
parseInt(
instance._iframeWindow.document.body.getAttribute(
"betternotes-status"
)
)
);
}
);
instance._iframeWindow.document.addEventListener("click", async (e) => {
@ -250,14 +261,16 @@ class ZoteroEvents extends AddonBase {
});
instance._iframeWindow.document.body.setAttribute(
"betternotes-status",
"initialized"
String(instance._item.id)
);
}
instance._popup.setAttribute(
"onpopupshowing",
"Zotero.BetterNotes.EditorViews.updatePopupMenu()"
);
instance._popup.addEventListener("popupshowing", (e) => {
if (e.originalTarget !== instance._popup) {
return;
}
this._Addon.EditorViews.updatePopupMenu();
});
instance._iframeWindow.addEventListener("mousedown", (e) => {
this._Addon.EditorController.activeEditor = instance;
@ -351,7 +364,11 @@ class ZoteroEvents extends AddonBase {
return;
}
const res = confirm(
`Will create a new note under collection '${currentCollection.getName()}' and set it the main note. Continue?`
`${this._Addon.Locale.getString(
"library.newMainNote.confirmHead"
)} '${currentCollection.getName()}' ${this._Addon.Locale.getString(
"library.newMainNote.confirmTail"
)}`
);
if (!res) {
return;
@ -936,8 +953,12 @@ class ZoteroEvents extends AddonBase {
new EditorMessage("export", { params: { item: noteItems[0] } })
);
} else {
const useSingleFile = confirm("Export linked notes to markdown files?");
const withMeta = confirm("With YAML header?");
const useSingleFile = confirm(
this._Addon.Locale.getString("export.withLinkedNotes.confirm")
);
const withMeta = confirm(
this._Addon.Locale.getString("export.withYAML.confirm")
);
await this._Addon.NoteExport.exportNotesToMDFiles(noteItems, {
useEmbed: !useSingleFile,
withMeta: withMeta,

18
src/zotero/locale.ts Normal file
View File

@ -0,0 +1,18 @@
import AddonModule from "../module";
import { addonRef } from "../../package.json";
class AddonLocale extends AddonModule {
private stringBundle: any;
public initLocale() {
this.stringBundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService)
.createBundle(`chrome://${addonRef}/locale/addon.properties`);
}
public getString(localString: string): string {
return this.stringBundle.GetStringFromName(localString);
}
}
export default AddonLocale;

View File

@ -64,54 +64,27 @@ class ZoteroViews extends AddonBase {
}
public addNewMainNoteButton() {
// Top toolbar button
let addNoteItem = document
.getElementById("zotero-tb-note-add")
.getElementsByTagName("menuitem")[1];
let buttons = this._Addon.toolkit.UI.creatElementsFromJSON(document, {
tag: "fragment",
subElementOptions: [
{
tag: "menuitem",
id: "zotero-tb-knowledge-create-mainnote",
attributes: {
label: "New Main Note",
class: "menuitem-iconic",
style:
"list-style-image: url('chrome://Knowledge4Zotero/skin/favicon.png');",
},
listeners: [
{
type: "click",
listener: (e) => {
this._Addon.ZoteroEvents.onEditorEvent(
new EditorMessage("createWorkspace", {})
);
},
},
],
},
{
tag: "menuitem",
id: "zotero-tb-knowledge-import-md",
attributes: {
label: "Import MarkDown as Note",
class: "menuitem-iconic",
style:
"list-style-image: url('chrome://Knowledge4Zotero/skin/favicon.png');",
},
listeners: [
{
type: "click",
listener: async (e) => {
await this._Addon.NoteImport.doImport();
},
},
],
},
],
const menupopup = document
.querySelector("#zotero-tb-note-add")
.querySelector("menupopup") as XUL.MenuPopup;
this._Addon.toolkit.UI.insertMenuItem(menupopup, {
tag: "menuitem",
label: this._Addon.Locale.getString("library.newMainNote"),
icon: "chrome://Knowledge4Zotero/skin/favicon.png",
commandListener: (e) => {
this._Addon.ZoteroEvents.onEditorEvent(
new EditorMessage("createWorkspace", {})
);
},
});
this._Addon.toolkit.UI.insertMenuItem(menupopup, {
tag: "menuitem",
label: this._Addon.Locale.getString("library.importMD"),
icon: "chrome://Knowledge4Zotero/skin/favicon.png",
commandListener: async (e) => {
await this._Addon.NoteImport.doImport();
},
});
addNoteItem.after(buttons);
}
public addOpenWorkspaceButton() {
@ -198,9 +171,7 @@ class ZoteroViews extends AddonBase {
style: "margin-left: 6px;",
},
directAttributes: {
innerHTML: Zotero.locale.includes("zh")
? "打开工作区"
: "Open Workspace",
innerHTML: this._Addon.Locale.getString("library.openWorkspace"),
},
},
],
@ -211,13 +182,13 @@ class ZoteroViews extends AddonBase {
}
public updateTemplateMenu(
type: "Note" | "Item" | "Text",
_document: Document,
prefix: string = "",
event: Event,
type: "Item" | "Text",
useMainNote: boolean = true
) {
_document =
_document || this._Addon.WorkspaceMenu.getWorkspaceMenuWindow().document;
// @ts-ignore
const menupopup = event.originalTarget as XUL.MenuPopup;
const _document = menupopup.ownerDocument;
// If no note is activated, use copy
const targetItemId =
@ -229,17 +200,14 @@ class ZoteroViews extends AddonBase {
: Zotero_Tabs.selectedID === this._Addon.WorkspaceWindow.workspaceTabId
? this._Addon.WorkspaceWindow.getWorkspaceNote().id
: -1;
this._Addon.toolkit.Tool.log(`updateTemplateMenu`);
this._Addon.toolkit.Tool.log("updateTemplateMenu");
let templates = this._Addon.TemplateController.getTemplateKeys()
.filter((e) => e.name.indexOf(type) !== -1)
.filter(
(e) =>
!this._Addon.TemplateController._systemTemplateNames.includes(e.name)
);
const popup = _document.getElementById(
`menu_insert${prefix}${type}TemplatePopup`
);
popup.innerHTML = "";
menupopup.innerHTML = "";
if (templates.length === 0) {
templates = [
{
@ -250,28 +218,32 @@ class ZoteroViews extends AddonBase {
];
}
for (const template of templates) {
const menuitem = this._Addon.toolkit.UI.createElement(
_document,
"menuitem",
"xul"
) as XUL.MenuItem;
// menuitem.setAttribute("id", template.name);
menuitem.setAttribute("label", template.name);
menuitem.setAttribute(
"oncommand",
`
Zotero.BetterNotes.ZoteroEvents.onEditorEvent({
type: "insert${type}UsingTemplate",
content: {
params: { templateName: "${template.name}", targetItemId: ${targetItemId}, useMainNote: ${useMainNote} },
const menuitem = this._Addon.toolkit.UI.creatElementsFromJSON(_document, {
tag: "menuitem",
namespace: "xul",
attributes: {
label: template.name,
disabled: template.disabled,
},
listeners: [
{
type: "command",
listener: (e) => {
this._Addon.ZoteroEvents.onEditorEvent({
type: `insert${type}UsingTemplate`,
content: {
params: {
templateName: template.name,
targetItemId,
useMainNote,
},
},
});
},
},
});`
);
if (template.disabled) {
menuitem.setAttribute("disabled", true as any);
}
popup.append(menuitem);
],
}) as XUL.MenuItem;
menupopup.append(menuitem);
}
}