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:
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)));
+ });
})
});