add: note editor right-click menu

This commit is contained in:
xiangyu 2022-10-15 00:51:38 +08:00
parent 78c2a5db03
commit 44b5a0dfa4
5 changed files with 176 additions and 23 deletions

View File

@ -17,3 +17,6 @@ pref("extensions.zotero.Knowledge4Zotero.OCRMathpix.Appkey", "");
pref("extensions.zotero.Knowledge4Zotero.OCRXunfei.APPID", "");
pref("extensions.zotero.Knowledge4Zotero.OCRMathpix.APISecret", "");
pref("extensions.zotero.Knowledge4Zotero.OCRMathpix.APIKey", "");
pref("extensions.zotero.Knowledge4Zotero.linkAction.click", "");
pref("extensions.zotero.Knowledge4Zotero.linkAction.shiftclick", "");
pref("extensions.zotero.Knowledge4Zotero.linkAction.ctrlclick", "");

View File

@ -11,6 +11,7 @@ class EditorController extends AddonBase {
time: number;
}>;
editorPromise: ZoteroPromise;
activeEditor: Zotero.EditorInstance;
constructor(parent: Knowledge4Zotero) {
super(parent);

View File

@ -864,6 +864,123 @@ class EditorViews extends AddonBase {
}
}
public updatePopupMenu() {
console.log("updating editor popup");
const instance = this._Addon.EditorController.activeEditor;
const noteItem = instance._item;
const copyLinkId = "menupopup-copylink";
if (!instance._popup.querySelector(`#${copyLinkId}`)) {
const copyLinkMenu =
instance._popup.ownerDocument.createElement("menuitem");
copyLinkMenu.id = copyLinkId;
copyLinkMenu.setAttribute("label", "Copy Note Link");
copyLinkMenu.addEventListener("command", (e) => {
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>`;
new CopyHelper()
.addText(linkText, "text/unicode")
.addText(linkHTML, "text/html")
.copy();
this._Addon.ZoteroViews.showProgressWindow(
"Better Notes",
"Note Link Copied"
);
});
instance._popup.append(copyLinkMenu);
}
const copyLinkAtLineId = "menupopup-copylinkline";
if (!instance._popup.querySelector(`#${copyLinkAtLineId}`)) {
const copyLinkAtLineMenu =
instance._popup.ownerDocument.createElement("menuitem");
copyLinkAtLineMenu.id = copyLinkAtLineId;
copyLinkAtLineMenu.setAttribute(
"label",
`Copy Note Link of Line ${
this._Addon.NoteUtils.currentLine[noteItem.id] + 1
}`
);
copyLinkAtLineMenu.addEventListener("command", (e) => {
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>`;
new CopyHelper()
.addText(linkText, "text/unicode")
.addText(linkHTML, "text/html")
.copy();
this._Addon.ZoteroViews.showProgressWindow(
"Better Notes",
`Note Link of Line ${
this._Addon.NoteUtils.currentLine[noteItem.id] + 1
} Copied`
);
});
instance._popup.append(copyLinkAtLineMenu);
}
const templateTextId = "menupopup-insertTextTemplate";
if (!instance._popup.querySelector(`#${templateTextId}`)) {
const templateTextMenu =
instance._popup.ownerDocument.createElement("menu");
templateTextMenu.id = templateTextId;
templateTextMenu.setAttribute("label", "Insert Template (Text)");
const templateTextMenuPopup =
instance._popup.ownerDocument.createElement("menupopup");
templateTextMenuPopup.id = `menu_insert${instance._item.id}TextTemplatePopup`;
templateTextMenuPopup.setAttribute(
"onpopupshowing",
`Zotero.Knowledge4Zotero.ZoteroViews.updateTemplateMenu('Text', Zotero.Knowledge4Zotero.EditorController.activeEditor._popup.ownerDocument, '${instance._item.id}');`
);
templateTextMenu.append(templateTextMenuPopup);
instance._popup.append(templateTextMenu);
}
const templateNoteId = "menupopup-insertNoteTemplate";
if (!instance._popup.querySelector(`#${templateNoteId}`)) {
const templateNoteMenu =
instance._popup.ownerDocument.createElement("menu");
templateNoteMenu.id = templateNoteId;
templateNoteMenu.setAttribute("label", "Insert Template (Note)");
const templateNoteMenuPopup =
instance._popup.ownerDocument.createElement("menupopup");
templateNoteMenuPopup.id = `menu_insert${instance._item.id}NoteTemplatePopup`;
templateNoteMenuPopup.setAttribute(
"onpopupshowing",
`Zotero.Knowledge4Zotero.ZoteroViews.updateTemplateMenu('Note', Zotero.Knowledge4Zotero.EditorController.activeEditor._popup.ownerDocument, ${instance._item.id});`
);
templateNoteMenu.append(templateNoteMenuPopup);
instance._popup.append(templateNoteMenu);
}
const templateItemId = "menupopup-insertItemTemplate";
if (!instance._popup.querySelector(`#${templateItemId}`)) {
const templateItemMenu =
instance._popup.ownerDocument.createElement("menu");
templateItemMenu.id = templateItemId;
templateItemMenu.setAttribute("label", "Insert Template (Item)");
const templateItemMenuPopup =
instance._popup.ownerDocument.createElement("menupopup");
templateItemMenuPopup.id = `menu_insert${instance._item.id}ItemTemplatePopup`;
templateItemMenuPopup.setAttribute(
"onpopupshowing",
`Zotero.Knowledge4Zotero.ZoteroViews.updateTemplateMenu('Item', Zotero.Knowledge4Zotero.EditorController.activeEditor._popup.ownerDocument, ${instance._item.id});`
);
templateItemMenu.append(templateItemMenuPopup);
instance._popup.append(templateItemMenu);
}
}
public async scrollToLine(
instance: Zotero.EditorInstance,
lineIndex: number

View File

@ -335,6 +335,15 @@ class ZoteroEvents extends AddonBase {
return;
}
instance._popup.setAttribute(
"onpopupshowing",
"Zotero.Knowledge4Zotero.EditorViews.updatePopupMenu()"
);
instance._iframeWindow.addEventListener("mousedown", (e) => {
this._Addon.EditorController.activeEditor = instance;
});
instance._knowledgeUIInitialized = true;
this._Addon.EditorController.recordEditor(instance);
@ -777,10 +786,13 @@ class ZoteroEvents extends AddonBase {
} else if (message.type === "insertTextUsingTemplate") {
/*
message.content = {
params: {templateName, copy}
params: {templateName, targetItemId}
}
*/
const newLines: string[] = [];
const targetItem = Zotero.Items.get(
message.content.params.targetItemId
) as Zotero.Item;
const progressWindow = this._Addon.ZoteroViews.showProgressWindow(
"Running Template",
@ -797,7 +809,7 @@ class ZoteroEvents extends AddonBase {
newLines.push(renderredTemplate);
newLines.push("<p> </p>");
const html = newLines.join("\n");
if (message.content.params.copy) {
if (!targetItem) {
console.log(html);
new CopyHelper()
.addText(html, "text/html")
@ -806,7 +818,12 @@ class ZoteroEvents extends AddonBase {
progressWindow.changeHeadline("Template Copied");
} else {
// End of line
await this._Addon.NoteUtils.addLineToNote(mainNote, html, -1, false);
await this._Addon.NoteUtils.addLineToNote(
targetItem,
html,
-1,
false
);
progressWindow.changeHeadline("Running Template Finished");
}
} else {
@ -819,6 +836,10 @@ class ZoteroEvents extends AddonBase {
params: {templateName}
}
*/
const targetItem = Zotero.Items.get(
message.content.params.targetItemId
) as Zotero.Item;
const ids = await this._Addon.ZoteroViews.openSelectItemsWindow();
const items = (Zotero.Items.get(ids) as Zotero.Item[]).filter(
(item: Zotero.Item) => item.isRegularItem()
@ -904,7 +925,7 @@ class ZoteroEvents extends AddonBase {
if (newLines) {
const html = newLines.join("\n");
if (message.content.params.copy) {
if (!targetItem) {
console.log(html);
new CopyHelper()
@ -916,14 +937,14 @@ class ZoteroEvents extends AddonBase {
const forceMetadata = toCopyImage.length > 0;
console.log(toCopyImage);
await this._Addon.NoteUtils.addLineToNote(
mainNote,
targetItem,
html,
-1,
forceMetadata
);
await Zotero.DB.executeTransaction(async () => {
for (const subNote of toCopyImage) {
await Zotero.Notes.copyEmbeddedImages(subNote, mainNote);
await Zotero.Notes.copyEmbeddedImages(subNote, targetItem);
}
});
progressWindow.changeHeadline("Running Template Finished");
@ -938,6 +959,9 @@ class ZoteroEvents extends AddonBase {
params: {templateName}
}
*/
const targetItem = Zotero.Items.get(
message.content.params.targetItemId
) as Zotero.Item;
const ids = await this._Addon.ZoteroViews.openSelectItemsWindow();
const notes = (Zotero.Items.get(ids) as Zotero.Item[]).filter(
(item: Zotero.Item) => item.isNote()
@ -1027,7 +1051,7 @@ class ZoteroEvents extends AddonBase {
if (newLines) {
const html = newLines.join("\n");
if (message.content.params.copy) {
if (!targetItem) {
console.log(html);
new CopyHelper()
@ -1039,14 +1063,14 @@ class ZoteroEvents extends AddonBase {
const forceMetadata = toCopyImage.length > 0;
console.log(toCopyImage);
await this._Addon.NoteUtils.addLineToNote(
mainNote,
targetItem,
html,
-1,
forceMetadata
);
await Zotero.DB.executeTransaction(async () => {
for (const subNote of toCopyImage) {
await Zotero.Notes.copyEmbeddedImages(subNote, mainNote);
await Zotero.Notes.copyEmbeddedImages(subNote, targetItem);
}
});
progressWindow.changeHeadline("Running Template Finished");

View File

@ -145,16 +145,24 @@ class ZoteroViews extends AddonBase {
.children[0].before(treeRow);
}
public updateTemplateMenu(type: "Note" | "Item" | "Text") {
const _window = this._Addon.WorkspaceMenu.getWorkspaceMenuWindow();
public updateTemplateMenu(
type: "Note" | "Item" | "Text",
_document: Document,
prefix: string = ""
) {
_document =
_document || this._Addon.WorkspaceMenu.getWorkspaceMenuWindow().document;
// If tab is open but not selected, we use copy mode
const copyMode =
Boolean(
this._Addon.WorkspaceWindow.workspaceTabId &&
this._Addon.WorkspaceWindow.workspaceTabId !== "WINDOW" &&
Zotero_Tabs.selectedID !== this._Addon.WorkspaceWindow.workspaceTabId
) || !this._Addon.WorkspaceWindow.workspaceTabId;
// If no note is activated, use copy
const targetItemId =
this._Addon.EditorController.activeEditor &&
Zotero.Notes._editorInstances.includes(
this._Addon.EditorController.activeEditor
)
? this._Addon.EditorController.activeEditor._item.id
: Zotero_Tabs.selectedID === this._Addon.WorkspaceWindow.workspaceTabId
? this._Addon.WorkspaceWindow.getWorkspaceNote().id
: -1;
Zotero.debug(`updateTemplateMenu`);
let templates = this._Addon.TemplateController.getTemplateKeys()
.filter((e) => e.name.indexOf(type) !== -1)
@ -162,8 +170,8 @@ class ZoteroViews extends AddonBase {
(e) =>
!this._Addon.TemplateController._systemTemplateNames.includes(e.name)
);
const popup = _window.document.getElementById(
`menu_insert${type}TemplatePopup`
const popup = _document.getElementById(
`menu_insert${prefix}${type}TemplatePopup`
);
popup.innerHTML = "";
if (templates.length === 0) {
@ -176,8 +184,8 @@ class ZoteroViews extends AddonBase {
];
}
for (const template of templates) {
const menuitem = _window.document.createElement("menuitem");
menuitem.setAttribute("id", template.name);
const menuitem = _document.createElement("menuitem");
// menuitem.setAttribute("id", template.name);
menuitem.setAttribute("label", template.name);
menuitem.setAttribute(
"oncommand",
@ -185,7 +193,7 @@ class ZoteroViews extends AddonBase {
Zotero.Knowledge4Zotero.ZoteroEvents.onEditorEvent({
type: "insert${type}UsingTemplate",
content: {
params: { templateName: "${template.name}", copy: ${copyMode} },
params: { templateName: "${template.name}", targetItemId: ${targetItemId} },
},
});`
);