Fix citeproc errors due to improper citeproc state updates
The error is triggered upon initial interaction with a doc after Zotero restart or if new external citations (copied into the document) are peresnt and `session.updateSession()` is called without a subsequent `session.updateDocument()` call. `session.updateSession()` is called without a subsequent `session.updateDocument()` call every time the user cancels a citation insert. More specifically, `session.updateSession()` is called every time a citation dialog is invoked. It retrieves all citations and writes them into a local `session.citationsByIndex` object. Moreover, it marks each citation that hasn't seen before in a `session.newIndices` object. `session.newIndices` is there to ensure that we load every new citation into citeproc upon document update. This object is built by marking any citation that does not appear in the previous invocation's list of citations as new. However, if the document is never updated (because the user cancels the insertion) then the new indices are not loaded into citeproc. This commit fixes that, by excluding citeproc unloaded items from the previous invocation's citation list.
This commit is contained in:
parent
ff6a4400b4
commit
78c3d5808b
2 changed files with 44 additions and 10 deletions
|
@ -1381,6 +1381,19 @@ Zotero.Integration.Session.prototype.resetRequest = function(doc) {
|
|||
|
||||
this.bibliographyHasChanged = false;
|
||||
this.bibliographyDataHasChanged = false;
|
||||
|
||||
// When processing citations this list will be checked for citations that are new to the document
|
||||
// (i.e. copied from somewhere else) and marked as newIndices to be processed with citeproc if
|
||||
// not present
|
||||
this.oldCitations = new Set();
|
||||
for (let i in this.citationsByIndex) {
|
||||
// But ignore indices from this.newIndices. If any are present it means that the last
|
||||
// call to this.updateSession() was never followed up with this.updateDocument()
|
||||
// i.e. the operation was user cancelled
|
||||
if (i in this.newIndices) continue;
|
||||
this.oldCitations.add(this.citationsByIndex[i].citationID);
|
||||
}
|
||||
|
||||
// After adding fields to the session
|
||||
// citations that are new to the document will be marked
|
||||
// as new, so that they are correctly loaded into and processed with citeproc
|
||||
|
@ -1390,15 +1403,8 @@ Zotero.Integration.Session.prototype.resetRequest = function(doc) {
|
|||
this.updateIndices = {};
|
||||
// Citations that require updating in the document will be marked in
|
||||
// processIndices
|
||||
|
||||
this.processIndices = {};
|
||||
|
||||
// When processing citations this list will be checked for citations that are new to the document
|
||||
// (i.e. copied from somewhere else) and marked as newIndices to be processed with citeproc if
|
||||
// not present
|
||||
this.oldCitations = new Set();
|
||||
for (let i in this.citationsByIndex) {
|
||||
this.oldCitations.add(this.citationsByIndex[i].citationID);
|
||||
}
|
||||
this.citationsByItemID = {};
|
||||
this.citationsByIndex = {};
|
||||
this.documentCitationIDs = {};
|
||||
|
|
|
@ -138,7 +138,7 @@ describe("Zotero.Integration", function () {
|
|||
/**
|
||||
* Deletes this field and its contents.
|
||||
*/
|
||||
delete: function() {this.doc.fields.filter((field) => field !== this)},
|
||||
delete: function() {this.doc.fields = this.doc.fields.filter((field) => field !== this)},
|
||||
/**
|
||||
* Removes this field, but maintains the field's contents.
|
||||
*/
|
||||
|
@ -268,7 +268,10 @@ describe("Zotero.Integration", function () {
|
|||
item = Zotero.Cite.getItem(item.id);
|
||||
return {id: item.id, uris: item.cslURIs, itemData: item.cslItemData};
|
||||
});
|
||||
await io.previewFn(io.citation);
|
||||
try {
|
||||
await io.previewFn(io.citation);
|
||||
}
|
||||
catch (e) {}
|
||||
io._acceptDeferred.resolve(() => {});
|
||||
};
|
||||
}
|
||||
|
@ -715,6 +718,31 @@ describe("Zotero.Integration", function () {
|
|||
stubUpdateDocument.restore();
|
||||
}
|
||||
});
|
||||
|
||||
it('should successfully insert a citation after canceled citation insert', async function () {
|
||||
var docID = this.test.fullTitle();
|
||||
if (!(docID in applications)) initDoc(docID);
|
||||
var doc = applications[docID].doc;
|
||||
|
||||
setAddEditItems(testItems[0]);
|
||||
await execCommand('addEditCitation', docID);
|
||||
assert.equal(doc.fields.length, 1);
|
||||
doc.fields.push(new DocumentPluginDummy.Field(doc));
|
||||
// Add a "citation copied from somewhere else"
|
||||
// the content doesn't really matter, just make sure that the citationID is different
|
||||
var newCitationID = Zotero.Utilities.randomString();
|
||||
doc.fields[1].code = doc.fields[0].code;
|
||||
doc.fields[1].code = doc.fields[1].code.replace(/"citationID":"[A-Za-z0-9^"]*"/,
|
||||
`"citationID":"${newCitationID}"`);
|
||||
doc.fields[1].text = doc.fields[0].text;
|
||||
|
||||
setAddEditItems([]);
|
||||
await execCommand('addEditCitation', docID);
|
||||
|
||||
setAddEditItems(testItems[1]);
|
||||
await execCommand('addEditCitation', docID);
|
||||
assert.notEqual(doc.fields[2].code, "TEMP");
|
||||
});
|
||||
});
|
||||
|
||||
describe('when delayCitationUpdates is set', function() {
|
||||
|
|
Loading…
Add table
Reference in a new issue