Fix 'id must be a positive integer' integration error

Report: https://forums.zotero.org/discussion/comment/298804#Comment_298804
This commit is contained in:
Adomas Venčkauskas 2018-01-22 13:25:11 +02:00
parent a1b6f072c1
commit 553d2b00d8
2 changed files with 53 additions and 57 deletions

View File

@ -291,9 +291,10 @@ Zotero.Cite = {
* Get an item by ID, either by retrieving it from the library or looking for the document it * Get an item by ID, either by retrieving it from the library or looking for the document it
* belongs to. * belongs to.
* @param {String|Number|Array} id * @param {String|Number|Array} id
* @param {Boolean} [getZoteroItems=false] - whether to get CSL or Zotero items for embedded items
* @return {Zotero.Item} item * @return {Zotero.Item} item
*/ */
"getItem":function getItem(id) { "getItem":function getItem(id, getZoteroItems=false) {
var slashIndex; var slashIndex;
if(id instanceof Array) { if(id instanceof Array) {
@ -303,7 +304,11 @@ Zotero.Cite = {
session = Zotero.Integration.sessions[sessionID], session = Zotero.Integration.sessions[sessionID],
item; item;
if(session) { if(session) {
item = session.embeddedItems[id.substr(slashIndex+1)]; if (getZoteroItems) {
item = session.embeddedZoteroItems[id.substr(slashIndex+1)];
} else {
item = session.embeddedItems[id.substr(slashIndex+1)];
}
} }
if(!item) { if(!item) {
@ -498,7 +503,7 @@ Zotero.Cite.System.prototype = {
/** /**
* citeproc-js system function for getting items * citeproc-js system function for getting items
* See http://gsl-nagoya-u.net/http/pub/citeproc-doc.html#retrieveitem * See http://gsl-nagoya-u.net/http/pub/citeproc-doc.html#retrieveitem
* @param {String|Integer} Item ID, or string item for embedded citations * @param {String|Integer} item - Item ID, or string item for embedded citations
* @return {Object} citeproc-js item * @return {Object} citeproc-js item
*/ */
"retrieveItem":function retrieveItem(item) { "retrieveItem":function retrieveItem(item) {
@ -509,10 +514,10 @@ Zotero.Cite.System.prototype = {
} else if(typeof item === "string" && (slashIndex = item.indexOf("/")) !== -1) { } else if(typeof item === "string" && (slashIndex = item.indexOf("/")) !== -1) {
// is an embedded item // is an embedded item
var sessionID = item.substr(0, slashIndex); var sessionID = item.substr(0, slashIndex);
var session = Zotero.Integration.sessions[sessionID] var session = Zotero.Integration.sessions[sessionID];
if(session) { if(session) {
var embeddedCitation = session.embeddedItems[item.substr(slashIndex+1)]; var embeddedCitation = session.embeddedItems[item.substr(slashIndex+1)];
if(embeddedCitation) { if (embeddedCitation) {
embeddedCitation.id = item; embeddedCitation.id = item;
return embeddedCitation; return embeddedCitation;
} }

View File

@ -888,7 +888,7 @@ Zotero.Integration.Fields.prototype._processFields = Zotero.Promise.coroutine(fu
let field = Zotero.Integration.Field.loadExisting(this._fields[i]); let field = Zotero.Integration.Field.loadExisting(this._fields[i]);
if (field.type === INTEGRATION_TYPE_ITEM) { if (field.type === INTEGRATION_TYPE_ITEM) {
var noteIndex = field.getNoteIndex(), var noteIndex = field.getNoteIndex(),
citation = new Zotero.Integration.Citation(field); citation = new Zotero.Integration.Citation(field, noteIndex);
let action = yield citation.loadItemData(); let action = yield citation.loadItemData();
@ -1130,35 +1130,31 @@ Zotero.Integration.Fields.prototype.addEditCitation = Zotero.Promise.coroutine(f
// ------------------- // -------------------
// Preparing stuff to pass into CitationEditInterface // Preparing stuff to pass into CitationEditInterface
var fieldIndexPromise = this.get().then(function(fields) { var fields = yield this.get();
for (var i=0, n=fields.length; i<n; i++) { for (var fieldIndex = 0; fieldIndex < fields.length; fieldIndex++) {
if (fields[i].equals(field._field)) { if (fields[fieldIndex].equals(field._field)) {
// This is needed, because LibreOffice integration plugin caches the field code instead of asking // This is needed, because LibreOffice integration plugin caches the field code instead of asking
// the document every time when calling #getCode(). // the document every time when calling #getCode().
fields[i] = field._field; fields[fieldIndex] = field._field;
return i; break;
}
} }
}); }
var citationsByItemIDPromise; var citationsByItemIDPromise;
if (this._session.data.prefs.delayCitationUpdates) { if (this._session.data.prefs.delayCitationUpdates) {
citationsByItemIDPromise = Zotero.Promise.resolve(this._session.citationsByItemID); citationsByItemIDPromise = Zotero.Promise.resolve(this._session.citationsByItemID);
} else { } else {
citationsByItemIDPromise = fieldIndexPromise.then(function() { citationsByItemIDPromise = this.updateSession(FORCE_CITATIONS_FALSE).then(function() {
return this.updateSession(FORCE_CITATIONS_FALSE);
}.bind(this)).then(function() {
return this._session.citationsByItemID; return this._session.citationsByItemID;
}.bind(this)); }.bind(this));
} }
var previewFn = Zotero.Promise.coroutine(function* (citation) { var previewFn = Zotero.Promise.coroutine(function* (citation) {
let idx = yield fieldIndexPromise;
yield citationsByItemIDPromise; yield citationsByItemIDPromise;
let citations = this._session.getCiteprocLists(); let citations = this._session.getCiteprocLists();
let citationsPre = citations.slice(0, idx); let citationsPre = citations.slice(0, fieldIndex);
let citationsPost = citations.slice(idx+1); let citationsPost = citations.slice(fieldIndex+1);
try { try {
return this._session.style.previewCitationCluster(citation, citationsPre, citationsPost, "rtf"); return this._session.style.previewCitationCluster(citation, citationsPre, citationsPost, "rtf");
} catch(e) { } catch(e) {
@ -1167,9 +1163,8 @@ Zotero.Integration.Fields.prototype.addEditCitation = Zotero.Promise.coroutine(f
}.bind(this)); }.bind(this));
var io = new Zotero.Integration.CitationEditInterface( var io = new Zotero.Integration.CitationEditInterface(
citation, citation, this._session.style.opt.sort_citations,
this._session.style.opt.sort_citations, fieldIndexPromise, citationsByItemIDPromise, fieldIndex, citationsByItemIDPromise, previewFn
previewFn
); );
if (Zotero.Prefs.get("integration.useClassicAddCitationDialog")) { if (Zotero.Prefs.get("integration.useClassicAddCitationDialog")) {
@ -1190,15 +1185,14 @@ Zotero.Integration.Fields.prototype.addEditCitation = Zotero.Promise.coroutine(f
// Try to delete new field on cancel // Try to delete new field on cancel
if (newField) { if (newField) {
try { try {
field.delete(); yield field.delete();
} catch(e) {} } catch(e) {}
} }
throw new Zotero.Exception.UserCancelled("inserting citation"); throw new Zotero.Exception.UserCancelled("inserting citation");
} }
let fieldIndex = yield fieldIndexPromise;
this._session.updateIndices[fieldIndex] = true; this._session.updateIndices[fieldIndex] = true;
// Make sure session updated // Make sure session is updated
yield citationsByItemIDPromise; yield citationsByItemIDPromise;
return [fieldIndex, field, io.citation]; return [fieldIndex, field, io.citation];
}); });
@ -1206,11 +1200,11 @@ Zotero.Integration.Fields.prototype.addEditCitation = Zotero.Promise.coroutine(f
/** /**
* Citation editing functions and propertiesaccessible to quickFormat.js and addCitationDialog.js * Citation editing functions and propertiesaccessible to quickFormat.js and addCitationDialog.js
*/ */
Zotero.Integration.CitationEditInterface = function(citation, sortable, fieldIndexPromise, citationsByItemIDPromise, previewFn) { Zotero.Integration.CitationEditInterface = function(citation, sortable, fieldIndex, citationsByItemIDPromise, previewFn) {
this.citation = citation; this.citation = citation;
this.sortable = sortable; this.sortable = sortable;
this.previewFn = previewFn; this.previewFn = previewFn;
this._fieldIndexPromise = fieldIndexPromise; this._fieldIndex = fieldIndex;
this._citationsByItemIDPromise = citationsByItemIDPromise; this._citationsByItemIDPromise = citationsByItemIDPromise;
// Not available in quickFormat.js if this unspecified // Not available in quickFormat.js if this unspecified
@ -1263,17 +1257,16 @@ Zotero.Integration.CitationEditInterface.prototype = {
}); });
// Sort all previously cited items at top, and all items cited later at bottom // Sort all previously cited items at top, and all items cited later at bottom
var fieldIndex = yield this._fieldIndexPromise;
ids.sort(function(a, b) { ids.sort(function(a, b) {
var indexA = citationsByItemID[a][0].properties.zoteroIndex, var indexA = citationsByItemID[a][0].properties.zoteroIndex,
indexB = citationsByItemID[b][0].properties.zoteroIndex; indexB = citationsByItemID[b][0].properties.zoteroIndex;
if(indexA >= fieldIndex){ if(indexA >= this._fieldIndex){
if(indexB < fieldIndex) return 1; if(indexB < this._fieldIndex) return 1;
return indexA - indexB; return indexA - indexB;
} }
if(indexB > fieldIndex) return -1; if(indexB > this._fieldIndex) return -1;
return indexB - indexA; return indexB - indexA;
}); });
@ -1286,6 +1279,7 @@ Zotero.Integration.CitationEditInterface.prototype = {
*/ */
Zotero.Integration.Session = function(doc, app) { Zotero.Integration.Session = function(doc, app) {
this.embeddedItems = {}; this.embeddedItems = {};
this.embeddedZoteroItems = {};
this.embeddedItemsByURI = {}; this.embeddedItemsByURI = {};
this.resetRequest(doc); this.resetRequest(doc);
this.primaryFieldType = app.primaryFieldType; this.primaryFieldType = app.primaryFieldType;
@ -1646,7 +1640,7 @@ Zotero.Integration.Session.prototype.writeDelayedCitation = Zotero.Promise.corou
Zotero.Integration.Session.prototype.getItems = function() { Zotero.Integration.Session.prototype.getItems = function() {
return Zotero.Cite.getItem(Object.keys(this.citationsByItemID)); return Zotero.Cite.getItem(Object.keys(this.citationsByItemID), true);
} }
@ -1979,7 +1973,7 @@ Zotero.Integration.URIMap.prototype.getZoteroItemForURIs = Zotero.Promise.corout
}); });
Zotero.Integration.Field = class { Zotero.Integration.Field = class {
constructor(field) { constructor(field, rawCode) {
if (field instanceof Zotero.Integration.Field) { if (field instanceof Zotero.Integration.Field) {
throw new Error("Trying to instantiate Integration.Field with Integration.Field, not doc field"); throw new Error("Trying to instantiate Integration.Field with Integration.Field, not doc field");
} }
@ -1990,6 +1984,7 @@ Zotero.Integration.Field = class {
} }
} }
this._field = field; this._field = field;
this._code = rawCode;
this.type = INTEGRATION_TYPE_TEMP; this.type = INTEGRATION_TYPE_TEMP;
} }
@ -2002,15 +1997,18 @@ Zotero.Integration.Field = class {
} else { } else {
this._field.setCode(`TEMP`); this._field.setCode(`TEMP`);
} }
this._code = code;
} }
getCode() { getCode() {
let code = this._field.getCode(); if (!this._code) {
let start = code.indexOf('{'); ths._code = this._field.getCode();
}
let start = this._code.indexOf('{');
if (start == -1) { if (start == -1) {
return '{}'; return '{}';
} }
return code.substring(start, code.lastIndexOf('}')+1); return this._code.substring(start, this._code.lastIndexOf('}')+1);
} }
clearCode() { clearCode() {
@ -2042,37 +2040,29 @@ Zotero.Integration.Field.loadExisting = function(docField) {
var field; var field;
// Already loaded // Already loaded
if (docField instanceof Zotero.Integration.Field) return docField; if (docField instanceof Zotero.Integration.Field) return docField;
let rawCode = docField.getCode(); var rawCode = docField.getCode();
// ITEM/CITATION CSL_ITEM {json: 'data'} // ITEM/CITATION CSL_ITEM {json: 'data'}
for (let type of ["ITEM", "CITATION"]) { for (let type of ["ITEM", "CITATION"]) {
if (rawCode.substr(0, type.length) === type) { if (rawCode.substr(0, type.length) === type) {
field = new Zotero.Integration.CitationField(docField); field = new Zotero.Integration.CitationField(docField, rawCode);
} }
} }
// BIBL {json: 'data'} CSL_BIBLIOGRAPHY // BIBL {json: 'data'} CSL_BIBLIOGRAPHY
if (rawCode.substr(0, 4) === "BIBL") { if (rawCode.substr(0, 4) === "BIBL") {
field = new Zotero.Integration.BibliographyField(docField); field = new Zotero.Integration.BibliographyField(docField, rawCode);
} }
if (!field) { if (!field) {
field = new Zotero.Integration.Field(docField); field = new Zotero.Integration.Field(docField, rawCode);
} }
if (field) {
let start = rawCode.indexOf('{');
if (start != -1) {
field._code = rawCode.substring(start, rawCode.lastIndexOf('}')+1);
} else {
field._code = rawCode.substr(rawCode.indexOf(' ')+1);
}
};
return field; return field;
}; };
Zotero.Integration.CitationField = class extends Zotero.Integration.Field { Zotero.Integration.CitationField = class extends Zotero.Integration.Field {
constructor(field) { constructor(field, rawCode) {
super(field); super(field, rawCode);
this.type = INTEGRATION_TYPE_ITEM; this.type = INTEGRATION_TYPE_ITEM;
} }
@ -2230,8 +2220,8 @@ Zotero.Integration.CitationField = class extends Zotero.Integration.Field {
Zotero.Integration.BibliographyField = class extends Zotero.Integration.Field { Zotero.Integration.BibliographyField = class extends Zotero.Integration.Field {
constructor(field) { constructor(field, rawCode) {
super(field); super(field, rawCode);
this.type = INTEGRATION_TYPE_BIBLIOGRAPHY; this.type = INTEGRATION_TYPE_BIBLIOGRAPHY;
}; };
@ -2261,12 +2251,12 @@ Zotero.Integration.BibliographyField = class extends Zotero.Integration.Field {
}; };
Zotero.Integration.Citation = class { Zotero.Integration.Citation = class {
constructor(citationField) { constructor(citationField, noteIndex) {
let data = citationField.unserialize(); let data = citationField.unserialize();
this.citationID = data.citationID; this.citationID = data.citationID;
this.citationItems = data.citationItems; this.citationItems = data.citationItems;
this.properties = data.properties; this.properties = data.properties;
this.properties.noteIndex = citationField.getNoteIndex(); this.properties.noteIndex = noteIndex;
this._field = citationField; this._field = citationField;
} }
@ -2331,9 +2321,10 @@ Zotero.Integration.Citation = class {
// assign a random string as an item ID // assign a random string as an item ID
var anonymousID = Zotero.randomString(); var anonymousID = Zotero.randomString();
var globalID = itemData.id = citationItem.id = Zotero.Integration.currentSession.data.sessionID+"/"+anonymousID; var globalID = itemData.id = citationItem.id = Zotero.Integration.currentSession.data.sessionID+"/"+anonymousID;
Zotero.Integration.currentSession.embeddedItems[anonymousID] = itemData;
// assign a Zotero item // assign a Zotero item
var surrogateItem = Zotero.Integration.currentSession.embeddedItems[anonymousID] = new Zotero.Item(); var surrogateItem = Zotero.Integration.currentSession.embeddedZoteroItems[anonymousID] = new Zotero.Item();
Zotero.Utilities.itemFromCSLJSON(surrogateItem, itemData); Zotero.Utilities.itemFromCSLJSON(surrogateItem, itemData);
surrogateItem.cslItemID = globalID; surrogateItem.cslItemID = globalID;
surrogateItem.cslURIs = citationItem.uris; surrogateItem.cslURIs = citationItem.uris;