Browse Source

Add block manager

pull/36/head
Artur Arseniev 10 years ago
parent
commit
d037e2aed7
  1. 7
      src/block_manager/config/config.js
  2. 105
      src/block_manager/main.js
  3. 13
      src/block_manager/model/Block.js
  4. 9
      src/block_manager/model/Blocks.js
  5. 17
      src/block_manager/view/BlockView.js
  6. 56
      src/block_manager/view/BlocksView.js
  7. 1
      src/commands/main.js
  8. 27
      src/commands/view/OpenBlocks.js
  9. 1
      src/config/require-config.js
  10. 3
      src/demo.js
  11. 1
      src/device_manager/main.js
  12. 19
      src/editor/config/config.js
  13. 5
      src/editor/main.js
  14. 14
      src/editor/model/Editor.js
  15. 1
      src/panels/main.js
  16. 2
      styles/css/main.css
  17. 2
      styles/scss/main.scss
  18. 1
      test/runner/main.js
  19. 76
      test/specs/block_manager/main.js
  20. 90
      test/specs/block_manager/view/BlocksView.js

7
src/block_manager/config/config.js

@ -0,0 +1,7 @@
define(function () {
return {
'blocks': [],
};
});

105
src/block_manager/main.js

@ -0,0 +1,105 @@
/**
* * [add](#add)
* * [get](#get)
* * [getAll](#getall)
* * [render](#render)
*
* Block manager helps managing various, draggable, pieces of content that could be reused inside templates.
*
* Before using methods you should get first the module from the editor instance, in this way:
*
* ```js
* var blockManager = editor.BlockManager;
* ```
*
* @module BlockManager
* @param {Object} config Configurations
* @param {Array<Object>} [config.blocks=[]] Default blocks
* @example
* ...
* blockManager: {
* blocks: [
* {id:'h1-block' label: 'Heading', content:'<h1>...</h1>'},
* ...
* ],
* }
* ...
*/
define(function(require) {
return function(config) {
var c = config || {},
defaults = require('./config/config'),
Blocks = require('./model/Blocks'),
BlocksView = require('./view/BlocksView');
for (var name in defaults) {
if (!(name in c))
c[name] = defaults[name];
}
var blocks = new Blocks(c.blocks);
var view = new BlocksView({ collection: blocks }, c);
return {
/**
* Add new block to the collection.
* @param {string} id Block id
* @param {Object} opts Options
* @param {string} opts.label Name of the block
* @param {string} opts.content HTML content
* @param {Object} [opts.attributes={}] Block attributes
* @return {Block} Added block
* @example
* blockManager.add('h1-block', {
* label: 'Heading',
* content: '<h1>Put your title here</h1>',
* attributes: {
* title: 'Insert h1 block'
* }
* });
*/
add: function(id, opts){
var obj = opts || {};
obj.id = id;
return blocks.add(obj);
},
/**
* Return block by id
* @param {string} id Block id
* @example
* var block = blockManager.get('h1-block');
* console.log(JSON.stringify(block));
* // {label: 'Heading', content: '<h1>Put your ...', ...}
*/
get: function(id){
return blocks.get(id);
},
/**
* Return all blocks
* @return {Collection}
* @example
* var blocks = blockManager.getAll();
* console.log(JSON.stringify(blocks));
* // [{label: 'Heading', content: '<h1>Put your ...'}, ...]
*/
getAll: function(){
return blocks;
},
/**
* Render blocks
* @return {HTMLElement}
*/
render: function(){
return view.render().el;
},
};
};
});

13
src/block_manager/model/Block.js

@ -0,0 +1,13 @@
define(['backbone'],
function(Backbone){
return Backbone.Model.extend({
defaults :{
label: '',
content: '',
attributes: {},
},
});
});

9
src/block_manager/model/Blocks.js

@ -0,0 +1,9 @@
define(['backbone','./Block'],
function (Backbone, Block) {
return Backbone.Collection.extend({
model: Block,
});
});

17
src/block_manager/view/BlockView.js

@ -0,0 +1,17 @@
define(['backbone'],
function(Backbone) {
return Backbone.View.extend({
initialize: function(o) {
this.config = o.config || {};
this.listenTo(this.model, 'destroy', this.remove);
},
render: function() {
this.el.innerHTML = this.model.get('label');
return this;
},
});
});

56
src/block_manager/view/BlocksView.js

@ -0,0 +1,56 @@
define(['backbone', './BlockView'],
function(Backbone, BlockView) {
return Backbone.View.extend({
initialize: function(opts, config) {
this.config = config || {};
this.ppfx = this.config.pStylePrefix || '';
this.listenTo(this.collection, 'add', this.addTo);
},
/**
* Add new model to the collection
* @param {Model} model
* @private
* */
addTo: function(model){
this.add(model);
},
/**
* Render new model inside the view
* @param {Model} model
* @param {Object} fragment Fragment collection
* */
add: function(model, fragment){
var frag = fragment || null;
var view = new BlockView({
model: model,
attributes: model.get('attributes'),
}, this.config);
var rendered = view.render().el;
if(frag)
frag.appendChild(rendered);
else
this.$el.append(rendered);
},
render: function() {
var frag = document.createDocumentFragment();
this.$el.empty();
this.collection.each(function(model){
this.add(model, frag);
}, this);
this.$el.append(frag);
this.$el.addClass(this.ppfx + 'blocks-c');
return this;
},
});
});

1
src/commands/main.js

@ -80,6 +80,7 @@ define(function(require) {
defaultCommands['sw-visibility'] = require('./view/SwitchVisibility'); defaultCommands['sw-visibility'] = require('./view/SwitchVisibility');
defaultCommands['open-layers'] = require('./view/OpenLayers'); defaultCommands['open-layers'] = require('./view/OpenLayers');
defaultCommands['open-sm'] = require('./view/OpenStyleManager'); defaultCommands['open-sm'] = require('./view/OpenStyleManager');
defaultCommands['open-blocks'] = require('./view/OpenBlocks');
//this.defaultCommands['resize-comp'] = require('./view/ResizeComponent'); //this.defaultCommands['resize-comp'] = require('./view/ResizeComponent');
if(config.em) if(config.em)

27
src/commands/view/OpenBlocks.js

@ -0,0 +1,27 @@
define(function() {
return {
run: function(editor, sender) {
var config = editor.Config;
var pfx = config.stylePrefix;
var bm = editor.BlockManager;
if(!this.blocks){
this.blocks = bm.render();
var panels = editor.Panels;
if(!panels.getPanel('views-container'))
panelC = panels.addPanel({id: 'views-container'});
else
panelC = panels.getPanel('views-container');
panelC.set('appendContent', this.blocks).trigger('change:appendContent');
}
this.blocks.style.display = 'block';
},
stop: function() {
if(this.blocks)
this.blocks.style.display = 'none';
}
};
});

1
src/config/require-config.js

@ -36,6 +36,7 @@ require.config({
{ name: 'GrapesJS', location: 'grapesjs', }, { name: 'GrapesJS', location: 'grapesjs', },
{ name: 'Editor', location: 'editor', }, { name: 'Editor', location: 'editor', },
{ name: 'AssetManager', location: 'asset_manager', }, { name: 'AssetManager', location: 'asset_manager', },
{ name: 'BlockManager', location: 'block_manager', },
{ name: 'StyleManager', location: 'style_manager', }, { name: 'StyleManager', location: 'style_manager', },
{ name: 'ClassManager', location: 'class_manager', }, { name: 'ClassManager', location: 'class_manager', },
{ name: 'DeviceManager', location: 'device_manager', }, { name: 'DeviceManager', location: 'device_manager', },

3
src/demo.js

@ -65,6 +65,7 @@ panels: {
id : 'selcomp', id : 'selcomp',
className : 'fa fa fa-mouse-pointer', className : 'fa fa fa-mouse-pointer',
command : 'select-comp', command : 'select-comp',
active: 1,
},{ },{
id : 'create', id : 'create',
className : 'fa fa-plus-square-o icon-add-comp', className : 'fa fa-plus-square-o icon-add-comp',
@ -410,6 +411,8 @@ panels: {
); );
window.grapesEditor = editor;
}); });
}); });

1
src/device_manager/main.js

@ -50,7 +50,6 @@ define(function(require) {
* @param {Object} opts Custom options * @param {Object} opts Custom options
* @return {Device} Added device * @return {Device} Added device
* @example * @example
* // In case of strings, would be interpreted as images
* deviceManager.add('Tablet', '900px'); * deviceManager.add('Tablet', '900px');
*/ */
add: function(name, width, opts){ add: function(name, width, opts){

19
src/editor/config/config.js

@ -38,7 +38,7 @@ define(function () {
storageType: 'local', storageType: 'local',
// The css that could only be seen (for instance, inside the code viewer) // The css that could only be seen (for instance, inside the code viewer)
protectedCss: 'body{margin:0;}', protectedCss: 'body{margin:0;height:100%}#wrapper{height:100%}',
//Configurations for Asset Manager //Configurations for Asset Manager
assetManager : {}, assetManager : {},
@ -96,6 +96,23 @@ define(function () {
}], }],
}, },
//Configurations for Block Manager
blockManager: {
'blocks': [{
id: 'b1',
label: 'Block1',
content: '<h1>Block 1</h1>',
},{
id: 'b2',
label: 'Block2',
content: '<h1>Block 2</h1>',
},{
id: 'b3',
label: 'Block3',
content: '<h1>Block 3</h1>',
}],
},
// If true render a select of available devices // If true render a select of available devices
showDevices: 1, showDevices: 1,

5
src/editor/main.js

@ -95,6 +95,11 @@ define(function (require){
*/ */
AssetManager: em.get('AssetManager'), AssetManager: em.get('AssetManager'),
/**
* @property {BlockManager}
*/
BlockManager: em.get('BlockManager'),
/** /**
* @property {ClassManager} * @property {ClassManager}
*/ */

14
src/editor/model/Editor.js

@ -3,6 +3,7 @@ define([
'backboneUndo', 'backboneUndo',
'keymaster', 'keymaster',
'AssetManager', 'AssetManager',
'BlockManager',
'StorageManager', 'StorageManager',
'DeviceManager', 'DeviceManager',
'ModalDialog', 'ModalDialog',
@ -22,6 +23,7 @@ define([
UndoManager, UndoManager,
Keymaster, Keymaster,
AssetManager, AssetManager,
BlockManager,
StorageManager, StorageManager,
DeviceManager, DeviceManager,
ModalDialog, ModalDialog,
@ -63,6 +65,7 @@ define([
this.initClassManager(); this.initClassManager();
this.initModal(); this.initModal();
this.initAssetManager(); this.initAssetManager();
this.initBlockManager();
this.initCodeManager(); this.initCodeManager();
this.initCommands(); this.initCommands();
this.initPanels(); this.initPanels();
@ -87,6 +90,17 @@ define([
this.set('Editor', editor); this.set('Editor', editor);
}, },
/**
* Initialize block manager
* @private
* */
initBlockManager: function(){
var cfg = this.config.blockManager;
cfg.em = this;
cfg.pStylePrefix = this.config.stylePrefix;
this.set('BlockManager', new BlockManager(cfg));
},
/** /**
* Initialize device manager * Initialize device manager
* @private * @private

1
src/panels/main.js

@ -52,6 +52,7 @@ define(function(require) {
defaults = require('./config/config'), defaults = require('./config/config'),
Panel = require('./model/Panel'), Panel = require('./model/Panel'),
Panels = require('./model/Panels'), Panels = require('./model/Panels'),
PanelView = require('./view/PanelView'),
PanelsView = require('./view/PanelsView'); PanelsView = require('./view/PanelsView');
// Set default options // Set default options

2
styles/css/main.css

@ -2846,7 +2846,7 @@ ol.example li.placeholder:before {
z-index: 4; } z-index: 4; }
.wte-pn-panel#wte-pn-views-container { .wte-pn-panel#wte-pn-views-container {
height: 100%; height: 100%;
padding: 52px 0 0; padding: 42px 0 0;
right: 0; right: 0;
width: 15%; width: 15%;
overflow: auto; overflow: auto;

2
styles/scss/main.scss

@ -353,7 +353,7 @@ $leftWidth: 15%;
&##{$pn-prefix}views-container{ &##{$pn-prefix}views-container{
height: 100%; height: 100%;
padding: 52px 0 0; padding: 42px 0 0;
right: 0; right: 0;
width: $leftWidth; width: $leftWidth;
overflow: auto; overflow: auto;

1
test/runner/main.js

@ -21,6 +21,7 @@ require(['../src/config/require-config.js', 'config/config.js'], function() {
'specs/style_manager/main.js', 'specs/style_manager/main.js',
'specs/storage_manager/main.js', 'specs/storage_manager/main.js',
'specs/plugin_manager/main.js', 'specs/plugin_manager/main.js',
'specs/block_manager/main.js',
'specs/parser/main.js', 'specs/parser/main.js',
'specs/grapesjs/main.js', 'specs/grapesjs/main.js',
'specs/utils/main.js' 'specs/utils/main.js'

76
test/specs/block_manager/main.js

@ -0,0 +1,76 @@
var modulePath = './../../../test/specs/block_manager';
define([ 'BlockManager',
modulePath + '/view/BlocksView',
],
function(BlockManager, BlocksView) {
describe('BlockManager', function() {
describe('Main', function() {
var obj;
var idTest;
var optsTest;
beforeEach(function () {
idTest = 'h1-block';
optsTest = {
label: 'Heading',
content: '<h1>Test</h1>'
};
obj = new BlockManager();
});
afterEach(function () {
delete obj;
});
it('Object exists', function() {
obj.should.be.exist;
});
it('No blocks inside', function() {
var coll = obj.getAll();
coll.length.should.equal(0);
});
it('Add new block', function() {
var model = obj.add(idTest, optsTest);
obj.getAll().length.should.equal(1);
});
it('Added block has correct data', function() {
var model = obj.add(idTest, optsTest);
model.get('label').should.equal(optsTest.label);
model.get('content').should.equal(optsTest.content);
});
it('Add block with attributes', function() {
optsTest.attributes = {'class':'test'};
var model = obj.add(idTest, optsTest);
model.get('attributes').class.should.equal('test');
});
it('The id of the block is unique', function() {
var model = obj.add(idTest, optsTest);
var model2 = obj.add(idTest, {other: 'test'});
model.should.deep.equal(model2);
});
it('Get block by id', function() {
var model = obj.add(idTest, optsTest);
var model2 = obj.get(idTest);
model.should.deep.equal(model2);
});
it('Render blocks', function() {
obj.render().should.be.ok;
});
});
BlocksView.run();
});
});

90
test/specs/block_manager/view/BlocksView.js

@ -0,0 +1,90 @@
var path = 'BlockManager/view/';
define([path + 'BlocksView', 'BlockManager/model/Blocks'],
function(BlocksView, Blocks) {
return {
run : function(){
describe('BlocksView', function() {
var $fixtures;
var $fixture;
var model;
var view;
var editorModel;
var ppfx;
before(function () {
$fixtures = $("#fixtures");
$fixture = $('<div class="devices-fixture"></div>');
});
beforeEach(function () {
model = new Blocks([]);
view = new BlocksView({ collection: model });
$fixture.empty().appendTo($fixtures);
$fixture.html(view.render().el);
});
afterEach(function () {
view.collection.reset();
});
after(function () {
$fixture.remove();
});
it("The container is not empty", function (){
view.el.outerHTML.should.be.not.empty;
});
it("No children inside", function (){
view.el.children.length.should.equal(0);
});
it("Render children on add", function (){
model.add({});
view.el.children.length.should.equal(1);
model.add([{},{}]);
view.el.children.length.should.equal(3);
});
it("Destroy children on remove", function (){
model.add([{},{}]);
view.el.children.length.should.equal(2);
model.at(0).destroy();
view.el.children.length.should.equal(1);
});
describe('With configs', function() {
beforeEach(function () {
ppfx = 'pfx-t-';
editorModel = new Backbone.Model();
model = new Blocks([
{name:'test1'},
{name:'test2'}
]);
view = new BlocksView({
collection: model,
},{
pStylePrefix: ppfx
});
$fixture.empty().appendTo($fixtures);
$fixture.html(view.render().el);
});
it("Render children", function (){
view.el.children.length.should.equal(2);
});
it("Render children", function (){
view.el.getAttribute('class').should.equal(ppfx + 'blocks-c');
});
});
});
}
};
});
Loading…
Cancel
Save