From b1d1d490ad755b2a3e0453002c801d915c1b6d91 Mon Sep 17 00:00:00 2001 From: xiangyu <3170102889@zju.edu.cn> Date: Sun, 12 Jun 2022 13:24:18 +0800 Subject: [PATCH] fix: #52 group item link bug fix: empty template bug update: template editor --- addon/chrome/content/export.xul | 9 ++ addon/chrome/content/template.xul | 1 + addon/chrome/locale/en-US/overlay.dtd | 3 + addon/chrome/locale/zh-CN/overlay.dtd | 3 + src/events.ts | 87 +++++------ src/export.ts | 20 +++ src/knowledge.ts | 205 ++++++++++++++++++-------- src/template.ts | 53 ++++++- src/views.ts | 18 +-- 9 files changed, 274 insertions(+), 125 deletions(-) diff --git a/addon/chrome/content/export.xul b/addon/chrome/content/export.xul index 98f4e59..6807a94 100644 --- a/addon/chrome/content/export.xul +++ b/addon/chrome/content/export.xul @@ -49,5 +49,14 @@ + + + + + + + + \ No newline at end of file diff --git a/addon/chrome/content/template.xul b/addon/chrome/content/template.xul index 252faac..3d37313 100644 --- a/addon/chrome/content/template.xul +++ b/addon/chrome/content/template.xul @@ -53,6 +53,7 @@ + diff --git a/addon/chrome/locale/en-US/overlay.dtd b/addon/chrome/locale/en-US/overlay.dtd index 2b1c8ad..da8a08f 100644 --- a/addon/chrome/locale/en-US/overlay.dtd +++ b/addon/chrome/locale/en-US/overlay.dtd @@ -31,6 +31,8 @@ + + @@ -63,6 +65,7 @@ + diff --git a/addon/chrome/locale/zh-CN/overlay.dtd b/addon/chrome/locale/zh-CN/overlay.dtd index 959f9ad..a544aa4 100644 --- a/addon/chrome/locale/zh-CN/overlay.dtd +++ b/addon/chrome/locale/zh-CN/overlay.dtd @@ -31,6 +31,8 @@ + + @@ -63,6 +65,7 @@ + diff --git a/src/events.ts b/src/events.ts index 07d5011..f88d599 100644 --- a/src/events.ts +++ b/src/events.ts @@ -991,21 +991,16 @@ class AddonEvents extends AddonBase { */ const newLines = []; - const templateText = this._Addon.template.getTemplateText( + const renderredTemplate = this._Addon.template.renderTemplate( message.content.params.templateName ); - let _newLine: string = ""; - try { - _newLine = new Function("return `" + templateText + "`")(); - } catch (e) { - alert(e); - return; + if (renderredTemplate) { + newLines.push(renderredTemplate); + newLines.push("

"); + // End of line + await this._Addon.knowledge.addLinesToNote(undefined, newLines, -1); } - newLines.push(_newLine); - newLines.push("

"); - // End of line - await this._Addon.knowledge.addLinesToNote(undefined, newLines, -1); } else if (message.type === "insertItemUsingTemplate") { /* message.content = { @@ -1039,10 +1034,6 @@ class AddonEvents extends AddonBase { const newLines = []; newLines.push("

"); - const templateText = this._Addon.template.getTemplateText( - message.content.params.templateName - ); - const toCopyImage = []; const copyNoteImage = (noteItem: ZoteroItem) => { @@ -1059,18 +1050,16 @@ class AddonEvents extends AddonBase { .getNotes() .map((e) => Zotero.Items.get(e)); - let _newLine: string = ""; - try { - _newLine = new Function( - "topItem, itemNotes, copyNoteImage", - "return `" + templateText + "`" - )(topItem, itemNotes, copyNoteImage); - } catch (e) { - alert(e); - continue; + const renderredTemplate = this._Addon.template.renderTemplate( + message.content.params.templateName, + "topItem, itemNotes, copyNoteImage", + [topItem, itemNotes, copyNoteImage] + ); + + if (renderredTemplate) { + newLines.push(renderredTemplate); + newLines.push("

"); } - newLines.push(_newLine); - newLines.push("

"); } await this._Addon.knowledge.addLinesToNote(undefined, newLines, -1); const mainNote = this._Addon.knowledge.getWorkspaceNote(); @@ -1112,10 +1101,6 @@ class AddonEvents extends AddonBase { const newLines = []; newLines.push("

"); - const templateText = this._Addon.template.getTemplateText( - message.content.params.templateName - ); - for (const noteItem of notes) { /* Available variables: @@ -1130,18 +1115,17 @@ class AddonEvents extends AddonBase { const link = `

${ linkText ? linkText : linkURL }

`; - let _newLine: string = ""; - try { - _newLine = new Function( - "noteItem, topItem, link", - "return `" + templateText + "`" - )(noteItem, topItem, link); - } catch (e) { - alert(e); - continue; + + const renderredTemplate = this._Addon.template.renderTemplate( + message.content.params.templateName, + "noteItem, topItem, link", + [noteItem, topItem, link] + ); + + if (renderredTemplate) { + newLines.push(renderredTemplate); + newLines.push("

"); } - newLines.push(_newLine); - newLines.push("

"); } await this._Addon.knowledge.addLinesToNote(undefined, newLines, -1); } else if (message.type === "editTemplate") { @@ -1185,7 +1169,8 @@ class AddonEvents extends AddonBase { options.embedLink, options.exportFile, options.exportNote, - options.exportCopy + options.exportCopy, + options.exportPDF ); } } else if (message.type === "exportNotes") { @@ -1307,17 +1292,13 @@ class AddonEvents extends AddonBase { annotations[0].attachmentItemID ).parentID; - let _newLine: string = ""; - const templateText = this._Addon.template.getTemplateText("[QuickNote]"); - try { - _newLine = new Function( - "annotationItem, topItem", - "return `" + templateText + "`" - )(annotationItem, annotationItem.parentItem.parentItem); - } catch (e) { - alert(e); - } - note.setNote(`
${_newLine}\n
`); + const renderredTemplate = this._Addon.template.renderTemplate( + "[QuickNote]", + "annotationItem, topItem", + [annotationItem, annotationItem.parentItem.parentItem] + ); + + note.setNote(`
${renderredTemplate}\n
`); const tags = annotationItem.getTags(); for (const tag of tags) { diff --git a/src/export.ts b/src/export.ts index 2108700..01fdbcd 100644 --- a/src/export.ts +++ b/src/export.ts @@ -57,6 +57,19 @@ class AddonExport extends AddonBase { ) as XUL.Checkbox ).checked = exportCopy; } + let exportPDF = Zotero.Prefs.get("Knowledge4Zotero.exportPDF"); + if (typeof exportPDF !== "undefined") { + ( + this._window.document.getElementById( + "Knowledge4Zotero-export-enablepdf" + ) as XUL.Checkbox + ).checked = false; + } + ( + this._window.document.getElementById( + "Knowledge4Zotero-export-enablepdf" + ) as XUL.Checkbox + ).disabled = true; this.doUpdate(); } doUpdate() { @@ -110,11 +123,17 @@ class AddonExport extends AddonBase { "Knowledge4Zotero-export-enablecopy" ) as XUL.Checkbox ).checked; + let exportPDF = ( + this._window.document.getElementById( + "Knowledge4Zotero-export-enablepdf" + ) as XUL.Checkbox + ).checked; Zotero.Prefs.set("Knowledge4Zotero.exportFile", exportFile); Zotero.Prefs.set("Knowledge4Zotero.exportSingleFile", exportSingleFile); Zotero.Prefs.set("Knowledge4Zotero.embedLink", embedLink); Zotero.Prefs.set("Knowledge4Zotero.exportNote", exportNote); Zotero.Prefs.set("Knowledge4Zotero.exportCopy", exportCopy); + Zotero.Prefs.set("Knowledge4Zotero.exportPDF", exportPDF); Zotero.debug(this.io); Zotero.debug(this.io.dataOut); this.io.dataOut = { @@ -123,6 +142,7 @@ class AddonExport extends AddonBase { embedLink: embedLink, exportNote: exportNote, exportCopy: exportCopy, + exportPDF: exportPDF, }; } } diff --git a/src/knowledge.ts b/src/knowledge.ts index ab33bd8..0b77446 100644 --- a/src/knowledge.ts +++ b/src/knowledge.ts @@ -414,31 +414,24 @@ class Knowledge extends AddonBase { } const link = this.getNoteLink(linkedNote); const linkText = linkedNote.getNoteTitle().trim(); - let _newLine: string = ""; - const insertTemplateText = - this._Addon.template.getTemplateText("[QuickInsert]"); - try { - _newLine = new Function( - "link, subNoteItem, noteItem", - "return `" + insertTemplateText + "`" - )(link, linkedNote, targetNote); - } catch (e) { - alert(e); - } - this.addLineToNote(targetNote, _newLine, lineIndex, true); - const backLinkTemplateText = - this._Addon.template.getTemplateText("[QuickBackLink]"); - if (backLinkTemplateText) { - try { - _newLine = new Function( - "subNoteItem, noteItem", - "return `" + backLinkTemplateText + "`" - )(linkedNote, targetNote); - } catch (e) { - alert(e); - } - this.addLineToNote(linkedNote, _newLine, -1, true); + const linkTemplate = this._Addon.template.renderTemplate( + "[QuickInsert]", + "link, subNoteItem, noteItem", + [link, linkedNote, targetNote] + ); + + this.addLineToNote(targetNote, linkTemplate, lineIndex, true); + + const backLinkTemplate = this._Addon.template.renderTemplate( + "[QuickBackLink]", + "subNoteItem, noteItem", + [linkedNote, targetNote], + false + ); + + if (backLinkTemplate) { + this.addLineToNote(linkedNote, backLinkTemplate, -1, true); } this._Addon.views.showProgressWindow( @@ -724,9 +717,10 @@ class Knowledge extends AddonBase { convertNoteLinks: boolean = true, saveFile: boolean = true, saveNote: boolean = false, - saveCopy: boolean = false + saveCopy: boolean = false, + savePDF: boolean = false ) { - if (!saveFile && !saveNote && !saveCopy) { + if (!saveFile && !saveNote && !saveCopy && !savePDF) { return; } this._exportFileDict = []; @@ -810,6 +804,94 @@ class Knowledge extends AddonBase { ); } } + if (savePDF) { + console.log(newNote); + let _w: Window; + let t = 0; + do { + ZoteroPane.openNoteWindow(newNote.id); + _w = ZoteroPane.findNoteWindow(newNote.id); + console.log(_w); + await Zotero.Promise.delay(10); + t += 1; + } while (!_w && t < 500); + _w.resizeTo(900, 650); + const editor: EditorInstance = Zotero.Notes._editorInstances.find( + (e) => e._item.id === newNote.id + ); + await editor._initPromise; + + const noteEditor = _w.document.getElementById( + "zotero-note-editor" + ) as any; + + let _editor: EditorInstance = noteEditor.getCurrentInstance(); + t = 0; + while (!_editor && t < 500) { + t += 1; + await Zotero.Promise.delay(10); + _editor = noteEditor.getCurrentInstance(); + } + await Zotero.Promise.delay(3000); + + await this._Addon.events.onEditorEvent( + new EditorMessage("switchEditorTex", { + editorInstance: _editor, + params: { + viewTex: true, + }, + }) + ); + await Zotero.Promise.delay(3000); + + _editor._iframeWindow.document + .querySelectorAll(".toolbar") + .forEach((e) => e.remove()); + _editor._iframeWindow.document + .getElementById("texView") + .removeAttribute("style"); + const fullPageStyle = + _editor._iframeWindow.document.createElement("style"); + fullPageStyle.innerHTML = + "@page { margin: 0; } @media print{ body { height : auto}}"; + _editor._iframeWindow.document + .getElementById("texView") + .before(fullPageStyle); + _editor._iframeWindow.print(); + // const doc = new jsPDF(); + // const source = editor._iframeWindow.document.getElementById("texView"); + // console.log(source); + // doc.html(source, { + // callback: function (doc) { + // doc.save(); + // }, + // x: 10, + // y: 10, + // }); + // // doc.text("123", 10, 10); + // const blob = doc.output("blob"); + // console.log(blob); + // let filename = await pick( + // Zotero.getString("fileInterface.export"), + // "save", + // [["PDF File(*.pdf)", "*.pdf"]], + // `${newNote.getNoteTitle()}.pdf` + // ); + // if (filename) { + // filename = Zotero.File.pathToFile(filename).path.replace(/\\/g, "/"); + // const file = OS.Path.join(...filename.split(/\//)); + // // const d = document.createElement("a"); + // // d.href = window.URL.createObjectURL(blob); + // // d.download = file; + // // d.style.display = "none"; + // // document.appendChild(d); + // // d.click(); + // // d.remove(); + // // window.URL.revokeObjectURL(d.href); + // await Zotero.File.putContentsAsync(file, blob); + // await Zotero.File.setNormalFilePermissions(file); + // } + } if (!saveNote) { if (newNote.id !== note.id) { const _w: Window = ZoteroPane.findNoteWindow(newNote.id); @@ -952,24 +1034,11 @@ class Knowledge extends AddonBase { } private _getFileName(noteItem: ZoteroItem) { - let _newLine: string = ""; - const templateText = - this._Addon.template.getTemplateText("[ExportMDFileName]"); - try { - _newLine = new Function("noteItem", "return `" + templateText + "`")( - noteItem - ); - } catch (e) { - alert(e); - return ( - (noteItem.getNoteTitle - ? noteItem.getNoteTitle().replace(/[/\\?%*:|"<> ]/g, "-") + "-" - : "") + - noteItem.key + - ".md" - ); - } - return _newLine; + return this._Addon.template.renderTemplate( + "[ExportMDFileName]", + "noteItem", + [noteItem] + ); } async convertNoteLines( @@ -982,6 +1051,7 @@ class Knowledge extends AddonBase { let subNotes = []; const [..._rootNoteIds] = rootNoteIds; _rootNoteIds.push(currentNote.id); + let newLines = []; const noteLines = this.getLinesInNote(currentNote); for (let i in noteLines) { @@ -991,13 +1061,22 @@ class Knowledge extends AddonBase { let link = this.getLinkFromText(noteLines[i]); while (link) { const params = this.getParamsFromLink(link); + alert(params); if (params.ignore) { Zotero.debug("ignore link"); + noteLines[i] = noteLines[i].substring( + noteLines[i].search(/zotero:\/\/note\//g) + ); + noteLines[i] = noteLines[i].substring( + noteLines[i].search(/<\/a>/g) + "".length + ); + link = this.getLinkFromText(noteLines[i]); continue; } Zotero.debug("convert link"); let res = await this.getNoteFromLink(link); const subNote = res.item; + alert(`${subNote.id}, ${_rootNoteIds}`); if (subNote && _rootNoteIds.indexOf(subNote.id) === -1) { Zotero.debug(`Knowledge4Zotero: Exporting sub-note ${link}`); const convertResult = await this.convertNoteLines( @@ -1006,19 +1085,13 @@ class Knowledge extends AddonBase { convertNoteLinks ); const subNoteLines = convertResult.lines; - let _newLine: string = ""; - const templateText = - this._Addon.template.getTemplateText("[QuickImport]"); - try { - _newLine = new Function( - "subNoteLines, subNoteItem, noteItem", - "return `" + templateText + "`" - )(subNoteLines, subNote, currentNote); - } catch (e) { - alert(e); - continue; - } - newLines.push(_newLine); + + const templateText = this._Addon.template.renderTemplate( + "[QuickImport]", + "subNoteLines, subNoteItem, noteItem", + [subNoteLines, subNote, currentNote] + ); + newLines.push(templateText); subNotes.push(subNote); subNotes = subNotes.concat(convertResult.subNotes); } @@ -1059,15 +1132,28 @@ class Knowledge extends AddonBase { getParamsFromLink(uri: string) { uri = uri.split("//").pop(); - let params = { + const extraParams = {}; + uri + .split("?") + .pop() + .split("&") + .forEach((p) => { + extraParams[p.split("=")[0]] = p.split("=")[1]; + }); + uri = uri.split("?")[0]; + let params: any = { libraryID: "", noteKey: 0, - ignore: 0, }; + Object.assign(params, extraParams); const router = new Zotero.Router(params); router.add("note/:libraryID/:noteKey", function () { if (params.libraryID === "u") { params.libraryID = Zotero.Libraries.userLibraryID; + } else { + params.libraryID = Zotero.Groups.getLibraryIDFromGroupID( + params.libraryID + ); } }); router.run(uri); @@ -1082,6 +1168,7 @@ class Knowledge extends AddonBase { infoText: "Library does not exist or access denied.", }; } + Zotero.debug(params); let item = await Zotero.Items.getByLibraryAndKeyAsync( params.libraryID, params.noteKey diff --git a/src/template.ts b/src/template.ts index 298182d..75ad7cb 100644 --- a/src/template.ts +++ b/src/template.ts @@ -108,6 +108,9 @@ class AddonTemplate extends AddonBase { listitem.setAttribute("id", template.name); const name = this._window.document.createElement("listcell"); name.setAttribute("label", template.name); + if (this._systemTemplateNames.includes(template.name)) { + listitem.style.color = "#f2ac46"; + } listitem.append(name); listbox.append(listitem); } @@ -127,6 +130,8 @@ class AddonTemplate extends AddonBase { const saveTemplate = this._window.document.getElementById("save-template"); const deleteTemplate = this._window.document.getElementById("delete-template"); + const resetTemplate = + this._window.document.getElementById("reset-template"); if (!name) { header.value = ""; header.setAttribute("disabled", "true"); @@ -134,18 +139,24 @@ class AddonTemplate extends AddonBase { text.setAttribute("disabled", "true"); saveTemplate.setAttribute("disabled", "true"); deleteTemplate.setAttribute("disabled", "true"); + deleteTemplate.hidden = false; + resetTemplate.hidden = true; } else { header.value = name; if (!this._systemTemplateNames.includes(name)) { header.removeAttribute("disabled"); - deleteTemplate.removeAttribute("disabled"); + deleteTemplate.hidden = false; + resetTemplate.hidden = true; } else { header.setAttribute("disabled", "true"); deleteTemplate.setAttribute("disabled", "true"); + deleteTemplate.hidden = true; + resetTemplate.hidden = false; } text.value = templateText; text.removeAttribute("disabled"); saveTemplate.removeAttribute("disabled"); + deleteTemplate.removeAttribute("disabled"); } } @@ -235,6 +246,46 @@ class AddonTemplate extends AddonBase { this.updateTemplateView(); } + resetSelectedTemplate() { + const name = this.getSelectedTemplateName(); + if (this._systemTemplateNames.includes(name)) { + const text: XUL.Textbox = + this._window.document.getElementById("editor-textbox"); + text.value = this.getTemplateText(name); + this._Addon.views.showProgressWindow( + "Better Notes", + `Template ${name} is reset. Please save before leaving.` + ); + } + } + + renderTemplate( + key: string, + argString: string = "", + argList: any[] = [], + useDefault: boolean = true + ) { + Zotero.debug(`renderTemplate: ${key}`); + let templateText = this.getTemplateText(key); + if (useDefault && !templateText) { + templateText = this._defaultTemplates[key]; + if (!templateText) { + return ""; + } + } + + let _newLine: string = ""; + try { + _newLine = new Function(argString, "return `" + templateText + "`")( + ...argList + ); + } catch (e) { + alert(`Template ${key} Error: ${e}`); + return ""; + } + return _newLine; + } + getTemplateKeys(): NoteTemplate[] { let templateKeys: string = Zotero.Prefs.get( "Knowledge4Zotero.templateKeys" diff --git a/src/views.ts b/src/views.ts index b37bfa5..483dd4d 100644 --- a/src/views.ts +++ b/src/views.ts @@ -406,18 +406,12 @@ class AddonViews extends AddonBase { false ); const subNoteLines = convertResult.lines; - let _newLine: string = ""; - const templateText = - this._Addon.template.getTemplateText("[QuickImport]"); - try { - _newLine = new Function( - "subNoteLines, subNoteItem, noteItem", - "return `" + templateText + "`" - )(subNoteLines, note, this._Addon.knowledge.getWorkspaceNote()); - } catch (e) { - alert(e); - } - newLines.push(_newLine); + const templateText = this._Addon.template.renderTemplate( + "[QuickImport]", + "subNoteLines, subNoteItem, noteItem", + [subNoteLines, note, this._Addon.knowledge.getWorkspaceNote()] + ); + newLines.push(templateText); const newLineString = newLines.join("\n"); await this._Addon.knowledge.modifyLineInNote( undefined,