diff --git a/chrome/content/zotero/bindings/noteeditor.xml b/chrome/content/zotero/bindings/noteeditor.xml
index 451ca0a144..24dde52693 100644
--- a/chrome/content/zotero/bindings/noteeditor.xml
+++ b/chrome/content/zotero/bindings/noteeditor.xml
@@ -274,6 +274,7 @@
}
this.initEditor();
+ this._id('links-box').item = this._item;
})();
]]>
@@ -392,6 +393,15 @@
this.id('tags').item = this.item;
this.id('related').item = this.item;
this.refresh();
+
+ // Hide popup to prevent it being visible out of the context or
+ // in some cases even invisible but still blocking the next click
+ this.id('relatedPopup').addEventListener('click', (event) => {
+ let target = event.originalTarget;
+ if (target.classList.contains('zotero-box-label')) {
+ this.id('relatedPopup').hidePopup();
+ }
+ });
]]>
@@ -568,7 +578,7 @@
diff --git a/chrome/content/zotero/bindings/relatedbox.xml b/chrome/content/zotero/bindings/relatedbox.xml
index 46ab5b75a9..a58399d35f 100644
--- a/chrome/content/zotero/bindings/relatedbox.xml
+++ b/chrome/content/zotero/bindings/relatedbox.xml
@@ -116,14 +116,25 @@
Zotero.Items.getIDFromLibraryAndKey(libraryID, key)));
+ for (let id of ids) {
+ if (relatedItemIDs.has(id)) {
+ this.refresh();
+ return;
+ }
+ }
}
]]>
diff --git a/chrome/content/zotero/contextPane.js b/chrome/content/zotero/contextPane.js
index 7958ee9617..1fbfd80431 100644
--- a/chrome/content/zotero/contextPane.js
+++ b/chrome/content/zotero/contextPane.js
@@ -238,19 +238,7 @@ var ZoteroContextPane = new function () {
}
if (splitter.getAttribute('state') != 'collapsed') {
- if (_panesDeck.selectedIndex == 0) {
- let child = _itemPaneDeck.selectedPanel;
- if (child) {
- var tabPanels = child.querySelector('tabpanels');
- if (tabPanels && tabPanels.selectedIndex == 1) {
- var notesDeck = child.querySelector('.notes-deck');
- if (notesDeck.selectedIndex == 1) {
- return child.querySelector('zoteronoteeditor');
- }
- }
- }
- }
- else {
+ if (_panesDeck.selectedIndex == 1) {
var node = _notesPaneDeck.selectedPanel;
if (node.selectedIndex == 1) {
return node.querySelector('zoteronoteeditor');
@@ -702,7 +690,6 @@ var ZoteroContextPane = new function () {
editor.mode = readOnly ? 'view' : 'edit';
editor.item = item;
editor.parentItem = null;
- editor.hideLinksContainer = true;
node.querySelector('.zotero-context-pane-editor-parent-line').innerHTML = '';
var parentItem = item.parentItem;
@@ -772,17 +759,90 @@ var ZoteroContextPane = new function () {
return;
}
var parentItem = Zotero.Items.get(item.parentID);
+
+ // Dynamically create item pane tabs and panels as in itemPane.xul.
+ // Keep the code below in sync with itemPane.xul
- // Info pane
- var panelInfo = document.createElement('vbox');
+ // tabbox
+ var tabbox = document.createElement('tabbox');
+ tabbox.setAttribute('flex', '1');
+ tabbox.className = 'zotero-view-tabbox';
+
+ container.append(tabbox);
+
+ // tabs
+ var tabs = document.createElement('tabs');
+ tabs.className = 'zotero-editpane-tabs';
+ // tabpanels
+ var tabpanels = document.createElement('tabpanels');
+ tabpanels.setAttribute('flex', '1');
+ tabpanels.className = 'zotero-view-item';
+ tabpanels.addEventListener('select', () => {
+ _updateAddToNote();
+ });
+
+ tabbox.append(tabs, tabpanels);
+
+ // Info tab
+ var tabInfo = document.createElement('tab');
+ tabInfo.setAttribute('label', Zotero.Intl.strings['zotero.tabs.info.label']);
+ // Tags tab
+ var tabTags = document.createElement('tab');
+ tabTags.setAttribute('label', Zotero.Intl.strings['zotero.tabs.tags.label']);
+ // Related tab
+ var tabRelated = document.createElement('tab');
+ tabRelated.setAttribute('label', Zotero.Intl.strings['zotero.tabs.related.label']);
+
+ tabs.append(tabInfo, tabTags, tabRelated);
+
+ // Info panel
+ var panelInfo = document.createElement('tabpanel');
panelInfo.setAttribute('flex', '1');
panelInfo.className = 'zotero-editpane-item-box';
var itemBox = document.createElement('zoteroitembox');
itemBox.setAttribute('flex', '1');
panelInfo.append(itemBox);
- container.append(panelInfo);
+ // Tags panel
+ var panelTags = document.createElement('tabpanel');
+ panelTags.setAttribute('orient', 'vertical');
+ panelTags.setAttribute('context', 'tags-context-menu');
+ panelTags.className = 'tags-pane';
+ panelTags.style.display = 'flex';
+ var div = document.createElementNS(HTML_NS, 'div');
+ div.className = 'tags-box-container';
+ div.style.display = 'flex';
+ div.style.flexGrow = '1';
+ panelTags.append(div);
+ var tagsBoxRef = React.createRef();
+ ReactDOM.render(
+ ,
+ div
+ );
+ // Related panel
+ var panelRelated = document.createElement('tabpanel');
+ var relatedBox = document.createElement('relatedbox');
+ relatedBox.setAttribute('flex', '1');
+ relatedBox.className = 'zotero-editpane-related';
+ panelRelated.addEventListener('click', (event) => {
+ if (event.originalTarget.closest('.zotero-clicky')) {
+ Zotero_Tabs.select('zotero-pane');
+ }
+ });
+ panelRelated.append(relatedBox);
+
+ tabpanels.append(panelInfo, panelTags, panelRelated);
+ tabbox.selectedIndex = 0;
+
itemBox.mode = readOnly ? 'view' : 'edit';
itemBox.item = parentItem;
+
+ relatedBox.mode = readOnly ? 'view' : 'edit';
+ relatedBox.item = parentItem;
}
};
diff --git a/chrome/content/zotero/itemPane.xul b/chrome/content/zotero/itemPane.xul
index 35563fafa6..f0201db1c7 100644
--- a/chrome/content/zotero/itemPane.xul
+++ b/chrome/content/zotero/itemPane.xul
@@ -69,6 +69,10 @@
+
diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js
index d2b7aaa2ad..36ae95098f 100644
--- a/chrome/content/zotero/zoteroPane.js
+++ b/chrome/content/zotero/zoteroPane.js
@@ -2205,6 +2205,8 @@ var ZoteroPane = new function()
if (found) {
document.getElementById('zotero-items-tree').focus();
}
+
+ Zotero_Tabs.select('zotero-pane');
};
diff --git a/scss/components/_tagsBox.scss b/scss/components/_tagsBox.scss
index be79367f72..b377f46ab3 100644
--- a/scss/components/_tagsBox.scss
+++ b/scss/components/_tagsBox.scss
@@ -64,7 +64,12 @@
.editable-container {
flex-grow: 1;
margin: 0 2px;
- //width: $item-pane-width - $icon-width - $delete-button-width - ($li-side-margin * 2);
+ // width: $item-pane-width - $icon-width - $delete-button-width - ($li-side-margin * 2);
+
+ // This container shouldn't force any width for its parent,
+ // because tagsBox is used in more places than just item pane,
+ // and it can have smaller width than $item-pane-width
+ width: 0;
}
ul.tags-box-list > li:not(.multiline) .editable-container {
diff --git a/test/tests/relatedboxTest.js b/test/tests/relatedboxTest.js
index 8f89d03d0c..81ee450aa0 100644
--- a/test/tests/relatedboxTest.js
+++ b/test/tests/relatedboxTest.js
@@ -12,6 +12,72 @@ describe("Related Box", function () {
win.close();
})
+ it("should update if a related item is renamed", async function () {
+ var title1 = 'aaaaaa';
+ var title2 = 'bbbbbb';
+ var item1 = await createDataObject('item', { title: title1 });
+ var item2 = await createDataObject('item', { title: title2 });
+ item1.addRelatedItem(item2);
+ await item1.saveTx();
+ item2.addRelatedItem(item1);
+ await item2.saveTx();
+
+ // Select the Related pane
+ var tabbox = doc.getElementById('zotero-view-tabbox');
+ tabbox.selectedIndex = 3;
+ var relatedbox = doc.getElementById('zotero-editpane-related');
+
+ // Wait for relations list to populate
+ do {
+ await Zotero.Promise.delay(50);
+ }
+ while (!relatedbox.id('relatedRows').childNodes.length);
+
+ assert.include(doc.getAnonymousNodes(relatedbox)[0].innerHTML, title1);
+
+ title1 = 'cccccc';
+ item1.setField('title', title1);
+ await item1.saveTx();
+
+ // New title should appear in list
+ do {
+ await Zotero.Promise.delay(50);
+ }
+ while (!doc.getAnonymousNodes(relatedbox)[0].innerHTML.includes(title1));
+ });
+
+ it("should update if a related item is deleted", async function () {
+ var title1 = 'aaaaaa';
+ var title2 = 'bbbbbb';
+ var item1 = await createDataObject('item', { title: title1 });
+ var item2 = await createDataObject('item', { title: title2 });
+ item1.addRelatedItem(item2);
+ await item1.saveTx();
+ item2.addRelatedItem(item1);
+ await item2.saveTx();
+
+ // Select the Related pane
+ var tabbox = doc.getElementById('zotero-view-tabbox');
+ tabbox.selectedIndex = 3;
+ var relatedbox = doc.getElementById('zotero-editpane-related');
+
+ // Wait for relations list to populate
+ do {
+ await Zotero.Promise.delay(50);
+ }
+ while (!relatedbox.id('relatedRows').childNodes.length);
+
+ assert.include(doc.getAnonymousNodes(relatedbox)[0].innerHTML, title1);
+
+ await item1.eraseTx();
+
+ // Deleted item should be removed from list
+ do {
+ await Zotero.Promise.delay(50);
+ }
+ while (doc.getAnonymousNodes(relatedbox)[0].innerHTML.includes(title1));
+ });
+
describe("Add button", function () {
it("should add a related item", function* () {
var item1 = yield createDataObject('item');