diff --git a/src/dom_components/index.js b/src/dom_components/index.js index 5bb9bde82..40001520e 100644 --- a/src/dom_components/index.js +++ b/src/dom_components/index.js @@ -34,6 +34,7 @@ */ module.exports = () => { var c = {}; + let em; const defaults = require('./config/config'); const Component = require('./model/Component'); const ComponentView = require('./view/ComponentView'); @@ -166,7 +167,7 @@ module.exports = () => { */ init(config) { c = config || {}; - const em = c.em; + em = c.em; if (em) { c.components = em.config.components || c.components; @@ -228,7 +229,10 @@ module.exports = () => { * @private */ onLoad() { - this.getComponents().reset(c.components); + const comps = this.getComponents(); + comps.reset(c.components); + const um = em && em.get('UndoManager'); + um && um.add(comps); }, /** diff --git a/src/editor/config/config.js b/src/editor/config/config.js index 328f6b861..4e6e44742 100644 --- a/src/editor/config/config.js +++ b/src/editor/config/config.js @@ -11,9 +11,6 @@ module.exports = { // Show an alert before unload the page with unsaved changes noticeOnUnload: true, - // Enable/Disable undo manager - undoManager: true, - // Show paddings and margins showOffsets: false, @@ -80,6 +77,9 @@ module.exports = { // Dom element el: '', + // Configurations for Undo Manager + undoManager: {}, + //Configurations for Asset Manager assetManager: {}, diff --git a/src/editor/model/Editor.js b/src/editor/model/Editor.js index 8e53e51c2..610d8040a 100644 --- a/src/editor/model/Editor.js +++ b/src/editor/model/Editor.js @@ -3,6 +3,7 @@ import { isUndefined, defaults } from 'underscore'; const deps = [ require('utils'), require('keymaps'), + require('undo_manager'), require('storage_manager'), require('device_manager'), require('parser'), @@ -58,9 +59,7 @@ module.exports = Backbone.Model.extend({ // Load modules deps.forEach(name => this.loadModule(name)); - - this.initUndoManager(); - + //this.initUndoManager(); this.on('change:selectedComponent', this.componentSelected, this); this.on('change:changesCount', this.updateChanges, this); }, @@ -97,8 +96,8 @@ module.exports = Backbone.Model.extend({ // I've initialized undo manager in initialize() because otherwise the // editor will unable to fetch the instance via 'editor.UndoManager' but // I need to cleare the stack now as it was dirtied by 'onLoad' method - this.um.clear(); - this.initUndoManager(); + //this.um && this.um.clear(); + //this.initUndoManager(); this.get('modules').forEach(module => module.postLoad && module.postLoad(this) ); @@ -231,7 +230,7 @@ module.exports = Backbone.Model.extend({ /** * Initialize Undo manager * @private - * */ + * * initUndoManager() { const canvas = this.get('Canvas'); @@ -304,6 +303,7 @@ module.exports = Backbone.Model.extend({ UndoManager.addUndoType("change:src", customUndoType); } }, + */ /** * Callback on component selection diff --git a/src/grapesjs/config/config.js b/src/grapesjs/config/config.js index 941316798..004f9be89 100644 --- a/src/grapesjs/config/config.js +++ b/src/grapesjs/config/config.js @@ -18,9 +18,6 @@ module.exports = { // Enable/Disable the possibility to copy(ctrl + c) & paste(ctrl + v) components copyPaste: true, - // Enable/Disable undo manager - undoManager: true, - // Storage Manager storageManager: {}, diff --git a/src/undo_manager/index.js b/src/undo_manager/index.js index 7fd5a431c..d25628da6 100644 --- a/src/undo_manager/index.js +++ b/src/undo_manager/index.js @@ -1,5 +1,5 @@ /** - * This module allows to create shortcuts for functions and commands (via command id) + * This module allows to manage the stack of changes applied on canvas * * You can access the module in this way * ```js @@ -10,8 +10,10 @@ import UndoManager from 'backbone-undo'; module.exports = () => { + let em; let config; let um; + let beforeCache; const configDef = {}; const keymaps = {}; @@ -100,8 +102,42 @@ module.exports = () => { */ init(opts = {}) { config = { ...opts, ...configDef }; - this.em = config.em; + em = config.em; + this.em = em; um = new UndoManager({ track: true, register: [] }); + um.changeUndoType('change', { condition: false }); + const updated = () => em.trigger('change:selectedComponent'); + const customUndoType = { + on(object, value, opt = {}) { + !beforeCache && (beforeCache = object.previousAttributes()); + + if (opt.avoidStore) { + return; + } else { + const result = { + object, + before: beforeCache, + after: object.toJSON() + }; + beforeCache = null; + return result; + } + }, + + undo(model, bf, af, opt) { + model.set(bf); + updated(); + }, + + redo(model, bf, af, opt) { + model.set(af); + updated(); + } + }; + + const events = ['style', 'attributes', 'content', 'src']; + events.forEach(ev => um.addUndoType(`change:${ev}`, customUndoType)); + return this; }, @@ -145,7 +181,7 @@ module.exports = () => { * Start/resume tracking changes */ start() { - em.startTracking(); + um.startTracking(); }, @@ -153,7 +189,7 @@ module.exports = () => { * Stop tracking changes */ stop() { - em.stopTracking(); + um.stopTracking(); }, @@ -161,7 +197,7 @@ module.exports = () => { * Undo last change */ undo() { - em.undo(1); + um.undo(1); }, @@ -169,7 +205,7 @@ module.exports = () => { * Undo all changes */ undoAll() { - em.undoAll(); + um.undoAll(); }, @@ -177,7 +213,7 @@ module.exports = () => { * Redo last change */ redo() { - em.redo(1); + um.redo(1); }, @@ -185,7 +221,25 @@ module.exports = () => { * Redo all changes */ redoAll() { - em.redoAll(); + um.redoAll(); + }, + + + /** + * Checks if there is an available undo + * @return {Boolean} + */ + hasUndo() { + return um.isAvailable('undo'); + }, + + + /** + * Checks if there is an available redo + * @return {Boolean} + */ + hasRedo() { + return um.isAvailable('redo'); }, @@ -194,14 +248,14 @@ module.exports = () => { * @return {Array} */ getStack() { - + return um.stack; }, /** * Clear the stack */ clear() { - + um.clear(); } }; };