From 0ea69548ea6389d8c3020939aed4fd2dd6bddfdf Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Tue, 5 Mar 2019 17:46:54 -0500 Subject: [PATCH] Add history.pauseChangeDispatch / history.resumeChangeDispatch To avoid dispatching change events at improper times --- modules/core/history.js | 25 ++++++++++++++++---- test/spec/core/history.js | 49 +++++++++++++++++++++++++++++---------- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/modules/core/history.js b/modules/core/history.js index 97f730579..fb7f9fa8c 100644 --- a/modules/core/history.js +++ b/modules/core/history.js @@ -36,6 +36,7 @@ export function coreHistory(context) { var duration = 150; var _imageryUsed = []; var _checkpoints = {}; + var _pausedGraph; var _stack; var _index; var _tree; @@ -104,11 +105,13 @@ export function coreHistory(context) { // determine difference and dispatch a change event function change(previous, isAnnotated) { var difference = coreDifference(previous, history.graph()); - dispatch.call('change', this, difference); - if (isAnnotated) { - // actions like dragging a node can fire lots of changes, - // so use 'annotatedChange' to listen for grouped undo/redo changes - dispatch.call('annotatedChange', this, difference); + if (!_pausedGraph) { + dispatch.call('change', this, difference); + if (isAnnotated) { + // actions like dragging a node can fire lots of changes, + // so use 'annotatedChange' to listen for grouped undo/redo changes + dispatch.call('annotatedChange', this, difference); + } } return difference; } @@ -244,6 +247,18 @@ export function coreHistory(context) { }, + pauseChangeDispatch: function() { + _pausedGraph = _stack[_index].graph; + }, + + + resumeChangeDispatch: function() { + var previous = _pausedGraph; + _pausedGraph = null; + return change(previous, true); + }, + + undoAnnotation: function() { var i = _index; while (i >= 0) { diff --git a/test/spec/core/history.js b/test/spec/core/history.js index 3c1533d3b..c9872a66f 100644 --- a/test/spec/core/history.js +++ b/test/spec/core/history.js @@ -55,8 +55,8 @@ describe('iD.History', function () { }); it('performs multiple actions', function () { - var action1 = sinon.stub().returns(iD.coreGraph()), - action2 = sinon.stub().returns(iD.coreGraph()); + var action1 = sinon.stub().returns(iD.coreGraph()); + var action2 = sinon.stub().returns(iD.coreGraph()); history.perform(action1, action2, 'annotation'); expect(action1).to.have.been.called; expect(action2).to.have.been.called; @@ -99,8 +99,8 @@ describe('iD.History', function () { }); it('performs multiple actions', function () { - var action1 = sinon.stub().returns(iD.coreGraph()), - action2 = sinon.stub().returns(iD.coreGraph()); + var action1 = sinon.stub().returns(iD.coreGraph()); + var action2 = sinon.stub().returns(iD.coreGraph()); history.replace(action1, action2, 'annotation'); expect(action1).to.have.been.called; expect(action2).to.have.been.called; @@ -193,8 +193,8 @@ describe('iD.History', function () { }); it('performs multiple actions', function () { - var action1 = sinon.stub().returns(iD.coreGraph()), - action2 = sinon.stub().returns(iD.coreGraph()); + var action1 = sinon.stub().returns(iD.coreGraph()); + var action2 = sinon.stub().returns(iD.coreGraph()); history.perform(action, 'annotation'); history.overwrite(action1, action2, 'annotation2'); expect(action1).to.have.been.called; @@ -266,6 +266,31 @@ describe('iD.History', function () { }); }); + describe('#pauseChangeDispatch / #resumeChangeDispatch', function() { + it('prevents change events from getting dispatched', function() { + history.perform(action, 'base'); + history.on('change', spy); + + history.pauseChangeDispatch(); + + history.perform(action, 'perform'); + expect(spy).to.have.been.notCalled; + history.replace(action, 'replace'); + expect(spy).to.have.been.notCalled; + history.overwrite(action, 'replace'); + expect(spy).to.have.been.notCalled; + history.undo(); + expect(spy).to.have.been.notCalled; + history.redo(); + expect(spy).to.have.been.notCalled; + history.pop(); + expect(spy).to.have.been.notCalled; + + var difference = history.resumeChangeDispatch(); + expect(spy).to.have.been.calledOnceWith(difference); + }); + }); + describe('#changes', function () { it('includes created entities', function () { var node = iD.osmNode(); @@ -274,8 +299,8 @@ describe('iD.History', function () { }); it('includes modified entities', function () { - var node1 = iD.osmNode({id: 'n1'}), - node2 = node1.update({ tags: { yes: 'no' } }); + var node1 = iD.osmNode({id: 'n1'}); + var node2 = node1.update({ tags: { yes: 'no' } }); history.merge([node1]); history.perform(function (graph) { return graph.replace(node2); }); expect(history.changes().modified).to.eql([node2]); @@ -357,10 +382,10 @@ describe('iD.History', function () { }); it('generates v3 JSON', function() { - var node_1 = iD.osmNode({id: 'n-1'}), - node1 = iD.osmNode({id: 'n1'}), - node2 = iD.osmNode({id: 'n2'}), - node3 = iD.osmNode({id: 'n3'}); + var node_1 = iD.osmNode({id: 'n-1'}); + var node1 = iD.osmNode({id: 'n1'}); + var node2 = iD.osmNode({id: 'n2'}); + var node3 = iD.osmNode({id: 'n3'}); history.merge([node1, node2, node3]); history.perform(iD.actionAddEntity(node_1)); // addition history.perform(iD.actionChangeTags('n2', {k: 'v'})); // modification