mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-12 16:52:50 +00:00
Make sure pause/resumeChangeDispatch can be called multiple times
This commit is contained in:
@@ -488,6 +488,8 @@ export function coreContext() {
|
||||
context.graph = history.graph;
|
||||
context.changes = history.changes;
|
||||
context.intersects = history.intersects;
|
||||
context.pauseChangeDispatch = history.pauseChangeDispatch;
|
||||
context.resumeChangeDispatch = history.resumeChangeDispatch;
|
||||
|
||||
validator = coreValidator(context);
|
||||
|
||||
|
||||
@@ -248,14 +248,18 @@ export function coreHistory(context) {
|
||||
|
||||
|
||||
pauseChangeDispatch: function() {
|
||||
_pausedGraph = _stack[_index].graph;
|
||||
if (!_pausedGraph) {
|
||||
_pausedGraph = _stack[_index].graph;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
resumeChangeDispatch: function() {
|
||||
var previous = _pausedGraph;
|
||||
_pausedGraph = null;
|
||||
return change(previous, true);
|
||||
if (_pausedGraph) {
|
||||
var previous = _pausedGraph;
|
||||
_pausedGraph = null;
|
||||
return change(previous, true);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
describe('iD.History', function () {
|
||||
var context, history, spy,
|
||||
action = function() { return iD.coreGraph(); };
|
||||
describe('iD.coreHistory', function () {
|
||||
var context, history, spy;
|
||||
var actionNoop = function(g) { return g; };
|
||||
var actionAddNode = function (nodeID) {
|
||||
return function(g) {
|
||||
return g.replace(iD.osmNode({ id: nodeID }));
|
||||
};
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.coreContext();
|
||||
@@ -33,7 +38,7 @@ describe('iD.History', function () {
|
||||
|
||||
describe('#perform', function () {
|
||||
it('returns a difference', function () {
|
||||
expect(history.perform(action).changes()).to.eql({});
|
||||
expect(history.perform(actionNoop).changes()).to.eql({});
|
||||
});
|
||||
|
||||
it('updates the graph', function () {
|
||||
@@ -43,13 +48,13 @@ describe('iD.History', function () {
|
||||
});
|
||||
|
||||
it('pushes an undo annotation', function () {
|
||||
history.perform(action, 'annotation');
|
||||
history.perform(actionNoop, 'annotation');
|
||||
expect(history.undoAnnotation()).to.equal('annotation');
|
||||
});
|
||||
|
||||
it('emits a change event', function () {
|
||||
history.on('change', spy);
|
||||
var difference = history.perform(action);
|
||||
var difference = history.perform(actionNoop);
|
||||
expect(spy).to.have.been.calledWith(difference);
|
||||
expect(spy.callCount).to.eql(1);
|
||||
});
|
||||
@@ -77,7 +82,7 @@ describe('iD.History', function () {
|
||||
|
||||
describe('#replace', function () {
|
||||
it('returns a difference', function () {
|
||||
expect(history.replace(action).changes()).to.eql({});
|
||||
expect(history.replace(actionNoop).changes()).to.eql({});
|
||||
});
|
||||
|
||||
it('updates the graph', function () {
|
||||
@@ -87,14 +92,14 @@ describe('iD.History', function () {
|
||||
});
|
||||
|
||||
it('replaces the undo annotation', function () {
|
||||
history.perform(action, 'annotation1');
|
||||
history.replace(action, 'annotation2');
|
||||
history.perform(actionNoop, 'annotation1');
|
||||
history.replace(actionNoop, 'annotation2');
|
||||
expect(history.undoAnnotation()).to.equal('annotation2');
|
||||
});
|
||||
|
||||
it('emits a change event', function () {
|
||||
history.on('change', spy);
|
||||
var difference = history.replace(action);
|
||||
var difference = history.replace(actionNoop);
|
||||
expect(spy).to.have.been.calledWith(difference);
|
||||
});
|
||||
|
||||
@@ -110,49 +115,49 @@ describe('iD.History', function () {
|
||||
|
||||
describe('#pop', function () {
|
||||
it('returns a difference', function () {
|
||||
history.perform(action, 'annotation');
|
||||
history.perform(actionNoop, 'annotation');
|
||||
expect(history.pop().changes()).to.eql({});
|
||||
});
|
||||
|
||||
it('updates the graph', function () {
|
||||
history.perform(action, 'annotation');
|
||||
history.perform(actionNoop, 'annotation');
|
||||
history.pop();
|
||||
expect(history.undoAnnotation()).to.be.undefined;
|
||||
});
|
||||
|
||||
it('does not push the redo stack', function () {
|
||||
history.perform(action, 'annotation');
|
||||
history.perform(actionNoop, 'annotation');
|
||||
history.pop();
|
||||
expect(history.redoAnnotation()).to.be.undefined;
|
||||
});
|
||||
|
||||
it('emits a change event', function () {
|
||||
history.perform(action);
|
||||
history.perform(actionNoop);
|
||||
history.on('change', spy);
|
||||
var difference = history.pop();
|
||||
expect(spy).to.have.been.calledWith(difference);
|
||||
});
|
||||
|
||||
it('pops n times', function () {
|
||||
history.perform(action, 'annotation1');
|
||||
history.perform(action, 'annotation2');
|
||||
history.perform(action, 'annotation3');
|
||||
history.perform(actionNoop, 'annotation1');
|
||||
history.perform(actionNoop, 'annotation2');
|
||||
history.perform(actionNoop, 'annotation3');
|
||||
history.pop(2);
|
||||
expect(history.undoAnnotation()).to.equal('annotation1');
|
||||
});
|
||||
|
||||
it('pops 0 times', function () {
|
||||
history.perform(action, 'annotation1');
|
||||
history.perform(action, 'annotation2');
|
||||
history.perform(action, 'annotation3');
|
||||
history.perform(actionNoop, 'annotation1');
|
||||
history.perform(actionNoop, 'annotation2');
|
||||
history.perform(actionNoop, 'annotation3');
|
||||
history.pop(0);
|
||||
expect(history.undoAnnotation()).to.equal('annotation3');
|
||||
});
|
||||
|
||||
it('pops 1 time if argument is invalid', function () {
|
||||
history.perform(action, 'annotation1');
|
||||
history.perform(action, 'annotation2');
|
||||
history.perform(action, 'annotation3');
|
||||
history.perform(actionNoop, 'annotation1');
|
||||
history.perform(actionNoop, 'annotation2');
|
||||
history.perform(actionNoop, 'annotation3');
|
||||
history.pop('foo');
|
||||
expect(history.undoAnnotation()).to.equal('annotation2');
|
||||
history.pop(-1);
|
||||
@@ -162,40 +167,40 @@ describe('iD.History', function () {
|
||||
|
||||
describe('#overwrite', function () {
|
||||
it('returns a difference', function () {
|
||||
history.perform(action, 'annotation');
|
||||
expect(history.overwrite(action).changes()).to.eql({});
|
||||
history.perform(actionNoop, 'annotation');
|
||||
expect(history.overwrite(actionNoop).changes()).to.eql({});
|
||||
});
|
||||
|
||||
it('updates the graph', function () {
|
||||
history.perform(action, 'annotation');
|
||||
history.perform(actionNoop, 'annotation');
|
||||
var node = iD.osmNode();
|
||||
history.overwrite(function (graph) { return graph.replace(node); });
|
||||
expect(history.graph().entity(node.id)).to.equal(node);
|
||||
});
|
||||
|
||||
it('replaces the undo annotation', function () {
|
||||
history.perform(action, 'annotation1');
|
||||
history.overwrite(action, 'annotation2');
|
||||
history.perform(actionNoop, 'annotation1');
|
||||
history.overwrite(actionNoop, 'annotation2');
|
||||
expect(history.undoAnnotation()).to.equal('annotation2');
|
||||
});
|
||||
|
||||
it('does not push the redo stack', function () {
|
||||
history.perform(action, 'annotation');
|
||||
history.overwrite(action, 'annotation2');
|
||||
history.perform(actionNoop, 'annotation');
|
||||
history.overwrite(actionNoop, 'annotation2');
|
||||
expect(history.redoAnnotation()).to.be.undefined;
|
||||
});
|
||||
|
||||
it('emits a change event', function () {
|
||||
history.perform(action, 'annotation');
|
||||
history.perform(actionNoop, 'annotation');
|
||||
history.on('change', spy);
|
||||
var difference = history.overwrite(action, 'annotation2');
|
||||
var difference = history.overwrite(actionNoop, 'annotation2');
|
||||
expect(spy).to.have.been.calledWith(difference);
|
||||
});
|
||||
|
||||
it('performs multiple actions', function () {
|
||||
var action1 = sinon.stub().returns(iD.coreGraph());
|
||||
var action2 = sinon.stub().returns(iD.coreGraph());
|
||||
history.perform(action, 'annotation');
|
||||
history.perform(actionNoop, 'annotation');
|
||||
history.overwrite(action1, action2, 'annotation2');
|
||||
expect(action1).to.have.been.called;
|
||||
expect(action2).to.have.been.called;
|
||||
@@ -209,26 +214,26 @@ describe('iD.History', function () {
|
||||
});
|
||||
|
||||
it('pops the undo stack', function () {
|
||||
history.perform(action, 'annotation');
|
||||
history.perform(actionNoop, 'annotation');
|
||||
history.undo();
|
||||
expect(history.undoAnnotation()).to.be.undefined;
|
||||
});
|
||||
|
||||
it('pushes the redo stack', function () {
|
||||
history.perform(action, 'annotation');
|
||||
history.perform(actionNoop, 'annotation');
|
||||
history.undo();
|
||||
expect(history.redoAnnotation()).to.equal('annotation');
|
||||
});
|
||||
|
||||
it('emits an undone event', function () {
|
||||
history.perform(action);
|
||||
history.perform(actionNoop);
|
||||
history.on('undone', spy);
|
||||
history.undo();
|
||||
expect(spy).to.have.been.called;
|
||||
});
|
||||
|
||||
it('emits a change event', function () {
|
||||
history.perform(action);
|
||||
history.perform(actionNoop);
|
||||
history.on('change', spy);
|
||||
var difference = history.undo();
|
||||
expect(spy).to.have.been.calledWith(difference);
|
||||
@@ -241,7 +246,7 @@ describe('iD.History', function () {
|
||||
});
|
||||
|
||||
it('does redo into an annotated state', function () {
|
||||
history.perform(action, 'annotation');
|
||||
history.perform(actionNoop, 'annotation');
|
||||
history.on('redone', spy);
|
||||
history.undo();
|
||||
history.redo();
|
||||
@@ -250,7 +255,7 @@ describe('iD.History', function () {
|
||||
});
|
||||
|
||||
it('does not redo into a non-annotated state', function () {
|
||||
history.perform(action);
|
||||
history.perform(actionNoop);
|
||||
history.on('redone', spy);
|
||||
history.undo();
|
||||
history.redo();
|
||||
@@ -258,7 +263,7 @@ describe('iD.History', function () {
|
||||
});
|
||||
|
||||
it('emits a change event', function () {
|
||||
history.perform(action);
|
||||
history.perform(actionNoop);
|
||||
history.undo();
|
||||
history.on('change', spy);
|
||||
var difference = history.redo();
|
||||
@@ -268,16 +273,16 @@ describe('iD.History', function () {
|
||||
|
||||
describe('#pauseChangeDispatch / #resumeChangeDispatch', function() {
|
||||
it('prevents change events from getting dispatched', function() {
|
||||
history.perform(action, 'base');
|
||||
history.perform(actionNoop, 'base');
|
||||
history.on('change', spy);
|
||||
|
||||
history.pauseChangeDispatch();
|
||||
|
||||
history.perform(action, 'perform');
|
||||
history.perform(actionNoop, 'perform');
|
||||
expect(spy).to.have.been.notCalled;
|
||||
history.replace(action, 'replace');
|
||||
history.replace(actionNoop, 'replace');
|
||||
expect(spy).to.have.been.notCalled;
|
||||
history.overwrite(action, 'replace');
|
||||
history.overwrite(actionNoop, 'replace');
|
||||
expect(spy).to.have.been.notCalled;
|
||||
history.undo();
|
||||
expect(spy).to.have.been.notCalled;
|
||||
@@ -286,8 +291,31 @@ describe('iD.History', function () {
|
||||
history.pop();
|
||||
expect(spy).to.have.been.notCalled;
|
||||
|
||||
var difference = history.resumeChangeDispatch();
|
||||
expect(spy).to.have.been.calledOnceWith(difference);
|
||||
var diff = history.resumeChangeDispatch();
|
||||
expect(spy).to.have.been.calledOnceWith(diff);
|
||||
});
|
||||
|
||||
it('does nothing if resume called before pause', function() {
|
||||
history.perform(actionNoop, 'base');
|
||||
history.on('change', spy);
|
||||
|
||||
history.resumeChangeDispatch();
|
||||
expect(spy).to.have.been.notCalled;
|
||||
});
|
||||
|
||||
it('uses earliest difference if pause called multiple times', function() {
|
||||
history.perform(actionNoop, 'base');
|
||||
history.on('change', spy);
|
||||
|
||||
history.pauseChangeDispatch();
|
||||
history.perform(actionAddNode('a'), 'perform');
|
||||
|
||||
history.pauseChangeDispatch();
|
||||
history.perform(actionAddNode('b'), 'perform');
|
||||
|
||||
var diff = history.resumeChangeDispatch();
|
||||
expect(spy).to.have.been.calledOnceWith(diff);
|
||||
expect(diff.changes()).to.include.keys(['a', 'b']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -328,8 +356,8 @@ describe('iD.History', function () {
|
||||
|
||||
describe('#reset', function () {
|
||||
it('clears the version stack', function () {
|
||||
history.perform(action, 'annotation');
|
||||
history.perform(action, 'annotation');
|
||||
history.perform(actionNoop, 'annotation');
|
||||
history.perform(actionNoop, 'annotation');
|
||||
history.undo();
|
||||
history.reset();
|
||||
expect(history.undoAnnotation()).to.be.undefined;
|
||||
@@ -345,16 +373,16 @@ describe('iD.History', function () {
|
||||
|
||||
describe('#checkpoint', function () {
|
||||
it('saves and resets to checkpoints', function () {
|
||||
history.perform(action, 'annotation1');
|
||||
history.perform(action, 'annotation2');
|
||||
history.perform(action, 'annotation3');
|
||||
history.perform(actionNoop, 'annotation1');
|
||||
history.perform(actionNoop, 'annotation2');
|
||||
history.perform(actionNoop, 'annotation3');
|
||||
history.checkpoint('check1');
|
||||
history.perform(action, 'annotation4');
|
||||
history.perform(action, 'annotation5');
|
||||
history.perform(actionNoop, 'annotation4');
|
||||
history.perform(actionNoop, 'annotation5');
|
||||
history.checkpoint('check2');
|
||||
history.perform(action, 'annotation6');
|
||||
history.perform(action, 'annotation7');
|
||||
history.perform(action, 'annotation8');
|
||||
history.perform(actionNoop, 'annotation6');
|
||||
history.perform(actionNoop, 'annotation7');
|
||||
history.perform(actionNoop, 'annotation8');
|
||||
|
||||
history.reset('check1');
|
||||
expect(history.undoAnnotation()).to.equal('annotation3');
|
||||
@@ -375,8 +403,7 @@ describe('iD.History', function () {
|
||||
|
||||
describe('#toJSON', function() {
|
||||
it('doesn\'t generate unsaveable changes', function() {
|
||||
var node_1 = iD.osmNode({id: 'n-1'});
|
||||
history.perform(iD.actionAddEntity(node_1));
|
||||
history.perform(actionAddNode('n-1'));
|
||||
history.perform(iD.actionDeleteNode('n-1'));
|
||||
expect(history.toJSON()).to.be.not.ok;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user