From eee0d3a0232ec72f9220f472b52ac3128739d9a1 Mon Sep 17 00:00:00 2001 From: xiangyu <3170102889@zju.edu.cn> Date: Sat, 8 Oct 2022 20:05:25 +0800 Subject: [PATCH] fix: #164 note link with line number bug --- src/addon.ts | 13 +++--- src/editor/editorController.ts | 46 +++++++++++++++++++++ src/editor/editorUI.ts | 5 ++- src/reader/annotationButton.ts | 8 +++- src/zotero/events.ts | 75 ++++++++++++++++------------------ 5 files changed, 100 insertions(+), 47 deletions(-) create mode 100644 src/editor/editorController.ts diff --git a/src/addon.ts b/src/addon.ts index 9df0454..c75c7b2 100644 --- a/src/addon.ts +++ b/src/addon.ts @@ -5,19 +5,20 @@ import AddonEvents from "./zotero/events"; import ZoteroViews from "./zotero/views"; import ReaderViews from "./reader/annotationButton"; -import WorkspaceOutline from "./workspace/workspaceOutline"; -import EditorViews from "./editor/editorUI"; import AddonWizard from "./wizard"; -import NoteExportWindow from "./editor/noteExportWindow"; import { TemplateController, TemplateAPI } from "./template/templateController"; import SyncInfoWindow from "./sync/syncInfoWindow"; import SyncListWindow from "./sync/syncListWindow"; -import NoteParse from "./editor/noteParse"; +import SyncController from "./sync/syncController"; import WorkspaceWindow from "./workspace/workspaceWindow"; +import WorkspaceOutline from "./workspace/workspaceOutline"; import WorkspaceMenu from "./workspace/workspaceMenu"; import NoteUtils from "./editor/noteUtils"; +import NoteParse from "./editor/noteParse"; +import NoteExportWindow from "./editor/noteExportWindow"; import NoteExport from "./editor/noteExportController"; -import SyncController from "./sync/syncController"; +import EditorViews from "./editor/editorUI"; +import EditorController from "./editor/editorController"; import TemplateWindow from "./template/templateWindow"; class Knowledge4Zotero { @@ -47,6 +48,7 @@ class Knowledge4Zotero { public NoteExportWindow: NoteExportWindow; public NoteParse: NoteParse; public EditorViews: EditorViews; + public EditorController: EditorController; constructor() { this.events = new AddonEvents(this); @@ -56,6 +58,7 @@ class Knowledge4Zotero { this.WorkspaceWindow = new WorkspaceWindow(this); this.WorkspaceMenu = new WorkspaceMenu(this); this.EditorViews = new EditorViews(this); + this.EditorController = new EditorController(this); this.wizard = new AddonWizard(this); this.SyncInfoWindow = new SyncInfoWindow(this); this.SyncListWindow = new SyncListWindow(this); diff --git a/src/editor/editorController.ts b/src/editor/editorController.ts new file mode 100644 index 0000000..6abf47b --- /dev/null +++ b/src/editor/editorController.ts @@ -0,0 +1,46 @@ +/* + * This file realizes editor watch. + */ + +import Knowledge4Zotero from "../addon"; +import AddonBase from "../module"; + +class EditorController extends AddonBase { + editorHistory: Array<{ + instance: Zotero.EditorInstance; + time: number; + }>; + editorPromise: ZoteroPromise; + + constructor(parent: Knowledge4Zotero) { + super(parent); + this.editorHistory = []; + } + + startWaiting() { + this.editorPromise = Zotero.Promise.defer(); + } + + async waitForEditor() { + await this.editorPromise.promise; + } + + recordEditor(instance: Zotero.EditorInstance) { + this.editorHistory.push({ + instance: instance, + time: new Date().getTime(), + }); + const aliveInstances = Zotero.Notes._editorInstances.map( + (_i) => _i.instanceID + ); + this.editorHistory = this.editorHistory.filter((obj) => + aliveInstances.includes(obj.instance.instanceID) + ); + + if (this.editorPromise) { + this.editorPromise.resolve(); + } + } +} + +export default EditorController; diff --git a/src/editor/editorUI.ts b/src/editor/editorUI.ts index a8cc500..4b9989f 100644 --- a/src/editor/editorUI.ts +++ b/src/editor/editorUI.ts @@ -470,7 +470,10 @@ class EditorViews extends AddonBase { } public getEditorElement(_document: Document): Element { - let editor = _document.querySelector(".primary-editor"); + let editor = Array.prototype.find.call( + _document.querySelectorAll(".primary-editor"), + (e) => e.id !== "note-link-preview" + ); return editor; } diff --git a/src/reader/annotationButton.ts b/src/reader/annotationButton.ts index cf4d981..8266969 100644 --- a/src/reader/annotationButton.ts +++ b/src/reader/annotationButton.ts @@ -51,7 +51,7 @@ class ReaderViews extends AddonBase { ); createNoteButton.addEventListener("click", async (e) => { - await this.createNoteFromAnnotation(annotationItem); + await this.createNoteFromAnnotation(annotationItem, e); e.preventDefault(); }); createNoteButton.addEventListener("mouseover", (e: XUL.XULEvent) => { @@ -106,7 +106,10 @@ class ReaderViews extends AddonBase { } } - private async createNoteFromAnnotation(annotationItem: Zotero.Item) { + private async createNoteFromAnnotation( + annotationItem: Zotero.Item, + event: MouseEvent + ) { if (annotationItem.annotationComment) { const text = annotationItem.annotationComment; let link = this._Addon.NoteParse.parseLinkInText(text); @@ -119,6 +122,7 @@ class ReaderViews extends AddonBase { params: { item: note, infoText: "OK", + forceStandalone: event.shiftKey, }, }) ); diff --git a/src/zotero/events.ts b/src/zotero/events.ts index 630e691..0a5ba1c 100644 --- a/src/zotero/events.ts +++ b/src/zotero/events.ts @@ -336,6 +336,8 @@ class AddonEvents extends AddonBase { } instance._knowledgeUIInitialized = true; + + this._Addon.EditorController.recordEditor(instance); }; } } @@ -747,55 +749,50 @@ class AddonEvents extends AddonBase { message.content = { params: { item: Zotero.Item | boolean, + forceStandalone: boolean, infoText: string args: {} } } */ - if (!message.content.params.item) { + const noteItem = message.content.params.item; + const forceStandalone = message.content.params.forceStandalone; + let _window = this._Addon.WorkspaceWindow.getWorkspaceWindow(); + if (!noteItem) { Zotero.debug(`Knowledge4Zotero: ${message.content.params.infoText}`); } - Zotero.debug( - `Knowledge4Zotero: onNoteLink ${message.content.params.item.id}` - ); - // Copy and save - const oldEditors = Zotero.Notes._editorInstances.map( - (e): string => e.instanceID - ); - let _window = this._Addon.WorkspaceWindow.getWorkspaceWindow(); - if (_window) { - if ( - message.content.params.item.id !== - Zotero.Prefs.get("Knowledge4Zotero.mainKnowledgeID") - ) { - this._Addon.WorkspaceWindow.setWorkspaceNote( - "preview", - message.content.params.item - ); - } - this._Addon.WorkspaceWindow.openWorkspaceWindow(); + Zotero.debug(`Knowledge4Zotero: onNoteLink ${noteItem.id}`); + if ( + !forceStandalone && + _window && + (noteItem.id === this._Addon.WorkspaceWindow.getWorkspaceNote().id || + noteItem.id === this._Addon.WorkspaceWindow.previewItemID) + ) { + // Scroll to line directly } else { - ZoteroPane.openNoteWindow(message.content.params.item.id); - } - if (message.content.params.args.line) { - let t = 0; - let newEditors = Zotero.Notes._editorInstances.filter( - (e) => !oldEditors.includes(e.instanceID) && e._knowledgeUIInitialized - ); - while (newEditors.length === 0 && t < 500) { - t += 1; - await Zotero.Promise.delay(10); - newEditors = Zotero.Notes._editorInstances.filter( - (e) => !oldEditors.includes(e.instanceID) + this._Addon.EditorController.startWaiting(); + if (_window && !forceStandalone) { + await this._Addon.WorkspaceWindow.setWorkspaceNote( + "preview", + noteItem ); + await this._Addon.WorkspaceWindow.openWorkspaceWindow(); + } else { + ZoteroPane.openNoteWindow(noteItem.id); } - newEditors.forEach((e) => { - this._Addon.EditorViews.scrollToLine( - e, - // Scroll to line - message.content.params.args.line - ); - }); + await this._Addon.EditorController.waitForEditor(); + } + + if (message.content.params.args.line) { + Zotero.Notes._editorInstances + .filter((e) => e._item.id === noteItem.id) + .forEach((e) => { + this._Addon.EditorViews.scrollToLine( + e, + // Scroll to line + message.content.params.args.line + ); + }); } } else if (message.type === "updateAutoAnnotation") { /*