commit ba91a2ea526fa0b1e0594b4b70916f3a282f56a1
parent 82b789e083b227f267ef9e6e6fd971a47bbf7098
Author: Dan Stillman <dstillman@zotero.org>
Date: Wed, 1 Mar 2017 01:35:15 -0500
Fix updating of notes list when child note is changed or moved to trash
Diffstat:
3 files changed, 152 insertions(+), 50 deletions(-)
diff --git a/chrome/content/zotero/itemPane.js b/chrome/content/zotero/itemPane.js
@@ -26,6 +26,7 @@
var ZoteroItemPane = new function() {
var _lastItem, _itemBox, _notesLabel, _notesButton, _notesList, _tagsBox, _relatedBox;
var _translationTarget;
+ var _noteIDs;
this.onLoad = function () {
if (!Zotero) {
@@ -45,9 +46,16 @@ var ZoteroItemPane = new function() {
_notesList = document.getElementById('zotero-editpane-dynamic-notes');
_tagsBox = document.getElementById('zotero-editpane-tags');
_relatedBox = document.getElementById('zotero-editpane-related');
+
+ this._unregisterID = Zotero.Notifier.registerObserver(this, ['item'], 'itemPane');
}
+ this.onUnload = function () {
+ Zotero.Notifier.unregisterObserver(this._unregisterID);
+ },
+
+
/*
* Load a top-level item
*/
@@ -125,6 +133,7 @@ var ZoteroItemPane = new function() {
_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++) {
@@ -163,6 +172,7 @@ var ZoteroItemPane = new function() {
}
_notesList.appendChild(row);
+ _noteIDs.add(id);
}
}
@@ -185,6 +195,21 @@ var ZoteroItemPane = new function() {
});
+ this.notify = Zotero.Promise.coroutine(function* (action, type, ids, extraData) {
+ var viewBox = document.getElementById('zotero-view-item');
+ // If notes pane is selected, refresh it if any of the notes change or are deleted
+ if (viewBox.selectedIndex == 1 && (action == 'modify' || action == 'delete')) {
+ let refresh = false;
+ if (ids.some(id => _noteIDs.has(id))) {
+ refresh = true;
+ }
+ if (refresh) {
+ yield this.viewItem(_lastItem, null, 1);
+ }
+ }
+ });
+
+
this.blurOpenField = Zotero.Promise.coroutine(function* () {
var tabBox = document.getElementById('zotero-view-tabbox');
switch (tabBox.selectedIndex) {
@@ -346,3 +371,4 @@ var ZoteroItemPane = new function() {
}
addEventListener("load", function(e) { ZoteroItemPane.onLoad(e); }, false);
+addEventListener("unload", function(e) { ZoteroItemPane.onUnload(e); }, false);
diff --git a/chrome/content/zotero/xpcom/data/items.js b/chrome/content/zotero/xpcom/data/items.js
@@ -876,6 +876,7 @@ Zotero.Items = function() {
let parentItem = yield Zotero.Items.getAsync(parentItemID);
yield parentItem.reload(['primaryData', 'childItems'], true);
}
+ Zotero.Notifier.queue('modify', 'item', ids);
Zotero.Notifier.queue('trash', 'item', ids);
Array.from(libraryIDs).forEach(libraryID => {
Zotero.Notifier.queue('refresh', 'trash', libraryID);
diff --git a/test/tests/itemPaneTest.js b/test/tests/itemPaneTest.js
@@ -112,6 +112,129 @@ describe("Item pane", function () {
});
})
+
+ describe("Notes pane", function () {
+ it("should refresh on child note change", function* () {
+ var item;
+ var note1;
+ var note2;
+ yield Zotero.DB.executeTransaction(function* () {
+ item = createUnsavedDataObject('item');
+ yield item.save();
+
+ note1 = new Zotero.Item('note');
+ note1.parentID = item.id;
+ note1.setNote('A');
+ yield note1.save();
+
+ note2 = new Zotero.Item('note');
+ note2.parentID = item.id;
+ note2.setNote('B');
+ yield note2.save();
+ });
+
+ var tabs = doc.getElementById('zotero-editpane-tabs');
+ var notesTab = doc.getElementById('zotero-editpane-notes-tab');
+ var noteRows = doc.getElementById('zotero-editpane-dynamic-notes');
+ tabs.selectedItem = notesTab;
+ // Wait for note list to update
+ do {
+ yield Zotero.Promise.delay(1);
+ }
+ while (noteRows.childNodes.length !== 2);
+
+ // Update note text
+ note2.setNote('C');
+ yield note2.saveTx();
+
+ // Wait for note list to update
+ do {
+ yield Zotero.Promise.delay(1);
+ }
+ while (Array.from(noteRows.querySelectorAll('label.zotero-box-label')).every(label => label.value != 'C'));
+ });
+
+ it("should refresh on child note trash", function* () {
+ var item;
+ var note1;
+ var note2;
+ yield Zotero.DB.executeTransaction(function* () {
+ item = createUnsavedDataObject('item');
+ yield item.save();
+
+ note1 = new Zotero.Item('note');
+ note1.parentID = item.id;
+ note1.setNote('A');
+ yield note1.save();
+
+ note2 = new Zotero.Item('note');
+ note2.parentID = item.id;
+ note2.setNote('B');
+ yield note2.save();
+ });
+
+ var tabs = doc.getElementById('zotero-editpane-tabs');
+ var notesTab = doc.getElementById('zotero-editpane-notes-tab');
+ var noteRows = doc.getElementById('zotero-editpane-dynamic-notes');
+ tabs.selectedItem = notesTab;
+ // Wait for note list to update
+ do {
+ yield Zotero.Promise.delay(1);
+ }
+ while (noteRows.childNodes.length !== 2);
+
+ // Click "-" in first note
+ var promise = waitForDialog();
+ noteRows.childNodes[0].lastChild.click();
+ yield promise;
+
+ // Wait for note list to update
+ do {
+ yield Zotero.Promise.delay(1);
+ }
+ while (noteRows.childNodes.length !== 1);
+ });
+
+ it("should refresh on child note delete", function* () {
+ var item;
+ var note1;
+ var note2;
+ yield Zotero.DB.executeTransaction(function* () {
+ item = createUnsavedDataObject('item');
+ yield item.save();
+
+ note1 = new Zotero.Item('note');
+ note1.parentID = item.id;
+ note1.setNote('A');
+ yield note1.save();
+
+ note2 = new Zotero.Item('note');
+ note2.parentID = item.id;
+ note2.setNote('B');
+ yield note2.save();
+ });
+
+ var tabs = doc.getElementById('zotero-editpane-tabs');
+ var notesTab = doc.getElementById('zotero-editpane-notes-tab');
+ var noteRows = doc.getElementById('zotero-editpane-dynamic-notes');
+ tabs.selectedItem = notesTab;
+ // Wait for note list to update
+ do {
+ yield Zotero.Promise.delay(1);
+ }
+ while (noteRows.childNodes.length !== 2);
+
+ yield note2.eraseTx();
+
+ // Wait for note list to update
+ do {
+ yield Zotero.Promise.delay(1);
+ }
+ while (noteRows.childNodes.length !== 1);
+ });
+ });
+
+
describe("Attachment pane", function () {
it("should refresh on file rename", function* () {
var file = getTestDataDirectory();
@@ -128,7 +251,8 @@ describe("Item pane", function () {
})
})
- describe("Note pane", function () {
+
+ describe("Note editor", function () {
it("should refresh on note update", function* () {
var item = new Zotero.Item('note');
var id = yield item.saveTx();
@@ -151,55 +275,6 @@ describe("Item pane", function () {
assert.equal(noteBox.noteField.value, '<p>Test</p>');
})
-
- it("should refresh on note trash", function* () {
- var item = yield createDataObject('item');
-
- var note = new Zotero.Item('note');
- note.parentItemID = item.id;
- yield note.saveTx();
- yield itemsView.selectItem(note.id);
-
- // Wait for the note editor, just to be polite
- var noteBox = doc.getElementById('zotero-note-editor');
- var val = false;
- do {
- try {
- val = noteBox.noteField.value;
- }
- catch (e) {}
- yield Zotero.Promise.delay(1);
- }
- while (val === false)
-
- // Select parent and make sure there's 1 note
- yield itemsView.selectItem(item.id);
- var tabs = doc.getElementById('zotero-editpane-tabs');
- var infoTab = doc.getElementById('zotero-editpane-info-tab');
- var notesTab = doc.getElementById('zotero-editpane-notes-tab');
- var notesList = doc.getElementById('zotero-editpane-dynamic-notes');
- tabs.selectedItem = notesTab;
- // Wait for note list to update
- do {
- yield Zotero.Promise.delay(1);
- }
- while (notesList.childNodes.length !== 1);
- tabs.selectedItem = infoTab;
-
- // Select child and trash it
- yield itemsView.selectItem(note.id);
- yield Zotero.Items.trashTx([note.id]);
-
- // Select parent and select notes pane
- yield itemsView.selectItem(item.id);
- tabs.selectedItem = notesTab;
- // Wait for note list to update
- var len = false;
- do {
- yield Zotero.Promise.delay(1);
- }
- while (notesList.childNodes.length !== 0);
- })
})
describe("Feed buttons", function() {