diff --git a/src/storage_manager/config/config.js b/src/storage_manager/config/config.js index 425523473..ec105ca70 100644 --- a/src/storage_manager/config/config.js +++ b/src/storage_manager/config/config.js @@ -57,6 +57,16 @@ export default { fetchOptions: '', credentials: 'include', + + /** + * Edit project data before sending them to the storage. + */ + onStore: data => data, + + /** + * Edit project data before loading them from the storage. + */ + onLoad: result => result, }, }, }; diff --git a/src/storage_manager/index.js b/src/storage_manager/index.js index 3c371a1e1..d0b41fbb6 100644 --- a/src/storage_manager/index.js +++ b/src/storage_manager/index.js @@ -53,6 +53,7 @@ import defaults from './config/config'; import LocalStorage from './model/LocalStorage'; import RemoteStorage from './model/RemoteStorage'; +import { deepMerge } from 'utils/mixins'; const eventStart = 'storage:start'; const eventAfter = 'storage:after'; @@ -66,33 +67,10 @@ export default () => { var defaultStorages = {}; return { - /** - * Name of the module - * @type {String} - * @private - */ name: 'StorageManager', - /** - * Initialize module. Automatically called with a new instance of the editor - * @param {Object} config Configurations - * @param {string} [config.id='gjs-'] The prefix for the fields, useful to differentiate storing/loading - * with multiple editors on the same page. For example, in local storage, the item of HTML will be saved like 'gjs-html' - * @param {Boolean} [config.autosave=true] Indicates if autosave mode is enabled, works in conjunction with stepsBeforeSave - * @param {number} [config.stepsBeforeSave=1] If autosave enabled, indicates how many steps/changes are necessary - * before autosave is triggered - * @param {string} [config.type='local'] Default storage type. Available: 'local' | 'remote' | ''(do not store) - * @private - * @example - * ... - * { - * autosave: false, - * type: 'remote', - * } - * ... - */ init(config = {}) { - c = { ...defaults, ...config }; + c = deepMerge(defaults, config); em = c.em; if (c._disable) c.type = 0; defaultStorages.remote = new RemoteStorage(c); @@ -239,8 +217,9 @@ export default () => { async load(options = {}) { const st = this.getCurrentStorage(); const opts = { ...this.getCurrentOptons(), ...options }; - - return await this.__exec(st, opts); + const result = await this.__exec(st, opts); + console.log('onLOAD', { opts, result }); + return result; }, async __exec(storage, opts, data) { @@ -255,11 +234,13 @@ export default () => { try { if (data) { - await storage.store(data, opts); + const toStore = (opts.onStore && (await opts.onStore(data))) || data; + await storage.store(toStore, opts); result = data; } else { result = await storage.load(opts); result = this.__clearKeys(result); + result = (opts.onLoad && (await opts.onLoad(result))) || result; } this.onAfter(ev, result); this.onEnd(ev, result); diff --git a/src/utils/mixins.js b/src/utils/mixins.js index f1dd4b354..eea59a0a1 100644 --- a/src/utils/mixins.js +++ b/src/utils/mixins.js @@ -180,6 +180,27 @@ export const escape = (str = '') => { .replace(/`/g, '`'); }; +export const deepMerge = (...args) => { + const target = { ...args[0] }; + + for (let i = 1; i < args.length; i++) { + const source = { ...args[i] }; + + for (let key in source) { + const targValue = target[key]; + const srcValue = source[key]; + + if (isObject(targValue) && isObject(srcValue)) { + target[key] = deepMerge(targValue, srcValue); + } else { + target[key] = srcValue; + } + } + } + + return target; +}; + /** * Ensure to fetch the model from the input argument * @param {HTMLElement|Component} el Component or HTML element