^s7%NGVOLK}eU6!a;*pgACcD@&G~pD4W$aN4RBMJY+J z&Ox~nnFO3_g)cGs(@VH1mdwH^e;$C_eWV@Tvmq zOSkf#+N0rgZ-4!9G`_X~KHGnEiqEw*#_ArH-K{lLEpx_z 1NLTE??C&y?6RFLtuH-DGHeenPk*~b#4hSP9XS8<~s zKbOx5+Wnkbf9pUKkXRVxqw}UMnAdM{MRIO(oP2|k6*4~jEZ~Lh&BZ*Y*3an{VFnB_ zc|h$3Ep_B!x*xml3zu=uDt+s_KZWdR?~#uaw8$u4#_q3dp18nouP=>MU%^K2mmHt% zfa3Q=Y=4hDfzYz=M^8CE-5zxq#fyTC-luvOiFF7N0l%P|wgXSVvg8$bE**mV(m}|s zmQLd}8T4iu0UaN|0KdI{ZM4c{j~%?m&~KyumWvOi$o3EtCLj#Q$(_&^&BuuQUkAA{ zy-CP^1Uec4{Rr@)37lxcs2>~*m+>{6X62-YQ-ADl$$AQ6;e5FN`(DI0c)f-F5>W$< zgp^>*-WBlH9D#A(8sx5cKb+pMWj1WP?uWkk0l3co1&ZVVr!hc3{XXQ)T@BCWBd{Od z2wuzrZ_JHcIj2I-@+$b->cWH#Bw`AKwHvfFmcy2sO4lK)bY1v4Rlx~5e6cAX0Y_uR zI)7A#QEcewZn+1tw;heI-UUtW3 @v5Y%?;ZEd_WL zIF&Y>Pj iFa2wtc}d I-92-!vVcAwP3 z=J>tv)_u%maLiC-_!`dza|b<=3=UmsMwkHE+x`~m_{Qyb!c+5MXTN+-I8M9{>wnhU zI8AObGUu)7**if*%iBMUyT=s&+mHPYieE~*!Mzch14?*p<^)^SGRWSJ9$Dxu``fR; z{{F8>r?V@BfW01mww8$>uCsrHan|<-%kD731b_*T&m(3cfzx()BV6a-VR1eLQf$%G zTz??lKp_$V_rO>dBSHl9yXxY#CVv=aeh=!r;&7Vt#2ZZDBmzzl2hr> IBf zO=zUd%nLR_EV=_uQi6qFhsdt^aQ=HQ6FhM@Y%V~+QG !(yelUEGQn6JQG_AGKL|J )+Nj mK9;tuFXlIbLfV z(e#Ik{gI0+P<&UARk{}X$qQp@P%OM1no(2XYu=N5?^A%J4@MN(1=(YTE=T|^dT2%0 z9h^!7-7R;+H2>#pg-44aAv5A$N!k(ja+uZx;`nbsmO3X%PF)CIw12>UxSZ_)P-Fnp z2&W)jJpujH#jK3%ZU843SopIaewqm?S*n8~J0N>%pah&lp8!qX3^snjap*Yu9Q QOhQx>A})o-yh zQiB;&m%v>9Td4HY;Hlq`RuW>K140WSTUBL5`Rh2b6Dq?*@M2NaI 5k+SV)~&aJ6LO%=Do@Ok1Q9a UHytDv# m0ZY6k;ZTR({6Wk9NlS2+)1G41y^if%Z=# zJ`YWf`l(AIu73pST){A-l7-75NdVi|x1Pr6pPYeUnGl}D$QUvzXW4ER%A(0z@(f?| zL0A^Q%;YegB85Q43z=hJoVyx+$A>90EjGmEa}>IAD*uErkDX&=$euO`<{}8Dam;wB zX~%WTOU ;i=#e|cc`QrNfY3?{1Hs0>!Hb=J}e1HXb5yyarB)Kox@AkGpX!X z+K> 5)bx&`EJRzUxUP5{?3fk_Y>cKp#JlCk!VNk_v-F zg1PL;9%;jkgrs#q# {k}8rWR`a*A*E8-Qt=WDCCi7Df&C$|{eZSwrT`-$qok7Q0U83m zL32X1asz=_=AeYW6dkUJ^rh$xzaetN6A RdE2G5f>Ed}IbRV-aS2%=pKmnT}+-_>R+TZax?USP+wK5F8*bz=}{{& 5|z)>|IojqVMA z5(6k2{?paqJ*~5nr16XJoqP#PpK1ilEr*Gs07WKiDv2LITLi$x+Ha^B`}#?iOg7%r z!rDvUg5YU^6d1z9F9#DQlG+R2cCg&_WG$y`9RCDd!REJBbE0s^mr%qAthYabXkQ}~ zDXN*Q#DsYp#{=}GuYVyL>G{D(mYwbHS7E-X91~{_ApOo~KpSn4qk+W9oC}dldy_IU zI3Lpnkj8qdosS-SPLU-eW3r3GwWU@v2^p&s)>|J(u=(A8CfZ$4 ufiY)8@&%#K+KE`G5K`zAWTA8M0J64!fnY-oA{Xn_ zwe8$-4E*pOKo7(sWYW7qv76!jpcsrT2afXhAo`EY3nKAeKryPhB8JsHA$0CjFqZt8 zB=!!3em$(l`2J@2e|!zJZdJ JD_#cobqhAv22gjlzopO4hiP@$^!;2=^O5F}jLmSXpMtjoESCeW_+_;% zwzL7#m%&=_uzEfA&C>{-Kf37Vs?S_O$NdK(O|~K0b3ujp*8zw!%Btb}em^2zXW%7)fK0yO+A^*1 zoUv4-1<;_;PsXnRK+b7>3-F!J{onsPzP1AJ7g|Ucu8S0ri~s-t07*qoM6N<$f{TAs A1ONa4 literal 0 HcmV?d00001 diff --git a/addon/chrome/skin/default/Knowledge4Zotero/favicon@0.5x.png b/addon/chrome/skin/default/Knowledge4Zotero/knowledge@0.5x.png similarity index 100% rename from addon/chrome/skin/default/Knowledge4Zotero/favicon@0.5x.png rename to addon/chrome/skin/default/Knowledge4Zotero/knowledge@0.5x.png diff --git a/addon/chrome/skin/default/Knowledge4Zotero/knowledge@2x.png b/addon/chrome/skin/default/Knowledge4Zotero/knowledge@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9b993e95ff3ac971fd237a697d753d40a6ac8b87 GIT binary patch literal 2479 zcmV;g2~hTlP) 9cFDf7Nd~@|J9~5PdHvu0&-uS|&JCw13T|ZZH?;LP2>^s7%NGVO zLK}eU6!a;*pgACcD@&G~pD4W$aN4RBMJY+J&Ox~nnFO 3_g)cGs(@VH1mdwH^e;$C_eWV@TvmqOSkf#+N0rgZ~bvJzP129+kbS5&$Tti z>K>Netu<6FbH;$=l0Eikh~#+tl_=u&0LAZhUwdb@=sdHB?)yB~O}q;uANo7p76G^% zwH}{)7pK-O?>PQ49G`AyX`0b9VgB}J1#+O4*O_Mq=am6P+>; $^XN>}l_j zj}x@WC|<_yuWX*Uz;CZFjZ|O3M(>v#pY4F+_e5-uJb}=%??+ELKHVO57{!Z%joznv z7m0NU5COlSo3;Z_z_R2OcrG1+`_e(ku9i;YH5v3~837$1zW~3zer>eMWRD%Z#?Wu0 z{+5dmrO5UW5+)!F$H|@07R|?q`(FpSF}+F1egrxi0sRQ@q6wU6!l)k{443gWoMz>u zhEwcs$$AQ6;e5FN`(DI0c)f-F5>W$ *-WBlH9D#A(8sx5cKb+pMWj1WP?uWkk z0l3co1&ZVVr!hc3{XXQ)T@BCWBd{Od2wuzrZ_JHcIj2I-@+$b->cWH#Bw`AKwHvfF zmcy2sO4lK)bY1v4Rlx~5e6cAX0Y_uRI#h;HZ0P82xd*bh9gVNv1x@Y@1RPd)>;K8# zwvaUrmZdwO9XlHw&jE^@l zliQ>2>1 lz5zMfY}})WYWYz3|q3%w%xPP-OTT&joV_J(3I#U1>&`0NLCA z7U}rL?RUac^I>Pdd`>t{ybkNu+c-^bF*4_^>DfC$M9bShjJwAa|J#rK4vJq&yTQE? zngdFBZRP}9)iTK5jviU)E&JQA!2bTPNT;(agn+#sezum0AFi{1gmKpQ2g~j-!UTW` zkIy4!B7xI(cq3fr-(hh+1X66#)Lefc-9RA{0r$XI79&Cg^t IBfO=zUd%nLR_EV=_uQi6qFhsdt^aQ=HQ6FhM@Y%V~+ zQG *(~z3qio5LfpwdqP;vgU#1$fbPA8lvltvW92r&K_b zR}9UVufSaPEOILU+^PF}xjUy8VJ?5RE1bpJsNMo?{#^K5|CWTQsX=!oc$rgaMyvFe zEtbXG7SqNDSa|GcabNhy_LjXX`mXL|KUBI*WX}H?+K>DuwhnPTMm=&6zH5gd` 4?iz`rkSCCb@7W&BxV`@+=yd9cRQ{ijglYH+} zfTRyb6xjvYV}&kA04;iGMb{miN(0?3cf&OQ=WK;Xiy }~)j7+CnTAAXt%Dp{(7B0C^^YM=z1 zL!SUm-V8Q=!Exv~`W*ai^-vi{vE?j QOhQx>A})o-yhQiB;&m%v>9Td4HY;Hlq`RuW>K140WSTUBL5`Rh2b6Dq?* z@M2NaI 5k+SV)~&aJ6LO%=Do@Ok1Q9a ?&U_IMNReW7*09tU-hDpb<=OLKxOo!cF{fZ~EulZusXXF*M z=NAo}W+Z#k?ck&bXiJO~C9lg%$dE)47Xg~Fv!WX)h!D($$&KIZ9JmY=VkUrAe#Y64 zcE ={4^58xsY@cR1nFGCFr$)%%OObs+t;_A#^|4%fnb>sp2Wx) zGAd`;ZWhX-$y@RaU-Lm&7Qf8oFr6ZWK*kH1V_=-S8h*!zDKafK#N~4ox^gQ2gfWku zV`RvlHVEb-2&Qq&c&TZ}b<0c5uR+v}$Jn*CXnXHTc(I-83LNlP#Nq%x>;i=#e|cc`QrNfY3?{1Hs0>!Hb=J}e1HXb5yy zarB)Kox@AkGpX!X+K> 5)bx&`EJRzUxUP5{?3fk_Y>c zKp#JlCk!VNk_v-Fg1PL;9%;jkgrs#q# um>y|FLhJr@ zQOgV!B&`GJG}bVw3WiBwlc1xzYf0PvzBBJ+mUk#2rBc{Z@e&Lr%ZHSK{UNdafVNtu z03#uzq>||Y8UnpRb3(Lo1A$oPpoG2@9j=J Bo-002ovPDHLkV1m|Sv3vjk literal 0 HcmV?d00001 diff --git a/addon/chrome/skin/default/Knowledge4Zotero/workspace.css b/addon/chrome/skin/default/Knowledge4Zotero/workspace.css index f31ad85..a031e5a 100644 --- a/addon/chrome/skin/default/Knowledge4Zotero/workspace.css +++ b/addon/chrome/skin/default/Knowledge4Zotero/workspace.css @@ -33,3 +33,29 @@ ul, li { display: list-item; } + +.tooltip { + position: relative; + display: inline-block; + border-bottom: 1px dotted black; +} + +.tooltip .tooltiptext { + visibility: hidden; + width: 120px; + background-color: black; + color: #fff; + text-align: center; + border-radius: 6px; + padding: 5px 0; + + position: absolute; + z-index: 1; + bottom: 100%; + left: 50%; + margin-left: -60px; +} + +.tooltip:hover .tooltiptext { + visibility: visible; +} diff --git a/src/events.ts b/src/events.ts index 32ec7b3..53f608c 100644 --- a/src/events.ts +++ b/src/events.ts @@ -27,7 +27,7 @@ class AddonEvents extends AddonBase { (event === "add" && type === "item" && Zotero.Items.get(ids).filter((item) => { - item.isAnnotation(); + return item.isAnnotation(); }).length > 0) || (event === "close" && type === "tab") || (event === "open" && type === "file") @@ -45,6 +45,7 @@ class AddonEvents extends AddonBase { Zotero.debug("Knowledge4Zotero: init called"); await Zotero.uiReadyPromise; this._Addon.views.addOpenWorkspaceButton(); + this._Addon.views.addNewKnowledgeButton(); this.addEditorInstanceListener(); // Register the callback in Zotero as an item observer let notifierID = Zotero.Notifier.registerObserver(this.notifierCallback, [ @@ -114,6 +115,17 @@ class AddonEvents extends AddonBase { message.content = {} */ await this._Addon.knowledge.openWorkspaceWindow(); + } else if (message.type === "createWorkspace") { + /* + message.content = {} + */ + const noteID = await ZoteroPane_Local.newNote(); + await this.onEditorEvent( + new EditorMessage("setMainKnowledge", { + params: noteID, + }) + ); + await this._Addon.knowledge.openWorkspaceWindow(); } else if (message.type === "addNoteInstance") { /* message.content = { @@ -224,9 +236,9 @@ class AddonEvents extends AddonBase { // This is a preview knowledge, hide openWorkspace button add show close botton this._Addon.views.changeEditorButtonView( _window.document.getElementById("knowledge-start"), - "jumpAttachment", + "openAttachment", "Open Note Attachments", - "jumpAttachment" + "openAttachment" ); this._Addon.views.changeEditorButtonView( _window.document.getElementById("knowledge-end"), @@ -298,21 +310,6 @@ class AddonEvents extends AddonBase { } Zotero.Prefs.set("Knowledge4Zotero.mainKnowledgeID", itemID); await this._Addon.knowledge.setWorkspaceNote("main"); - for (let editor of Zotero.Notes._editorInstances) { - await editor._initPromise; - let isMainKnowledge = editor._item.id === mainKnowledgeID; - let button = - editor._iframeWindow.document.getElementById("knowledge-start"); - if (button) { - this._Addon.views.changeEditorButtonView( - button, - isMainKnowledge ? "isMainKnowledge" : "notMainKnowledge", - isMainKnowledge - ? "Edit the main knowledge in Workspace" - : "Open Workspace" - ); - } - } } } else if (message.type === "clickOutlineHeading") { /* @@ -441,7 +438,7 @@ class AddonEvents extends AddonBase { await this._Addon.knowledge.exportNoteToFile( message.content.editorInstance._item ); - } else if (message.type === "jumpAttachment") { + } else if (message.type === "openAttachment") { /* message.content = { editorInstance @@ -453,10 +450,17 @@ class AddonEvents extends AddonBase { if (note.parentItem) { for (const attchment of Zotero.Items.get( note.parentItem.getAttachments() - )) { + ).filter((item: ZoteroItem) => { + return item.isPDFAttachment(); + })) { Zotero.debug(attchment); try { - await Zotero.OpenPDF.openToPage(attchment, 0); + Zotero.debug("Launching PDF without page number"); + let zp = Zotero.getActiveZoteroPane(); + if (zp) { + zp.viewAttachment([attchment.id]); + } + Zotero.Notifier.trigger("open", "file", attchment.id); successCount += 1; } catch (e) { Zotero.debug("Knowledge4Zotero: Open attachment failed:"); @@ -492,15 +496,21 @@ class AddonEvents extends AddonBase { } else if (message.type === "addAnnotationNote") { /* message.content = { - params: annotations of Reader JSON type + params: { annotations: Reader JSON type, annotationItem } } */ - const annotations = message.content.params; + const annotations = message.content.params.annotations; + const annotationItem: ZoteroItem = message.content.params.annotationItem; const note: ZoteroItem = new Zotero.Item("note"); note.parentID = Zotero.Items.get( annotations[0].attachmentItemID ).parentID; + if (annotationItem.annotationComment) { + note.setNote( + ` ` + ); + } await note.saveTx(); ZoteroPane.openNoteWindow(note.id); let t = 0; @@ -518,9 +528,8 @@ class AddonEvents extends AddonBase { await Zotero.Promise.delay(10); } const editorInstance = noteEditor.getCurrentInstance(); - Zotero.debug(editorInstance); editorInstance.focus(); - editorInstance.insertAnnotations(annotations); + await editorInstance.insertAnnotations(annotations); } else { Zotero.debug(`Knowledge4Zotero: message not handled.`); } diff --git a/src/knowledge.ts b/src/knowledge.ts index a0902c4..e0e376b 100644 --- a/src/knowledge.ts +++ b/src/knowledge.ts @@ -143,10 +143,17 @@ class Knowledge extends AddonBase { } let noteText: string = note.getNote(); let containerIndex = noteText.search(/data-schema-version="8">/g); - let noteHead = noteText.substring(0, containerIndex); - note.setNote( - `${noteHead}data-schema-version="8">${noteLines.join("\n")}` - ); + if (containerIndex === -1) { + note.setNote( + `${annotationItem.annotationComment}
\n${noteLines.join("\n")}` + ); + } else { + let noteHead = noteText.substring(0, containerIndex); + note.setNote( + `${noteHead}data-schema-version="8">${noteLines.join("\n")}` + ); + } + note.saveTx(); } @@ -401,6 +408,9 @@ class Knowledge extends AddonBase { lineIndex: -1, endIndex: -1, }); + if (!metadataContainer) { + return root; + } let id = 0; let currentNode = root; let lastNode = undefined; diff --git a/src/views.ts b/src/views.ts index ebafeb9..c5e2fac 100644 --- a/src/views.ts +++ b/src/views.ts @@ -16,7 +16,7 @@ class AddonViews extends AddonBase { addToKnowledge: ``, notMainKnowledge: ``, isMainKnowledge: ``, - jumpAttachment: ``, + openAttachment: ``, addAnnotationNote: ``, export: ``, close: ``, @@ -167,6 +167,22 @@ class AddonViews extends AddonBase { editor.parentNode.scrollTo(0, editor.children[lineIndex].offsetTop); } + addNewKnowledgeButton() { + // Top toolbar button + let addNoteButton = document.getElementById("zotero-tb-note-add"); + let button = document.createElement("toolbarbutton"); + button.setAttribute("id", "zotero-tb-knowledge-openwindow"); + button.setAttribute("tooltiptext", "Create new Knowledge Workspace"); + button.addEventListener("click", (e) => { + this._Addon.events.onEditorEvent(new EditorMessage("createWorkspace", {})); + }); + button.setAttribute( + "style", + "list-style-image: url('chrome://Knowledge4Zotero/skin/knowledge.png');" + ); + addNoteButton.after(button); + } + addOpenWorkspaceButton() { // Left collection tree view button const treeRow = document.createElement("html:div"); @@ -184,7 +200,7 @@ class AddonViews extends AddonBase { span3.setAttribute("class", "icon icon-bg cell-icon"); span3.setAttribute( "style", - "background-image:url(chrome://Knowledge4Zotero/skin/favicon.png)" + "background-image:url(chrome://Knowledge4Zotero/skin/knowledge.png)" ); const span4 = document.createElement("span"); span4.setAttribute("class", "cell-text"); @@ -225,7 +241,7 @@ class AddonViews extends AddonBase { continue; } moreButton.setAttribute("knowledgeinit", "true"); - const addAnnotationNoteButton = _document.createElement("button"); + const addAnnotationNoteButton = _document.createElement("div"); addAnnotationNoteButton.innerHTML = this.editorIcon["addAnnotationNote"]; let annotationWrapper = moreButton; @@ -272,7 +288,7 @@ class AddonViews extends AddonBase { return { id, type, - attachmentItemID: Zotero.Reader._readers[0].itemID, + attachmentItemID: reader.itemID, text: text ? text.trim() : text, color, comment: comment ? comment.trim() : comment, @@ -286,7 +302,10 @@ class AddonViews extends AddonBase { addAnnotationNoteButton.addEventListener("click", (e) => { this._Addon.events.onEditorEvent( new EditorMessage("addAnnotationNote", { - params: annotations, + params: { + annotations: annotations, + annotationItem: annotationItem, + }, }) ); e.preventDefault(); @@ -349,14 +368,19 @@ class AddonViews extends AddonBase { }); this.$("#outline-addafter").dxButton({ icon: "plus", - hint: "Add Heading after the selected Heading's section", onClick: (e) => { - if (this._Addon.knowledge.currentNodeID < 0) { - return; - } - const text = prompt("Enter new Heading:"); + const text = prompt("Enter new heading:"); this._Addon.knowledge.openWorkspaceWindow(); if (text.trim()) { + if (this._Addon.knowledge.currentNodeID < 0) { + // Add a new H1 + this._Addon.knowledge.addSubLineToNote( + undefined, + `${text}
`, + -1 + ); + return; + } let node = this._Addon.knowledge.getNoteTreeNodeById( undefined, this._Addon.knowledge.currentNodeID @@ -371,9 +395,9 @@ class AddonViews extends AddonBase { }); this.$("#outline-tab").dxButton({ icon: "increaseindent", - hint: "Raise the selected Heading level", onClick: (e) => { if (this._Addon.knowledge.currentNodeID < 0) { + this.showProgressWindow("Knowledge", "Please select a Heading."); return; } let node = this._Addon.knowledge.getNoteTreeNodeById( @@ -389,9 +413,9 @@ class AddonViews extends AddonBase { }); this.$("#outline-untab").dxButton({ icon: "decreaseindent", - hint: "Decrease the selected Heading level", onClick: (e) => { if (this._Addon.knowledge.currentNodeID < 0) { + this.showProgressWindow("Knowledge", "Please select a Heading."); return; } let node = this._Addon.knowledge.getNoteTreeNodeById( diff --git a/typing/global.d.ts b/typing/global.d.ts index 03ac687..b8c32d0 100644 --- a/typing/global.d.ts +++ b/typing/global.d.ts @@ -87,7 +87,8 @@ declare interface ZoteroItem { setNote: (string) => void; getNoteTitle: () => string; isAttachment: () => boolean; - isAnnotation?: () => boolean; + isAnnotation: () => boolean; + isPDFAttachment: () => boolean; itemTypeID: number; libraryID: number; parentID: number; @@ -145,6 +146,10 @@ declare const ZoteroPane: { getSelectedItems: () => Array; }; +declare const ZoteroPane_Local: { + newNote: () => Promise ; +}; + declare class ZoteroCollection { getChildItems: (arg1: boolean, arg2: boolean) => Array ; }