diff --git a/chrome/content/zotero/xpcom/sync/syncLocal.js b/chrome/content/zotero/xpcom/sync/syncLocal.js index a8bbd905e..036c9c6d8 100644 --- 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 index cfade8e6d..dbc0e4d40 100644 --- 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 = "
Foo bar
bar foo
Foo bar!
", + 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",