From 307701788ff0abe314dfe57e4428c5b2f4c4ded6 Mon Sep 17 00:00:00 2001 From: Martynas Bagdonas Date: Fri, 27 May 2022 13:19:52 +0300 Subject: [PATCH] fx-compat: Fix and extract notesBox into a separate element --- chrome/content/zotero/elements/notesBox.js | 180 +++++++++++++++++++++ chrome/content/zotero/itemPane.js | 102 ++---------- chrome/content/zotero/zoteroPane.xhtml | 17 +- scss/_notesBox.scss | 2 + scss/components/_notesBox.scss | 42 +++++ scss/notesBox-mac.scss | 1 + scss/notesBox-unix.scss | 1 + scss/notesBox-win.scss | 1 + 8 files changed, 240 insertions(+), 106 deletions(-) create mode 100644 chrome/content/zotero/elements/notesBox.js create mode 100644 scss/_notesBox.scss create mode 100644 scss/components/_notesBox.scss create mode 100644 scss/notesBox-mac.scss create mode 100644 scss/notesBox-unix.scss create mode 100644 scss/notesBox-win.scss diff --git a/chrome/content/zotero/elements/notesBox.js b/chrome/content/zotero/elements/notesBox.js new file mode 100644 index 0000000000..11a0055e6d --- /dev/null +++ b/chrome/content/zotero/elements/notesBox.js @@ -0,0 +1,180 @@ +/* + ***** BEGIN LICENSE BLOCK ***** + + Copyright © 2021 Corporation for Digital Scholarship + Vienna, Virginia, USA + https://www.zotero.org + + This file is part of Zotero. + + Zotero is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Zotero is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with Zotero. If not, see . + + ***** END LICENSE BLOCK ***** +*/ + +"use strict"; + +{ + class NotesBox extends XULElement { + constructor() { + super(); + + this._mode = 'view'; + this._item = null; + this._destroyed = false; + this._noteIDs = []; + + this.content = MozXULElement.parseXULToFragment(` + +
+
+
+
+
+ + `, ['chrome://zotero/locale/zotero.dtd']); + } + + connectedCallback() { + this._destroyed = false; + window.addEventListener("unload", this.destroy); + + let shadow = this.attachShadow({ mode: "open" }); + + let s1 = document.createElement("link"); + s1.rel = "stylesheet"; + s1.href = "chrome://zotero-platform/content/notesBox.css"; + shadow.append(s1); + + let content = document.importNode(this.content, true); + shadow.append(content); + + this._id('add').addEventListener('click', this._handleAdd); + + this._notifierID = Zotero.Notifier.registerObserver(this, ['item'], 'notesBox'); + } + + destroy() { + if (this._destroyed) { + return; + } + window.removeEventListener("unload", this.destroy); + this._destroyed = true; + + Zotero.Notifier.unregisterObserver(this._notifierID); + } + + disconnectedCallback() { + this.replaceChildren(); + this.destroy(); + } + + get mode() { + return this._mode; + } + + set mode(val) { + switch (val) { + case 'view': + case 'merge': + case 'mergeedit': + case 'edit': + break; + + default: + throw new Error(`Invalid mode '${val}'`); + } + + this._mode = val; + } + + get item() { + return this._item; + } + + set item(val) { + this._item = val; + this._refresh(); + } + + notify(event, type, ids, extraData) { + if (['modify', 'delete'].includes(event) && ids.some(id => this._noteIDs.includes(id))) { + this._refresh(); + } + } + + _refresh() { + if (!this._item) { + return; + } + + this._noteIDs = this._item.getNotes(); + this._id('add').hidden = this._mode != 'edit'; + + let grid = this._id('grid'); + grid.replaceChildren(); + + let notes = Zotero.Items.get(this._item.getNotes()); + for (let item of notes) { + let id = item.id; + let icon = document.createElement("img"); + icon.src = item.getImageSrc(); + + let label = document.createElement("label"); + label.append(item.getDisplayTitle()); + + let box = document.createElement('div'); + box.addEventListener('click', () => this._handleShowItem(id)); + box.className = 'box zotero-clicky'; + box.appendChild(icon); + box.appendChild(label); + + grid.append(box); + + if (this._mode == 'edit') { + let remove = document.createElement("label"); + remove.addEventListener('click', () => this._handleRemove(id)); + remove.className = 'zotero-clicky zotero-clicky-minus'; + remove.append('-'); + grid.append(remove); + } + } + + let num = this._noteIDs.length; + this._id('num').replaceChildren(Zotero.getString('pane.item.notes.count', num, num)); + } + + _handleAdd = (event) => { + ZoteroPane_Local.newNote(event.shiftKey, this._item.key); + }; + + _handleRemove(id) { + var ps = Services.prompt; + if (ps.confirm(null, '', Zotero.getString('pane.item.notes.delete.confirm'))) { + Zotero.Items.trashTx(id); + } + } + + _handleShowItem(id) { + ZoteroPane_Local.selectItem(id); + } + + _id(id) { + return this.shadowRoot.querySelector(`[id=${id}]`); + } + } + customElements.define("notes-box", NotesBox); +} diff --git a/chrome/content/zotero/itemPane.js b/chrome/content/zotero/itemPane.js index 504ca23e36..295e488ed4 100644 --- a/chrome/content/zotero/itemPane.js +++ b/chrome/content/zotero/itemPane.js @@ -28,11 +28,10 @@ import ReactDOM from 'react-dom'; import TagsBoxContainer from 'containers/tagsBoxContainer'; var ZoteroItemPane = new function() { - var _lastItem, _itemBox, _notesLabel, _notesButton, _notesList, _tagsBox, _relatedBox; + var _lastItem, _itemBox, _tagsBox, _notesBox, _relatedBox; var _selectedNoteID; var _translationTarget; - var _noteIDs; - + this.onLoad = function () { if (!Zotero) { return; @@ -44,16 +43,14 @@ var ZoteroItemPane = new function() { if (!document.getElementById('zotero-view-tabbox')) { return; } - - _notesLabel = document.getElementById('zotero-editpane-notes-label'); - _notesButton = document.getElementById('zotero-editpane-notes-add'); - _notesList = document.getElementById('zotero-editpane-dynamic-notes'); + // Fake a ref _tagsBox = { current: null }; + _notesBox = document.getElementById('zotero-editpane-notes'); _relatedBox = document.getElementById('zotero-editpane-related'); - + this._unregisterID = Zotero.Notifier.registerObserver(this, ['item'], 'itemPane'); } @@ -84,6 +81,11 @@ var ZoteroItemPane = new function() { break; } + case 1: + var box = _notesBox; + box.parentItem = item; + break; + case 3: var box = _relatedBox; break; @@ -134,60 +136,6 @@ var ZoteroItemPane = new function() { this.setTranslateButton(); } } - else if (index == 1) { - var editable = ZoteroPane_Local.canEdit(); - _notesButton.hidden = !editable; - - while(_notesList.hasChildNodes()) { - _notesList.removeChild(_notesList.firstChild); - } - - _noteIDs = new Set(); - let notes = yield Zotero.Items.getAsync(item.getNotes()); - if (notes.length) { - for (var i = 0; i < notes.length; i++) { - let note = notes[i]; - let id = notes[i].id; - - var icon = document.createElement('image'); - icon.className = "zotero-box-icon"; - icon.setAttribute('src', `chrome://zotero/skin/treeitem-note${Zotero.hiDPISuffix}.png`); - - var label = document.createElement('label'); - label.className = "zotero-box-label"; - var title = note.getNoteTitle(); - title = title ? title : Zotero.getString('pane.item.notes.untitled'); - label.setAttribute('value', title); - label.setAttribute('flex','1'); //so that the long names will flex smaller - label.setAttribute('crop','end'); - - var box = document.createElement('box'); - box.setAttribute('class','zotero-clicky'); - box.addEventListener('click', function () { ZoteroPane_Local.selectItem(id); }); - box.appendChild(icon); - box.appendChild(label); - - if (editable) { - var removeButton = document.createElement('label'); - removeButton.setAttribute("value","-"); - removeButton.setAttribute("class","zotero-clicky zotero-clicky-minus"); - removeButton.addEventListener('click', function () { ZoteroItemPane.removeNote(id); }); - } - - var row = document.createElement('row'); - row.appendChild(box); - if (editable) { - row.appendChild(removeButton); - } - - _notesList.appendChild(row); - _noteIDs.add(id); - } - } - - _updateNoteCount(); - return; - } else if (index == 2) { ReactDOM.render( _noteIDs.has(id))) { - refresh = true; - } - if (refresh) { - yield this.viewItem(_lastItem, null, 1); - } - } if (viewBox.selectedIndex == 0 && action == 'refresh' && _lastItem) { yield this.viewItem(_lastItem, null, 0); } @@ -290,20 +228,6 @@ var ZoteroItemPane = new function() { }; - this.addNote = function (popup) { - ZoteroPane_Local.newNote(popup, _lastItem.key); - } - - - this.removeNote = function (id) { - var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] - .getService(Components.interfaces.nsIPromptService); - if (ps.confirm(null, '', Zotero.getString('pane.item.notes.delete.confirm'))) { - Zotero.Items.trashTx(id); - } - } - - this.onTagsContextPopupShowing = function () { if (!_lastItem.isEditable()) { return false; @@ -414,12 +338,6 @@ var ZoteroItemPane = new function() { var tooltip = label + (Zotero.rtl ? ' \u202B' : ' ') + '(' + key + ')' elem.setAttribute('tooltiptext', tooltip); }; - - - function _updateNoteCount() { - var c = _notesList.childNodes.length; - _notesLabel.value = Zotero.getString('pane.item.notes.count', c, c); - } } addEventListener("load", function(e) { ZoteroItemPane.onLoad(e); }, false); diff --git a/chrome/content/zotero/zoteroPane.xhtml b/chrome/content/zotero/zoteroPane.xhtml index 0b15243c81..c8aa25258b 100644 --- a/chrome/content/zotero/zoteroPane.xhtml +++ b/chrome/content/zotero/zoteroPane.xhtml @@ -79,6 +79,7 @@ Services.scriptloader.loadSubScript("chrome://zotero/content/elements/menulistItemTypes.js", this); Services.scriptloader.loadSubScript("chrome://zotero/content/elements/itemBox.js", this); Services.scriptloader.loadSubScript("chrome://zotero/content/elements/noteEditor.js", this); + Services.scriptloader.loadSubScript("chrome://zotero/content/elements/notesBox.js", this); Services.scriptloader.loadSubScript("chrome://zotero/content/elements/relatedBox.js", this); Services.scriptloader.loadSubScript("chrome://zotero/content/tabs.js", this); @@ -1117,20 +1118,8 @@ - - - -