commit 4032edcf7d9ee959ce64f0e5090a39a05054a36a
parent 3ebc238320a7f000da31cf4edea37236c0cabd48
Author: Dan Stillman <dstillman@zotero.org>
Date: Wed, 14 Jun 2017 02:35:21 -0400
Ignore note markup conflicts without cache when text content matches
Diffstat:
2 files changed, 88 insertions(+), 0 deletions(-)
diff --git a/chrome/content/zotero/xpcom/sync/syncLocal.js b/chrome/content/zotero/xpcom/sync/syncLocal.js
@@ -1547,6 +1547,15 @@ Zotero.Sync.Data.Local = {
}
var localChanged = false;
+ var normalizeHTML = (str) => {
+ let parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
+ .createInstance(Components.interfaces.nsIDOMParser);
+ str = parser.parseFromString(str, 'text/html');
+ str = str.body.textContent;
+ // Normalize internal spaces
+ str = str.replace(/\s+/g, ' ');
+ return str;
+ };
// Massage some old data
conflicts = conflicts.filter((x) => {
@@ -1567,6 +1576,27 @@ Zotero.Sync.Data.Local = {
}
}
}
+ // Ignore notes with the same text content
+ //
+ // These can happen to people upgrading to 5.0 with notes that were added without going
+ // through TinyMCE (e.g., from translators)
+ else if (x[0].field == 'note' && x[0].op == 'add' && x[1].op == 'add') {
+ let a = x[0].value;
+ let b = x[1].value;
+ try {
+ a = normalizeHTML(a);
+ b = normalizeHTML(b);
+ if (a == b) {
+ Zotero.debug("Notes differ only by markup -- using remote version");
+ changes.push(x[1]);
+ return false;
+ }
+ }
+ catch (e) {
+ Zotero.logError(e);
+ return true
+ }
+ }
return true;
});
diff --git a/test/tests/syncLocalTest.js b/test/tests/syncLocalTest.js
@@ -1965,6 +1965,64 @@ describe("Zotero.Sync.Data.Local", function() {
);
})
+ it("should automatically use remote version for note markup differences when text content matches", function () {
+ var val2 = "<p>Foo bar<br />bar foo</p>";
+
+ var json1 = {
+ key: "AAAAAAAA",
+ version: 0,
+ itemType: "note",
+ note: "Foo bar<br/>bar foo",
+ dateModified: "2017-06-13 13:45:12"
+ };
+ var json2 = {
+ key: "AAAAAAAA",
+ version: 5,
+ itemType: "note",
+ note: val2,
+ dateModified: "2017-06-13 13:45:12"
+ };
+ var ignoreFields = ['dateAdded', 'dateModified'];
+ var result = Zotero.Sync.Data.Local._reconcileChangesWithoutCache(
+ 'item', json1, json2, ignoreFields
+ );
+ assert.lengthOf(result.changes, 1);
+ assert.sameDeepMembers(
+ result.changes,
+ [
+ {
+ field: "note",
+ op: "add",
+ value: val2
+ }
+ ]
+ );
+ assert.lengthOf(result.conflicts, 0);
+ });
+
+ it("should show conflict for note markup differences when text content doesn't match", function () {
+ var json1 = {
+ key: "AAAAAAAA",
+ version: 0,
+ itemType: "note",
+ note: "Foo bar?",
+ dateModified: "2017-06-13 13:45:12"
+ };
+ var json2 = {
+ key: "AAAAAAAA",
+ version: 5,
+ itemType: "note",
+ note: "<p>Foo bar!</p>",
+ dateModified: "2017-06-13 13:45:12"
+ };
+ var ignoreFields = ['dateAdded', 'dateModified'];
+ var result = Zotero.Sync.Data.Local._reconcileChangesWithoutCache(
+ 'item', json1, json2, ignoreFields
+ );
+ assert.lengthOf(result.changes, 0);
+ assert.lengthOf(result.conflicts, 1);
+ });
+
it("should automatically use remote version for conflicting fields when both sides are in trash", function () {
var json1 = {
key: "AAAAAAAA",