From 81ede07d94305bbdc53cf449717e7c3f4294cb46 Mon Sep 17 00:00:00 2001 From: aloscha Date: Fri, 27 May 2016 22:35:05 +0200 Subject: [PATCH 1/3] Change the observed events to mouseup, keyup #98 Remove slowCheck (dirty checking in fixed time intervals) #103 --- src/json-patch-duplex.js | 34 +++++++--------------------- src/json-patch-duplex.ts | 44 ++++++++++-------------------------- test/spec/duplexSpec.js | 49 +++++++++++++++++++++++++++++++--------- 3 files changed, 58 insertions(+), 69 deletions(-) diff --git a/src/json-patch-duplex.js b/src/json-patch-duplex.js index 88fbde0b..4bbc1d2e 100644 --- a/src/json-patch-duplex.js +++ b/src/json-patch-duplex.js @@ -226,14 +226,14 @@ var jsonpatch; this.obj = obj; } return Mirror; - })(); + }()); var ObserverInfo = (function () { function ObserverInfo(callback, observer) { this.callback = callback; this.observer = observer; } return ObserverInfo; - })(); + }()); function getMirror(obj) { for (var i = 0, ilen = beforeDict.length; i < ilen; i++) { if (beforeDict[i].obj === obj) { @@ -288,11 +288,6 @@ var jsonpatch; if (callback) { observer.callback = callback; observer.next = null; - var intervals = this.intervals || [100, 1000, 10000, 60000]; - if (intervals.push === void 0) { - throw new OriginalError("jsonpatch.intervals must be an array"); - } - var currentInterval = 0; var dirtyCheck = function () { generate(observer); }; @@ -300,29 +295,18 @@ var jsonpatch; clearTimeout(observer.next); observer.next = setTimeout(function () { dirtyCheck(); - currentInterval = 0; - observer.next = setTimeout(slowCheck, intervals[currentInterval++]); - }, 0); - }; - var slowCheck = function () { - dirtyCheck(); - if (currentInterval == intervals.length) - currentInterval = intervals.length - 1; - observer.next = setTimeout(slowCheck, intervals[currentInterval++]); + }); }; if (typeof window !== 'undefined') { if (window.addEventListener) { - window.addEventListener('mousedown', fastCheck); window.addEventListener('mouseup', fastCheck); - window.addEventListener('keydown', fastCheck); + window.addEventListener('keyup', fastCheck); } else { - document.documentElement.attachEvent('onmousedown', fastCheck); document.documentElement.attachEvent('onmouseup', fastCheck); - document.documentElement.attachEvent('onkeydown', fastCheck); + document.documentElement.attachEvent('onkeyup', fastCheck); } } - observer.next = setTimeout(slowCheck, intervals[currentInterval++]); } observer.patches = patches; observer.object = obj; @@ -332,14 +316,12 @@ var jsonpatch; removeObserverFromMirror(mirror, observer); if (typeof window !== 'undefined') { if (window.removeEventListener) { - window.removeEventListener('mousedown', fastCheck); window.removeEventListener('mouseup', fastCheck); - window.removeEventListener('keydown', fastCheck); + window.removeEventListener('keyup', fastCheck); } else { - document.documentElement.detachEvent('onmousedown', fastCheck); document.documentElement.detachEvent('onmouseup', fastCheck); - document.documentElement.detachEvent('onkeydown', fastCheck); + document.documentElement.detachEvent('onkeyup', fastCheck); } } }; @@ -514,7 +496,7 @@ var jsonpatch; this.tree = tree; } return JsonPatchError; - })(OriginalError); + }(OriginalError)); jsonpatch.JsonPatchError = JsonPatchError; jsonpatch.Error = JsonPatchError; /** diff --git a/src/json-patch-duplex.ts b/src/json-patch-duplex.ts index 8af3c0a7..72c0e1e6 100644 --- a/src/json-patch-duplex.ts +++ b/src/json-patch-duplex.ts @@ -241,8 +241,6 @@ module jsonpatch { var beforeDict = []; - export var intervals; - class Mirror { obj: any; observers = []; @@ -324,61 +322,43 @@ module jsonpatch { if (callback) { observer.callback = callback; observer.next = null; - var intervals = this.intervals || [100, 1000, 10000, 60000]; - if (intervals.push === void 0) { - throw new OriginalError("jsonpatch.intervals must be an array"); - } - var currentInterval = 0; - var dirtyCheck = function () { - generate(observer); - }; - var fastCheck = function () { - clearTimeout(observer.next); - observer.next = setTimeout(function () { - dirtyCheck(); - currentInterval = 0; - observer.next = setTimeout(slowCheck, intervals[currentInterval++]); - }, 0); + var dirtyCheck = () => { + generate(observer); }; - var slowCheck = function () { - dirtyCheck(); - if (currentInterval == intervals.length) - currentInterval = intervals.length - 1; - observer.next = setTimeout(slowCheck, intervals[currentInterval++]); + var fastCheck = () => { + clearTimeout(observer.next); + observer.next = setTimeout(() => { + dirtyCheck(); + }); }; if (typeof window !== 'undefined') { //not Node if (window.addEventListener) { //standards - window.addEventListener('mousedown', fastCheck); window.addEventListener('mouseup', fastCheck); - window.addEventListener('keydown', fastCheck); + window.addEventListener('keyup', fastCheck); } else { //IE8 - document.documentElement.attachEvent('onmousedown', fastCheck); document.documentElement.attachEvent('onmouseup', fastCheck); - document.documentElement.attachEvent('onkeydown', fastCheck); + document.documentElement.attachEvent('onkeyup', fastCheck); } } - observer.next = setTimeout(slowCheck, intervals[currentInterval++]); } observer.patches = patches; observer.object = obj; - observer.unobserve = function () { + observer.unobserve = () => { generate(observer); clearTimeout(observer.next); removeObserverFromMirror(mirror, observer); if (typeof window !== 'undefined') { if (window.removeEventListener) { - window.removeEventListener('mousedown', fastCheck); window.removeEventListener('mouseup', fastCheck); - window.removeEventListener('keydown', fastCheck); + window.removeEventListener('keyup', fastCheck); } else { - document.documentElement.detachEvent('onmousedown', fastCheck); document.documentElement.detachEvent('onmouseup', fastCheck); - document.documentElement.detachEvent('onkeydown', fastCheck); + document.documentElement.detachEvent('onkeyup', fastCheck); } } }; diff --git a/test/spec/duplexSpec.js b/test/spec/duplexSpec.js index c857b10c..8906f25d 100644 --- a/test/spec/duplexSpec.js +++ b/test/spec/duplexSpec.js @@ -18,6 +18,12 @@ function triggerMouseup(elem) { } } +function triggerKeyup(elem) { + if (typeof document !== 'undefined') { + fireEvent((elem || document.documentElement), 'keyup'); + } +} + //http://stackoverflow.com/questions/827716/emulate-clicking-a-link-with-javascript-that-works-with-ie function fireEvent(obj, evt) { var fireOnThis = obj; @@ -407,7 +413,7 @@ describe("duplex", function () { obj.foo = "something"; var patches = jsonpatch.generate(observer); - expect(patches).toEqual([{op: 'replace', path: '/foo', value: "something"}]); + expect(patches).toEqual([{op: 'add', path: '/foo', value: "something"}]); }); it('`undefined` array element is set to something', function() { var obj = {foo: [0,undefined,2]}; @@ -426,7 +432,7 @@ describe("duplex", function () { delete obj.foo; var patches = jsonpatch.generate(observer); - expect(patches).toEqual([{op: 'remove', path: '/foo'}]); + expect(patches).toEqual([]); }); }); @@ -458,6 +464,8 @@ describe("duplex", function () { obj.phoneNumbers[0].number = "123"; obj.phoneNumbers[1].number = "456"; + triggerKeyup(); + waitsFor(function(){ return typeof patches === 'object'; }, 100); @@ -478,13 +486,14 @@ describe("duplex", function () { obj = { firstName:"Albert", lastName:"Einstein", phoneNumbers:[ {number:"12345"}, {number:"45353"} ]}; - jsonpatch.intervals = [50]; jsonpatch.observe(obj, function(patches) { called++; lastPatches = patches; }); obj.firstName = "Marcin"; + triggerKeyup(); + waitsFor(function(){ return called > 0; }, 100, 'firstName change to Marcin'); @@ -494,6 +503,7 @@ describe("duplex", function () { expect(lastPatches).toEqual([{op: 'replace', path: '/firstName', value: 'Marcin'}]); obj.lastName = "Warp"; + triggerKeyup(); }); waitsFor(function(){ @@ -516,13 +526,14 @@ describe("duplex", function () { obj = { firstName:"Albert", lastName:"Einstein", phoneNumbers:[ {number:"12345"}, {number:"45353"} ]}; - jsonpatch.intervals = [50]; jsonpatch.observe(obj, function(patches) { called++; lastPatches = patches; }); obj.phoneNumbers[0].number = "123"; + triggerKeyup(); + waitsFor(function(){ return called > 0; }, 100, 'phoneNumbers[0].number change to 123'); @@ -532,6 +543,7 @@ describe("duplex", function () { expect(lastPatches).toEqual([{op: 'replace', path: '/phoneNumbers/0/number', value: '123'}]); obj.phoneNumbers[1].number = "456"; + triggerKeyup(); }); waitsFor(function(){ @@ -555,7 +567,6 @@ describe("duplex", function () { obj = { firstName:"Albert", lastName:"Einstein", phoneNumbers:[ {number:"12345"}, {number:"45353"} ]}; - jsonpatch.intervals = [10]; var observer = jsonpatch.observe(obj, function(patches) { called++; lastPatches = patches; @@ -582,13 +593,14 @@ describe("duplex", function () { obj = { firstName:"Albert", lastName:"Einstein", phoneNumbers:[ {number:"12345"}, {number:"45353"} ]}; - jsonpatch.intervals = [10]; var observer = jsonpatch.observe(obj, function(patches) { called++; }); obj.firstName = 'Malvin'; + triggerKeyup(); + waits(20); runs(function(){ @@ -597,6 +609,8 @@ describe("duplex", function () { jsonpatch.unobserve(obj, observer); obj.firstName = 'Wilfred'; + + triggerKeyup(); }); waits(20); @@ -609,6 +623,7 @@ describe("duplex", function () { }); obj.firstName = 'Megan'; + triggerKeyup(); }); waits(20); @@ -622,15 +637,17 @@ describe("duplex", function () { var called = 0; obj = { firstName:"Albert", lastName:"Einstein", - phoneNumbers:[ {number:"12345"}, {number:"45353"} ]}; + phoneNumbers: [{ number: "12345" }, { number: "45353" }] + }; - jsonpatch.intervals = [10]; var observer = jsonpatch.observe(obj, function(patches) { called++; }); obj.phoneNumbers[1].number = '555'; + triggerKeyup(); + waits(20); runs(function(){ @@ -639,6 +656,8 @@ describe("duplex", function () { jsonpatch.unobserve(obj, observer); obj.phoneNumbers[1].number = '556'; + + triggerKeyup(); }); waits(20); @@ -651,6 +670,8 @@ describe("duplex", function () { }); obj.phoneNumbers[1].number = '557'; + + triggerKeyup(); }); waits(20); @@ -669,7 +690,6 @@ describe("duplex", function () { {number: "45353"} ]}; - jsonpatch.intervals = [10]; var observer = jsonpatch.observe(obj, function (patches) { lastPatches = patches; }); @@ -710,6 +730,8 @@ describe("duplex", function () { obj.foo = 'bazz'; + triggerKeyup(); + waitsFor(function () { return callback.calls.length > 0; }, 'callback calls', 1000); @@ -720,6 +742,8 @@ describe("duplex", function () { callback.reset(); obj.foo = 'bazinga'; + + triggerKeyup(); }); waitsFor(function () { @@ -745,7 +769,7 @@ describe("duplex", function () { expect(lastPatches).toEqual([ { op: 'replace', path: '/lastName', value: 'Hawking' } ]); - }, 0); + }, 100); }); }); @@ -815,6 +839,8 @@ describe("duplex", function () { obj.foo = 'bazz'; + triggerKeyup() + waitsFor(function () { return callback.calls.length > 0; }, 'callback call', 1000); @@ -863,13 +889,14 @@ describe("duplex", function () { obj = { firstName:"Albert", lastName:"Einstein", phoneNumbers:[ {number:"12345"}, {number:"45353"} ]}; - jsonpatch.intervals = [10]; var observer = jsonpatch.observe(obj, function(patches) { called++; }); obj.firstName = 'Malvin'; + triggerKeyup(); + waits(20); runs(function(){ From e3afd5bf9775909c34c1660c6fecef607302dd66 Mon Sep 17 00:00:00 2001 From: aloscha Date: Mon, 30 May 2016 13:35:06 +0200 Subject: [PATCH 2/3] Fix rv #103 #98 --- src/json-patch-duplex.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/json-patch-duplex.ts b/src/json-patch-duplex.ts index 72c0e1e6..38e66234 100644 --- a/src/json-patch-duplex.ts +++ b/src/json-patch-duplex.ts @@ -328,9 +328,7 @@ module jsonpatch { }; var fastCheck = () => { clearTimeout(observer.next); - observer.next = setTimeout(() => { - dirtyCheck(); - }); + observer.next = setTimeout(dirtyCheck); }; if (typeof window !== 'undefined') { //not Node if (window.addEventListener) { //standards From 565ffa5ed61bd833e19c4c06ae57e253c6d146ca Mon Sep 17 00:00:00 2001 From: aloscha Date: Mon, 30 May 2016 15:01:07 +0200 Subject: [PATCH 3/3] Revert rv #103 #98 --- src/json-patch-duplex.js | 4 +--- test/spec/duplexSpec.js | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/json-patch-duplex.js b/src/json-patch-duplex.js index 4bbc1d2e..6302c747 100644 --- a/src/json-patch-duplex.js +++ b/src/json-patch-duplex.js @@ -293,9 +293,7 @@ var jsonpatch; }; var fastCheck = function () { clearTimeout(observer.next); - observer.next = setTimeout(function () { - dirtyCheck(); - }); + observer.next = setTimeout(dirtyCheck); }; if (typeof window !== 'undefined') { if (window.addEventListener) { diff --git a/test/spec/duplexSpec.js b/test/spec/duplexSpec.js index 8906f25d..310cdcdd 100644 --- a/test/spec/duplexSpec.js +++ b/test/spec/duplexSpec.js @@ -413,7 +413,7 @@ describe("duplex", function () { obj.foo = "something"; var patches = jsonpatch.generate(observer); - expect(patches).toEqual([{op: 'add', path: '/foo', value: "something"}]); + expect(patches).toEqual([{op: 'replace', path: '/foo', value: "something"}]); }); it('`undefined` array element is set to something', function() { var obj = {foo: [0,undefined,2]}; @@ -432,8 +432,7 @@ describe("duplex", function () { delete obj.foo; var patches = jsonpatch.generate(observer); - expect(patches).toEqual([]); - + expect(patches).toEqual([{ op: 'remove', path: '/foo' }]); }); }); });