add: insert lines support undo/redo

This commit is contained in:
xiangyu 2022-07-10 20:45:35 +08:00
parent 0f16a30bdc
commit 197e53b814
4 changed files with 110 additions and 16 deletions

View File

@ -1190,7 +1190,11 @@ class AddonEvents extends AddonBase {
);
newLines.push("<p> </p>");
}
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("<p> </p>");
// 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("<p> </p>");
}
}
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("<p> </p>");
}
}
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 = {}

View File

@ -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);
}

View File

@ -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()) {

View File

@ -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