Browse Source

Fix for undo manager

pull/2732/head
Artur Arseniev 6 years ago
parent
commit
d9c5ff94ac
  1. 16
      src/dom_components/model/Component.js
  2. 4
      src/dom_components/model/Components.js
  3. 12
      src/undo_manager/index.js
  4. 35
      test/specs/editor/index.js

16
src/dom_components/model/Component.js

@ -1252,6 +1252,22 @@ const Component = Backbone.Model.extend(Styleable).extend(
return { tagName: el.tagName ? el.tagName.toLowerCase() : '' };
},
ensureInList(model) {
const list = Component.getList(model);
const id = model.getId();
const current = list[id];
if (!current) {
// Insert in list
list[id] = model;
} else if (current !== model) {
// Create new ID
const nextId = Component.getIncrementId(id, list);
model.setId(nextId);
list[nextId] = model;
}
},
/**
* Relying simply on the number of components becomes a problem when you
* store and load them back, you might hit collisions with new components

4
src/dom_components/model/Components.js

@ -18,6 +18,7 @@ export default Backbone.Collection.extend({
const coll = this;
const { previousModels = [] } = opts;
previousModels.forEach(md => this.removeChildren(md, coll, opts));
models.each(model => this.onAdd(model));
},
removeChildren(removed, coll, opts = {}) {
@ -186,9 +187,10 @@ export default Backbone.Collection.extend({
},
onAdd(model, c, opts = {}) {
const em = this.em;
const { domc, em } = this;
const style = model.getStyle();
const avoidInline = em && em.getConfig('avoidInlineStyle');
domc.Component.ensureInList(model);
if (
!isEmpty(style) &&

12
src/undo_manager/index.js

@ -182,8 +182,8 @@ export default () => {
* @example
* um.undo();
*/
undo() {
!em.isEditing() && um.undo(1);
undo(all = true) {
!em.isEditing() && um.undo(all);
return this;
},
@ -204,8 +204,8 @@ export default () => {
* @example
* um.redo();
*/
redo() {
!em.isEditing() && um.redo(1);
redo(all = true) {
!em.isEditing() && um.redo(all);
return this;
},
@ -276,6 +276,10 @@ export default () => {
return result;
},
getPointer() {
return this.getStack().pointer;
},
/**
* Clear the stack
* @return {this}

35
test/specs/editor/index.js

@ -70,18 +70,47 @@ describe('Editor', () => {
expect(keys(all).length).toBe(initComps);
});
test.only('Components are correctly tracked with UndoManager', () => {
test('Components are correctly tracked with UndoManager', () => {
editor.Components.postLoad(); // Init UndoManager
const all = editor.Components.allById();
const um = editor.UndoManager;
const umStack = um.getStack();
const wrapper = editor.getWrapper();
expect(umStack.length).toBe(0);
wrapper.append(`<div>Component 1</div><div>Component 2</div>`);
const comp = wrapper.append(`<div>Component 1</div>`)[0];
expect(umStack.length).toBe(1);
wrapper.empty();
console.log('Post reset', umStack);
expect(umStack.length).toBe(2);
expect(keys(all).length).toBe(initComps);
um.undo(false);
expect(keys(all).length).toBe(1 + initComps);
});
test('Components are correctly tracked with UndoManager and mutiple operations', () => {
editor.Components.postLoad(); // Init UndoManager
const all = editor.Components.allById();
const um = editor.UndoManager;
const umStack = um.getStack();
const wrapper = editor.getWrapper();
expect(umStack.length).toBe(0);
wrapper.append(`<div>
<div>Component 1</div>
<div>Component 2</div>
</div>`);
expect(umStack.length).toBe(1); // UM counts first children
expect(keys(all).length).toBe(3 + initComps);
wrapper
.components()
.at(0)
.components()
.at(0)
.remove(); // Remove 1 component
// UM registers 2 identical remove undoTypes as Backbone triggers remove from the
// collection and the model
expect(umStack.length).toBe(3);
expect(keys(all).length).toBe(2 + initComps);
wrapper.empty();
expect(umStack.length).toBe(4);
expect(keys(all).length).toBe(initComps);
});
});

Loading…
Cancel
Save