Browse Source

Refactor StorageManager

pull/36/head
Artur Arseniev 10 years ago
parent
commit
afbea10a02
  1. 84
      src/editor/model/Editor.js
  2. 3
      src/storage_manager/config/config.js
  3. 64
      src/storage_manager/main.js
  4. 24
      src/storage_manager/model/LocalStorage.js
  5. 26
      src/storage_manager/model/RemoteStorage.js
  6. 33
      test/specs/storage_manager/main.js
  7. 57
      test/specs/storage_manager/model/Models.js

84
src/editor/model/Editor.js

@ -97,6 +97,7 @@ define([
cfg.sm = this; cfg.sm = this;
this.cssc = new CssComposer(cfg); this.cssc = new CssComposer(cfg);
this.CssComposer = this.cssc;
this.set('CssComposer', this.cssc); this.set('CssComposer', this.cssc);
if(this.stm.isAutosave()) if(this.stm.isAutosave())
@ -182,7 +183,7 @@ define([
cfg.em = this; cfg.em = this;
this.cmp = new DomComponents(cfg); this.cmp = new DomComponents(cfg);
this.Components = this.cmp;
if(this.stm.isAutosave()){ if(this.stm.isAutosave()){
var md = this.cmp.getComponent(); var md = this.cmp.getComponent();
this.updateComponents( md, null, { avoidStore : 1 }); this.updateComponents( md, null, { avoidStore : 1 });
@ -227,9 +228,9 @@ define([
/** /**
* Initialize storage * Initialize storage
* */ * */
initStorage: function() initStorage: function() {
{ this.stm = new StorageManager(this.config.storageManager);
this.stm = new StorageManager(this.config.storageManager); this.StorageManager = this.stm;
this.stm.loadDefaultProviders().setCurrent(this.config.storageType); this.stm.loadDefaultProviders().setCurrent(this.config.storageType);
this.set('StorageManager', this.stm); this.set('StorageManager', this.stm);
}, },
@ -272,6 +273,7 @@ define([
pfx = cfg.stylePrefix || 'cm-'; pfx = cfg.stylePrefix || 'cm-';
cfg.stylePrefix = this.config.stylePrefix + pfx; cfg.stylePrefix = this.config.stylePrefix + pfx;
this.cm = new CodeManager(cfg); this.cm = new CodeManager(cfg);
this.CodeManager = this.cm;
this.cm.loadDefaultGenerators().loadDefaultViewers(); this.cm.loadDefaultGenerators().loadDefaultViewers();
this.set('CodeManager', this.cm); this.set('CodeManager', this.cm);
}, },
@ -509,7 +511,79 @@ define([
if(!avSt) if(!avSt)
this.componentsUpdated(); this.componentsUpdated();
} },
/**
* Store data to the current storage
*/
store: function(){
var sm = this.StorageManager;
var cm = this.CodeManager;
var cmp = this.Components;
var cssc = this.CssComposer;
if(!sm || !cm || !cmp)
return;
var wrp = cmp.getComponent();
var smConfig = sm.getConfig();
var store = {};
if(wrp){
if(smConfig.storeHtml)
store.html = cm.getCode(wrp, 'html');
if(smConfig.storeComponents)
store.components = JSON.stringify(cm.getCode(wrp, 'json'));
}
if(cssc){
if(smConfig.storeCss && wrp)
store.css = cm.getCode(wrp, 'css', cssc);
if(smConfig.storeStyles)
store.styles = JSON.stringify(cssc.getRules());
}
sm.store(store);
},
/**
* Load data from the current storage
*/
load: function(){
var sm = this.StorageManager;
var load = [];
if(!sm)
return;
var smConfig = sm.getConfig();
if(smConfig.storeHtml)
load.push('html');
if(smConfig.storeComponents)
load.push('components');
if(smConfig.storeCss)
load.push('css');
if(smConfig.storeStyles)
load.push('styles');
var result = sm.load(load);
if(result.components){
try{
var comps = JSON.parse(result.components);
this.setComponents(comps);
}catch(err){}
}else if(result.html){
this.setComponents(result.html);
}
},
}); });
}); });

3
src/storage_manager/config/config.js

@ -1,6 +1,9 @@
define(function () { define(function () {
return { return {
// Prefix identifier that will be used inside storing and loading
id: 'gjs-',
// Enable/Disable autosaving // Enable/Disable autosaving
autosave: 1, autosave: 1,

64
src/storage_manager/main.js

@ -20,6 +20,8 @@
* *
* @module StorageManager * @module StorageManager
* @param {Object} config Configurations * @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 {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 * @param {number} [config.stepsBeforeSave=1] If autosave enabled, indicates how many steps/changes are necessary
* before autosave is triggered * before autosave is triggered
@ -100,11 +102,17 @@ define(function(require) {
* @return {this} * @return {this}
* @example * @example
* storageManager.add('local2', { * storageManager.add('local2', {
* load: function(item){ * load: function(keys){
* return localStorage.getItem(name); * var res = {};
* for (var i = 0, len = keys.length; i < len; i++){
* var v = localStorage.getItem(keys[i]);
* if(v) res[keys[i]] = v;
* }
* return res;
* }, * },
* store: function(item, value){ * store: function(data){
* localStorage.setItem(item, value); * for(var key in data)
* localStorage.setItem(key, data[key]);
* } * }
* }); * });
* */ * */
@ -149,24 +157,43 @@ define(function(require) {
}, },
/** /**
* Store resource in the current storage * Store key-value resources in the current storage
* @param {String} name Resource's name * @param {Object} data Data in key-value format, eg. {item1: value1, item2: value2}
* @param {String} value Resource's value
* @return {Object|null} * @return {Object|null}
* @example
* storageManager.store({item1: value1, item2: value2});
* */ * */
store: function(name, value){ store: function(data){
var st = this.get(this.getCurrent()); var st = this.get(this.getCurrent());
return st ? st.store(name, value) : null; var dataF = {};
for(var key in data)
dataF[c.id + key] = data[key];
return st ? st.store(dataF) : null;
}, },
/** /**
* Load resource from the current storage * Load resource from the current storage by keys
* @param {string} name Resource's name * @param {string|Array<string>} keys Keys to load
* @return {Object|null} Loaded resource * @return {Object|null} Loaded resources
* @example
* var data = storageManager.load(['item1', 'item2']);
* // data -> {item1: value1, item2: value2}
* var data2 = storageManager.load('item1');
* // data2 -> {item1: value1}
* */ * */
load: function(name){ load: function(keys){
var st = this.get(this.getCurrent()); var st = this.get(this.getCurrent());
return st ? st.load(name) : null; var keysF = [];
if(typeof keys === 'string')
keys = [keys];
for (var i = 0, len = keys.length; i < len; i++)
keysF.push(c.id + keys[i]);
return st ? st.load(keysF) : null;
}, },
/** /**
@ -180,6 +207,15 @@ define(function(require) {
return this; return this;
}, },
/**
* Get configuration object
* @return {Object}
* @private
* */
getConfig : function() {
return c;
},
}; };
}; };

24
src/storage_manager/model/LocalStorage.js

@ -8,21 +8,33 @@ define(['backbone'],
}, },
/** @inheritdoc */ /** @inheritdoc */
store: function(name, value) { store: function(data) {
this.checkStorageEnvironment(); this.checkStorageEnvironment();
localStorage.setItem(name, value);
for(var key in data)
localStorage.setItem(key, data[key]);
}, },
/** @inheritdoc */ /** @inheritdoc */
load: function(name){ load: function(keys){
this.checkStorageEnvironment(); this.checkStorageEnvironment();
return localStorage.getItem(name); var result = {};
for (var i = 0, len = keys.length; i < len; i++){
var value = localStorage.getItem(keys[i]);
if(value)
result[keys[i]] = value;
}
return result;
}, },
/** @inheritdoc */ /** @inheritdoc */
remove: function(name) { remove: function(keys) {
this.checkStorageEnvironment(); this.checkStorageEnvironment();
localStorage.removeItem(name);
for (var i = 0, len = keys.length; i < len; i++)
localStorage.removeItem(keys[i]);
}, },
/** /**

26
src/storage_manager/model/RemoteStorage.js

@ -14,13 +14,15 @@ define(['backbone'],
}, },
/** @inheritdoc */ /** @inheritdoc */
store: function(name, value) { store: function(data) {
var fd = new FormData(), var fd = {},
params = this.get('params'); params = this.get('params');
fd.append(name, value);
for(var k in data)
fd[k] = data[k];
for(var key in params) for(var key in params)
fd.append(key, params[key]); fd[key] = params[key];
$.ajax({ $.ajax({
url: this.get('urlStore'), url: this.get('urlStore'),
@ -34,17 +36,25 @@ define(['backbone'],
}, },
/** @inheritdoc */ /** @inheritdoc */
load: function(name){ load: function(keys){
var result = null; var result = {},
fd = {},
params = this.get('params');
for(var key in params)
fd[key] = params[key];
fd.keys = keys;
$.ajax({ $.ajax({
url: this.get('urlLoad'), url: this.get('urlLoad'),
beforeSend: this.get('beforeSend'), beforeSend: this.get('beforeSend'),
complete: this.get('onComplete'), complete: this.get('onComplete'),
data: this.get('paramsLoad'), data: fd,
async: false, async: false,
type: 'GET', type: 'GET',
}).done(function(d){ }).done(function(d){
result = d.data ? d.data[name] : d[name]; result = d;
}); });
return result; return result;
}, },

33
test/specs/storage_manager/main.js

@ -64,11 +64,11 @@ define([
}); });
it('Store do not execute if empty', function() { it('Store do not execute if empty', function() {
(obj.store('item','test') === null).should.equal(true); (obj.store({item:'test'}) === null).should.equal(true);
}); });
it('Load do not execute if empty', function() { it('Load do not execute if empty', function() {
(obj.load('item') === null).should.equal(true); (obj.load(['item']) === null).should.equal(true);
}); });
it('Load default storages ', function() { it('Load default storages ', function() {
@ -83,11 +83,11 @@ define([
var storeValue; var storeValue;
var storageId = 'testStorage'; var storageId = 'testStorage';
var storage = { var storage = {
store: function(n, v){ store: function(data){
storeValue[n] = v; storeValue = data;
}, },
load: function(n){ load: function(keys){
return storeValue[n]; return storeValue;
}, },
}; };
@ -104,14 +104,19 @@ define([
}); });
it('Store and load data', function() { it('Store and load data', function() {
obj.store('item','testData'); var data = {
storeValue['item'].should.equal('testData'); item: 'testData',
obj.load('item').should.equal('testData'); item2: 'testData2',
}); };
var data2 = {};
it('Load inexistent data', function() { var id = obj.getConfig().id;
obj.store('item','testData'); data2[id + 'item'] = 'testData';
(obj.load('item2') === undefined).should.equal(true); data2[id + 'item2'] = 'testData2';
obj.store(data);
var load = obj.load(['item', 'item2']);
storeValue.should.deep.equal(data2);
load.should.deep.equal(data2);
}); });
}); });

57
test/specs/storage_manager/model/Models.js

@ -10,6 +10,10 @@ define([path + 'LocalStorage',
var obj; var obj;
var itemName = 'testItem'; var itemName = 'testItem';
var data = {
'item1': 'value1',
'item2': 'value2',
};
beforeEach(function () { beforeEach(function () {
obj = new LocalStorage(); obj = new LocalStorage();
@ -19,15 +23,29 @@ define([path + 'LocalStorage',
delete obj; delete obj;
}); });
it('Store and load item', function() { it('Store and load items', function() {
obj.store(itemName, 'test'); obj.store(data);
obj.load(itemName).should.equal('test'); var result = obj.load(['item1', 'item2']);
result.should.deep.equal(data);
}); });
it('Remove item', function() { it('Store, update and load items', function() {
obj.store(itemName, 'test'); obj.store(data);
obj.remove(itemName); obj.store({item3: 'value3'});
(obj.load(itemName) === null).should.equal(true); obj.store({item2: 'value22'});
var result = obj.load(['item1', 'item2', 'item3']);
result.should.deep.equal({
'item1': 'value1',
'item2': 'value22',
'item3': 'value3',
});
});
it('Remove items', function() {
var items = ['item1', 'item2', 'item3'];
obj.store(data);
obj.remove(items);
obj.load(items).should.be.empty;
}); });
}); });
@ -40,8 +58,13 @@ define([path + 'LocalStorage',
var endpointLoad = 'testLoadEndpoint'; var endpointLoad = 'testLoadEndpoint';
var params = { test: 'testValue' }; var params = { test: 'testValue' };
var storageOptions; var storageOptions;
var data;
beforeEach(function () { beforeEach(function () {
data = {
'item1': 'value1',
'item2': 'value2',
};
storageOptions = { storageOptions = {
urlStore: endpointStore, urlStore: endpointStore,
urlLoad: endpointLoad, urlLoad: endpointLoad,
@ -57,11 +80,14 @@ define([path + 'LocalStorage',
it('Store data', function() { it('Store data', function() {
sinon.stub($, "ajax"); sinon.stub($, "ajax");
obj.store(itemName, 'test');
var data = params; for(var k in params)
data.itemName = 'test'; data[k] = params[k];
obj.store(data);
$.ajax.calledWithMatch({ $.ajax.calledWithMatch({
url: endpointStore, url: endpointStore,
data: data,
}).should.equal(true); }).should.equal(true);
}); });
@ -69,10 +95,17 @@ define([path + 'LocalStorage',
sinon.stub($, "ajax").returns({ sinon.stub($, "ajax").returns({
done: function(){} done: function(){}
}); });
obj.load(itemName); var dt = {};
var data = params; var keys = ['item1', 'item2'];
obj.load(keys);
dt.keys = keys;
for(var k in params)
dt[k] = params[k];
$.ajax.calledWithMatch({ $.ajax.calledWithMatch({
url: endpointLoad, url: endpointLoad,
data: dt
}).should.equal(true); }).should.equal(true);
}); });

Loading…
Cancel
Save