From f44d563a152f3837a2da2a231d3c1a71b83446f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adomas=20Ven=C4=8Dkauskas?= Date: Thu, 25 May 2017 10:48:43 +0300 Subject: [PATCH] Add Zotero.Integration.Citation - Moves a bunch of citation related processing from Integration.Session - Replaces missing item handling with a function instead of exception - Solves some really confusing flow issues in _processFields --- chrome/content/zotero/xpcom/cite.js | 2 +- chrome/content/zotero/xpcom/integration.js | 732 +++++++++------------ test/tests/integrationTest.js | 17 +- 3 files changed, 329 insertions(+), 422 deletions(-) diff --git a/chrome/content/zotero/xpcom/cite.js b/chrome/content/zotero/xpcom/cite.js index b4ded1b303..1c575d510b 100644 --- a/chrome/content/zotero/xpcom/cite.js +++ b/chrome/content/zotero/xpcom/cite.js @@ -526,7 +526,7 @@ Zotero.Cite.System.prototype = { } if(!zoteroItem) { - throw "Zotero.Cite.System.retrieveItem called on non-item "+item; + throw new Error("Zotero.Cite.System.retrieveItem called on non-item "+item); } var cslItem = Zotero.Utilities.itemToCSLJSON(zoteroItem); diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js index 65ef1ee048..217be0a1e5 100644 --- a/chrome/content/zotero/xpcom/integration.js +++ b/chrome/content/zotero/xpcom/integration.js @@ -305,8 +305,8 @@ Zotero.Integration = new function() { * @param {String} [io] Data to pass to the window * @return {Promise} Promise resolved when the window is closed */ - this.displayDialog = function displayDialog(doc, url, options, io) { - doc.cleanup(); + this.displayDialog = function displayDialog(url, options, io) { + Zotero.Integration.currentDoc.cleanup(); var allOptions = 'chrome,centerscreen'; // without this, Firefox gets raised with our windows under Compiz @@ -442,66 +442,13 @@ Zotero.Integration = new function() { /** * An exception thrown when a document contains an item that no longer exists in the current document. - * - * @param reselectKeys {Array} Keys representing the missing item - * @param reselectKeyType {Integer} The type of the keys (see RESELECT_KEY_* constants) - * @param citationIndex {Integer} The index of the missing item within the citation cluster - * @param citationLength {Integer} The number of items cited in this citation cluster */ -Zotero.Integration.MissingItemException = function(reselectKeys, reselectKeyType, citationIndex, citationLength) { - this.reselectKeys = reselectKeys; - this.reselectKeyType = reselectKeyType; - this.citationIndex = citationIndex; - this.citationLength = citationLength; -} +Zotero.Integration.MissingItemException = function() {}; Zotero.Integration.MissingItemException.prototype = { "name":"MissingItemException", "message":"An item in this document is missing from your Zotero library.", - "toString":function() { return this.message }, - "setContext":function(fieldGetter, fieldIndex) { - this.fieldGetter = fieldGetter; - this.fieldIndex = fieldIndex; - }, - - "attemptToResolve":function() { - Zotero.logError(this); - if(!this.fieldGetter) { - throw new Error("Could not resolve "+this.name+": setContext not called"); - } - - // Ask user what to do with this item - if(this.citationLength == 1) { - var msg = Zotero.getString("integration.missingItem.single"); - } else { - var msg = Zotero.getString("integration.missingItem.multiple", (this.citationIndex+1).toString()); - } - msg += '\n\n'+Zotero.getString('integration.missingItem.description'); - this.fieldGetter._fields[this.fieldIndex].select(); - this.fieldGetter._doc.activate(); - var result = this.fieldGetter._doc.displayAlert(msg, 1, 3); - if(result == 0) { // Cancel - return Zotero.Promise.reject(new Zotero.Exception.UserCancelled("document update")); - } else if(result == 1) { // No - for (let reselectKey of this.reselectKeys) { - this.fieldGetter._removeCodeKeys[reselectKey] = true; - } - this.fieldGetter._removeCodeFields[this.fieldIndex] = true; - return this.fieldGetter._processFields(this.fieldIndex+1); - } else { // Yes - // Display reselect item dialog - var fieldGetter = this.fieldGetter, - fieldIndex = this.fieldIndex, - oldCurrentWindow = Zotero.Integration.currentWindow; - return fieldGetter._session.reselectItem(fieldGetter._doc, this) - .then(function() { - // Now try again - Zotero.Integration.currentWindow = oldCurrentWindow; - fieldGetter._doc.activate(); - return fieldGetter._processFields(fieldIndex); - }); - } - } -} + "toString":function() { return this.message } +}; Zotero.Integration.CorruptFieldException = function(code, cause) { this.code = code; @@ -697,26 +644,23 @@ Zotero.Integration.Interface.prototype.addEditCitation = function() { * Adds a bibliography to the current document. * @return {Promise} */ -Zotero.Integration.Interface.prototype.addBibliography = function() { +Zotero.Integration.Interface.prototype.addBibliography = Zotero.Promise.coroutine(function* () { var me = this; - return this._prepareData(true, false).then(function() { - // Make sure we can have a bibliography - if(!me._session.data.style.hasBibliography) { - throw new Zotero.Exception.Alert("integration.error.noBibliography", [], - "integration.error.title"); - } - - var fieldGetter = new Zotero.Integration.Fields(me._session, me._doc, Zotero.Integration.onFieldError); - return fieldGetter.addField().then(function(field) { - field.clearCode(); - field.type = INTEGRATION_TYPE_BIBLIOGRAPHY; - field.writeToDoc(); - return fieldGetter.updateSession().then(function() { - return fieldGetter.updateDocument(FORCE_CITATIONS_FALSE, true, false); - }); - }); - }); -} + yield this._prepareData(true, false); + // Make sure we can have a bibliography + if(!me._session.data.style.hasBibliography) { + throw new Zotero.Exception.Alert("integration.error.noBibliography", [], + "integration.error.title"); + } + + var fieldGetter = new Zotero.Integration.Fields(me._session, me._doc, Zotero.Integration.onFieldError); + let field = new Zotero.Integration.BibliographyField(yield fieldGetter.addField()); + field.clearCode(); + field.type = INTEGRATION_TYPE_BIBLIOGRAPHY; + field.writeToDoc(); + yield fieldGetter.updateSession(); + yield fieldGetter.updateDocument(FORCE_CITATIONS_FALSE, true, false); +}) /** * Edits bibliography metadata. @@ -774,11 +718,10 @@ Zotero.Integration.Interface.prototype.addEditBibliography = Zotero.Promise.coro if (haveBibliography) { yield fieldGetter.updateSession(); - yield this._session.editBibliography(this._doc); + yield this._session.editBibliography(); } else { var field = new Zotero.Integration.BibliographyField(yield fieldGetter.addField()); field.clearCode(); - field.type = INTEGRATION_TYPE_BIBLIOGRAPHY; field.writeToDoc(); yield fieldGetter.updateSession(); } @@ -921,7 +864,6 @@ Zotero.Integration.Fields = function(session, doc, fieldErrorHandler) { this._doc = doc; this._deferreds = null; - this._removeCodeKeys = {}; this._removeCodeFields = {}; this._bibliographyFields = []; this._bibliographyData = ""; @@ -1054,7 +996,6 @@ Zotero.Integration.Fields.prototype.updateSession = Zotero.Promise.coroutine(fun yield this.get(); this._session.resetRequest(this._doc); - this._removeCodeKeys = {}; this._removeCodeFields = {}; this._bibliographyFields = []; this._bibliographyData = ""; @@ -1104,31 +1045,28 @@ Zotero.Integration.Fields.prototype._processFields = Zotero.Promise.coroutine(fu for(var n = this._fields.length; i {return {id: i.id} }); - var field = doc.insertField("Field", 0); - field.setCode('TEMP'); + var field = new Zotero.Integration.CitationField(Zotero.Integration.currentDoc.insertField("Field", 0)); + field.clearCode(); + field.writeToDoc(); + var citation = new Zotero.Integration.Citation(field); var integrationDoc = addEditCitationSpy.lastCall.thisValue; var fieldGetter = new Zotero.Integration.Fields(integrationDoc._session, integrationDoc._doc, () => 0); var io = new Zotero.Integration.CitationEditInterface( - { citationItems, properties: {} }, + citation, field, fieldGetter, integrationDoc._session @@ -313,10 +315,11 @@ describe("Zotero.Integration", function () { // possible bug that reset() erases callsFake. // @NOTE: https://github.com/sinonjs/sinon/issues/1341 // displayDialogStub.callsFake(function(doc, dialogName, prefs, io) { - function(doc, dialogName, prefs, io) { + function(dialogName, prefs, io) { + Zotero.debug(`Display dialog: ${dialogName}`, 2); var ioResult = dialogResults[dialogName.substring(dialogName.lastIndexOf('/')+1, dialogName.length-4)]; if (typeof ioResult == 'function') { - ioResult = ioResult(doc, dialogName); + ioResult = ioResult(dialogName); } Object.assign(io, ioResult); return Zotero.Promise.resolve(); @@ -460,7 +463,7 @@ describe("Zotero.Integration", function () { displayDialogStub.reset(); yield execCommand('addEditBibliography', docID); assert.isTrue(displayDialogStub.calledOnce); - assert.isTrue(displayDialogStub.lastCall.args[1].includes('editBibliographyDialog')); + assert.isTrue(displayDialogStub.lastCall.args[0].includes('editBibliographyDialog')); }); }); });