diff --git a/src/events.ts b/src/events.ts index bd2954b..8a622c9 100644 --- a/src/events.ts +++ b/src/events.ts @@ -1190,7 +1190,11 @@ class AddonEvents extends AddonBase { ); newLines.push("
"); } - await this._Addon.knowledge.addLinesToNote(undefined, newLines, -1); + await this._Addon.knowledge.addLineToNote( + undefined, + newLines.join("\n"), + -1 + ); } else if (message.type === "insertTextUsingTemplate") { /* message.content = { @@ -1207,7 +1211,11 @@ class AddonEvents extends AddonBase { newLines.push(renderredTemplate); newLines.push("
"); // End of line - await this._Addon.knowledge.addLinesToNote(undefined, newLines, -1); + await this._Addon.knowledge.addLineToNote( + undefined, + newLines.join("\n"), + -1 + ); } } else if (message.type === "insertItemUsingTemplate") { /* @@ -1272,7 +1280,11 @@ class AddonEvents extends AddonBase { newLines.push("
"); } } - await this._Addon.knowledge.addLinesToNote(undefined, newLines, -1); + await this._Addon.knowledge.addLineToNote( + undefined, + newLines.join("\n"), + -1 + ); const mainNote = this._Addon.knowledge.getWorkspaceNote(); await Zotero.DB.executeTransaction(async () => { for (const subNote of toCopyImage) { @@ -1339,7 +1351,11 @@ class AddonEvents extends AddonBase { newLines.push("
"); } } - await this._Addon.knowledge.addLinesToNote(undefined, newLines, -1); + await this._Addon.knowledge.addLineToNote( + undefined, + newLines.join("\n"), + -1 + ); } else if (message.type === "editTemplate") { /* message.content = {} diff --git a/src/knowledge.ts b/src/knowledge.ts index c3c78cf..9927119 100644 --- a/src/knowledge.ts +++ b/src/knowledge.ts @@ -7,6 +7,7 @@ class Knowledge extends AddonBase { currentNodeID: number; workspaceWindow: Window; workspaceTabId: string; + workspaceNoteEditor: EditorInstance; _exportPath: string; _exportFileDict: object; _exportPromise: any; @@ -17,6 +18,7 @@ class Knowledge extends AddonBase { this.currentLine = -1; this.currentNodeID = -1; this._pdfNoteId = -1; + this.workspaceNoteEditor = undefined; } getWorkspaceNote(): ZoteroItem { @@ -148,7 +150,15 @@ class Knowledge extends AddonBase { t += 1; await Zotero.Promise.delay(10); } - return noteEditor.getCurrentInstance() as EditorInstance; + this.workspaceNoteEditor = + noteEditor.getCurrentInstance() as EditorInstance; + return this.workspaceNoteEditor; + } + + getEditorInstance(note: ZoteroItem) { + return (Zotero.Notes._editorInstances as EditorInstance[]).find( + (e) => e._item.id === note.id + ); } async setWorkspaceNote( @@ -249,15 +259,44 @@ class Knowledge extends AddonBase { ); Zotero.debug(text); - // insert after current line - lineIndex += 1; - noteLines.splice(lineIndex, 0, text); - this.setLinesToNote(note, noteLines); - if (this.getWorkspaceNote().id === note.id) { - await this.scrollWithRefresh(lineIndex); + const editorInstance = this.getEditorInstance(note); + if (editorInstance) { + // The note is opened. Add line via note editor + console.log("Add note line via note editor"); + const _document = editorInstance._iframeWindow.document; + const currentElement = this._Addon.parse.parseHTMLLineElement( + _document.querySelector(".primary-editor"), + lineIndex + ); + const frag = _document.createDocumentFragment(); + const temp = _document.createElement("div"); + temp.innerHTML = text; + while (temp.firstChild) { + frag.appendChild(temp.firstChild); + } + currentElement.after(frag); + if (this.getWorkspaceNote().id === note.id) { + await this.scrollWithRefresh(lineIndex); + } + // this._Addon.views.scrollToElement( + // editorInstance, + // currentElement.offsetTop + // ); + } else { + // The note editor does not exits yet. Fall back to modify the metadata + console.log("Add note line via note metadata"); + + // insert after current line + lineIndex += 1; + noteLines.splice(lineIndex, 0, text); + this.setLinesToNote(note, noteLines); + if (this.getWorkspaceNote().id === note.id) { + await this.scrollWithRefresh(lineIndex); + } } } + // Abandoned async addLinesToNote( note: ZoteroItem, newLines: string[], @@ -276,10 +315,7 @@ class Knowledge extends AddonBase { } else if (lineIndex >= noteLines.length) { lineIndex = noteLines.length; } - this.setLinesToNote( - note, - noteLines.slice(0, lineIndex).concat(newLines, noteLines.slice(lineIndex)) - ); + await this.addLineToNote(note, newLines.join("\n"), lineIndex); await this.scrollWithRefresh(lineIndex); } diff --git a/src/parse.ts b/src/parse.ts index 85a13f5..bb89bb8 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -164,6 +164,37 @@ class AddonParse extends AddonBase { return parsedLines; } + parseHTMLLineElement(doc: HTMLElement, lineIndex: number): Element { + let currentLineIndex = 0; + let currentElement: Element; + + const diveTagNames = ["OL", "UL", "LI"]; + for (const e of doc.children) { + if (currentLineIndex > lineIndex) { + break; + } + if (diveTagNames.includes(e.tagName)) { + const innerLines = this.parseListElements(e); + if (currentLineIndex + innerLines.length > lineIndex) { + // The target line is inside the line list + for (const _e of innerLines) { + if (currentLineIndex <= lineIndex) { + currentLineIndex += 1; + currentElement = _e; + console.log(currentLineIndex, _e); + } + } + } + } else { + currentLineIndex += 1; + currentElement = e; + console.log(currentLineIndex, e); + } + } + console.log(currentLineIndex); + return currentElement; + } + async parseAnnotation(annotationItem: ZoteroItem) { try { if (!annotationItem || !annotationItem.isAnnotation()) { diff --git a/src/views.ts b/src/views.ts index f275571..7cff4e7 100644 --- a/src/views.ts +++ b/src/views.ts @@ -35,7 +35,7 @@ class AddonViews extends AddonBase { } getEditorElement(_document: Document): Element { - let editor = _document.getElementsByClassName("primary-editor")[0]; + let editor = _document.querySelector(".primary-editor"); return editor; } @@ -287,6 +287,17 @@ class AddonViews extends AddonBase { } } + scrollToPosition(instance: EditorInstance, offset: number) { + let editorElement = this.getEditorElement(instance._iframeWindow.document); + // @ts-ignore + (editorElement.parentNode as HTMLElement).scrollTo(0, offset); + + const texView = instance._iframeWindow.document.getElementById("texView"); + if (texView) { + texView.scrollTo(0, offset); + } + } + addNewKnowledgeButton() { // Top toolbar button let addNoteItem = document