www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit bbec11e3eb9679f02b01496e410c25d081f17874
parent e272465f6c8e97f7b8637532922fc6b9a365f293
Author: Adomas VenĨkauskas <adomas.ven@gmail.com>
Date:   Thu, 20 Apr 2017 15:29:56 +0300

Prepare 5.0 to handle JSON doc prefs

Diffstat:
Mchrome/content/zotero/xpcom/integration.js | 37++++++++++++++++++++++++++++---------
Mchrome/locale/en-US/zotero/zotero.properties | 2+-
Mtest/tests/integrationTests.js | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
3 files changed, 88 insertions(+), 14 deletions(-)

diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js @@ -990,7 +990,7 @@ Zotero.Integration.Document.prototype._getSession = Zotero.Promise.coroutine(fun return this._session.setDocPrefs(this._doc, this._app.primaryFieldType, this._app.secondaryFieldType).then(function(status) { // save doc prefs in doc - me._doc.setDocumentData(me._session.data.serializeXML()); + me._doc.setDocumentData(me._session.data.serialize()); if(haveFields) { me._session.reload = true; @@ -1007,12 +1007,13 @@ Zotero.Integration.Document.prototype._getSession = Zotero.Promise.coroutine(fun data.prefs.fieldType = "ReferenceMark"; } - var warning = this._doc.displayAlert(Zotero.getString("integration.upgradeWarning"), + var warning = this._doc.displayAlert(Zotero.getString("integration.upgradeWarning", Zotero.clientName, '5.0'), DIALOG_ICON_WARNING, DIALOG_BUTTONS_OK_CANCEL); if(!warning) { return Zotero.Promise.reject(new Zotero.Exception.UserCancelled("document upgrade")); } - } else if(data.dataVersion > DATA_VERSION) { + // Don't throw for version 4(JSON) during the transition from 4.0 to 5.0 + } else if((data.dataVersion > DATA_VERSION) && data.dataVersion != 4) { return Zotero.Promise.reject(new Zotero.Exception.Alert("integration.error.newerDocumentVersion", [data.zoteroVersion, Zotero.version], "integration.error.title")); } @@ -1046,7 +1047,7 @@ Zotero.Integration.Document.prototype._getSession = Zotero.Promise.coroutine(fun } return this._session.setDocPrefs(this._doc, this._app.primaryFieldType, this._app.secondaryFieldType).then(function(status) { - me._doc.setDocumentData(me._session.data.serializeXML()); + me._doc.setDocumentData(me._session.data.serialize()); me._session.reload = true; return me._session; }); @@ -1259,7 +1260,7 @@ Zotero.Integration.Document.prototype.setDocPrefs = function() { oldData = aOldData; // Write document data to document - me._doc.setDocumentData(me._session.data.serializeXML()); + me._doc.setDocumentData(me._session.data.serialize()); // If oldData is null, then there was no document data, so we don't need to update // fields @@ -1736,7 +1737,7 @@ Zotero.Integration.Fields.prototype._updateDocument = function* (forceCitations, // set bibliographyStyleHasBeenSet parameter to prevent further changes this._session.data.style.bibliographyStyleHasBeenSet = true; - this._doc.setDocumentData(this._session.data.serializeXML()); + this._doc.setDocumentData(this._session.data.serialize()); } } @@ -3080,9 +3081,20 @@ Zotero.Integration.DocumentData = function(string) { } /** - * Serializes document-specific data as XML + * Serializes document-specific data as JSON */ -Zotero.Integration.DocumentData.prototype.serializeXML = function() { +Zotero.Integration.DocumentData.prototype.serialize = function() { + // If we've retrieved data with version 4 (JSON), serialize back to JSON + if (this.dataVersion == 4) { + return JSON.stringify({ + style: this.style, + prefs: this.prefs, + sessionID: this.sessionID, + zoteroVersion: Zotero.version, + dataVersion: 4 + }); + } + // Otherwise default to XML for now var prefs = ""; for(var pref in this.prefs) { prefs += `<pref name="${Zotero.Utilities.htmlSpecialChars(pref)}" `+ @@ -3136,7 +3148,14 @@ Zotero.Integration.DocumentData.prototype.unserializeXML = function(xmlData) { * Unserializes document-specific data, either as XML or as the string form used previously */ Zotero.Integration.DocumentData.prototype.unserialize = function(input) { - if(input[0] == "<") { + try { + return Object.assign(this, JSON.parse(input)) + } catch (e) { + if (!(e instanceof SyntaxError)) { + throw e; + } + } + if (input[0] == "<") { this.unserializeXML(input); } else { const splitRe = /(^|[^:]):(?!:)/; diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties @@ -832,7 +832,7 @@ integration.missingItem.single = The highlighted citation no longer exists in integration.missingItem.multiple = Item %1$S in the highlighted citation no longer exists in your Zotero database. Do you want to select a substitute item? integration.missingItem.description = Clicking "No" will delete the field codes for citations containing this item, preserving the citation text but deleting it from your bibliography. integration.removeCodesWarning = Removing field codes will prevent Zotero from updating citations and bibliographies in this document. Are you sure you want to continue? -integration.upgradeWarning = Your document must be permanently upgraded in order to work with Zotero 2.1 or later. It is recommended that you make a backup before proceeding. Are you sure you want to continue? +integration.upgradeWarning = Your document must be permanently upgraded in order to work with %S %S or later. It is recommended that you make a backup before proceeding. Are you sure you want to continue? integration.error.newerDocumentVersion = Your document was created with a newer version of Zotero (%1$S) than the currently installed version (%2$S). Please upgrade Zotero before editing this document. integration.corruptField = The Zotero field code corresponding to this citation, which tells Zotero which item in your library this citation represents, has been corrupted. Would you like to reselect the item? integration.corruptField.description = Clicking "No" will delete the field codes for citations containing this item, preserving the citation text but potentially deleting it from your bibliography. diff --git a/test/tests/integrationTests.js b/test/tests/integrationTests.js @@ -255,7 +255,7 @@ describe("Zotero.Integration", function () { data.style = {styleID, locale: 'en-US', hasBibliography: true, bibliographyStyleHasBeenSet: true}; data.sessionID = Zotero.Utilities.randomString(10); Object.assign(data, options); - applications[docID].getActiveDocument().setDocumentData(data.serializeXML()); + applications[docID].getActiveDocument().setDocumentData(data.serialize()); } function setDefaultIntegrationDocPrefs() { @@ -472,7 +472,7 @@ describe("Zotero.Integration", function () { }); describe("DocumentData", function() { - it('should properly unserialize document data', function() { + it('should properly unserialize old XML document data', function() { var serializedXMLData = "<data data-version=\"3\" zotero-version=\"5.0.SOURCE\"><session id=\"F0NFmZ32\"/><style id=\"http://www.zotero.org/styles/cell\" hasBibliography=\"1\" bibliographyStyleHasBeenSet=\"1\"/><prefs><pref name=\"fieldType\" value=\"ReferenceMark\"/><pref name=\"storeReferences\" value=\"true\"/><pref name=\"automaticJournalAbbreviations\" value=\"true\"/><pref name=\"noteType\" value=\"0\"/></prefs></data>"; var data = new Zotero.Integration.DocumentData(serializedXMLData); var expectedData = { @@ -496,7 +496,30 @@ describe("Zotero.Integration", function () { assert.equal(JSON.stringify(data), JSON.stringify(expectedData)); }); - it('should properly serialize document data', function() { + it('should properly unserialize JSON document data', function() { + var expectedData = JSON.stringify({ + style: { + styleID: 'http://www.zotero.org/styles/cell', + locale: 'en-US', + hasBibliography: true, + bibliographyStyleHasBeenSet: true + }, + prefs: { + fieldType: 'ReferenceMark', + storeReferences: true, + automaticJournalAbbreviations: false, + noteType: 0 + }, + sessionID: 'owl-sesh', + zoteroVersion: '5.0.SOURCE', + dataVersion: 4 + }); + var data = new Zotero.Integration.DocumentData(expectedData); + // Convert to JSON to remove functions from DocumentData object + assert.equal(JSON.stringify(data), expectedData); + }); + + it('should properly serialize document data to XML (data ver 3)', function() { sinon.spy(Zotero, 'debug'); var data = new Zotero.Integration.DocumentData(); data.sessionID = "owl-sesh"; @@ -515,8 +538,11 @@ describe("Zotero.Integration", function () { automaticJournalAbbreviations: true }; + var serializedData = data.serialize(); + // Make sure we serialized to XML here + assert.equal(serializedData[0], '<'); // Serialize and unserialize (above test makes sure unserialize works properly). - var processedData = new Zotero.Integration.DocumentData(data.serializeXML()); + var processedData = new Zotero.Integration.DocumentData(serializedData); // This isn't ideal, but currently how it works. Better serialization which properly retains types // coming with official 5.0 release. @@ -530,5 +556,34 @@ describe("Zotero.Integration", function () { assert.isFalse(Zotero.debug.calledWith(sinon.match.string, 1)); Zotero.debug.restore(); }); + + it('should properly serialize document data to JSON (data ver 4)', function() { + var data = new Zotero.Integration.DocumentData(); + // data version 4 triggers serialization to JSON + // (e.g. when we've retrieved data from the doc and it was ver 4 already) + data.dataVersion = 4; + data.sessionID = "owl-sesh"; + data.style = { + styleID: 'http://www.zotero.org/styles/cell', + locale: 'en-US', + hasBibliography: false, + bibliographyStyleHasBeenSet: true + }; + data.prefs = { + noteType: 1, + fieldType: "Field", + storeReferences: true, + automaticJournalAbbreviations: true + }; + + // Serialize and unserialize (above tests makes sure unserialize works properly). + var processedData = new Zotero.Integration.DocumentData(data.serialize()); + + // Added in serialization routine + data.zoteroVersion = Zotero.version; + + // Convert to JSON to remove functions from DocumentData objects + assert.deepEqual(JSON.parse(JSON.stringify(processedData)), JSON.parse(JSON.stringify(data))); + }); }) });