mirror of https://github.com/artf/grapesjs.git
20 changed files with 446 additions and 4 deletions
@ -0,0 +1,7 @@ |
|||||
|
define(function () { |
||||
|
return { |
||||
|
|
||||
|
'blocks': [], |
||||
|
|
||||
|
}; |
||||
|
}); |
||||
@ -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; |
||||
|
}, |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
}); |
||||
@ -0,0 +1,13 @@ |
|||||
|
define(['backbone'], |
||||
|
function(Backbone){ |
||||
|
|
||||
|
return Backbone.Model.extend({ |
||||
|
|
||||
|
defaults :{ |
||||
|
label: '', |
||||
|
content: '', |
||||
|
attributes: {}, |
||||
|
}, |
||||
|
|
||||
|
}); |
||||
|
}); |
||||
@ -0,0 +1,9 @@ |
|||||
|
define(['backbone','./Block'], |
||||
|
function (Backbone, Block) { |
||||
|
|
||||
|
return Backbone.Collection.extend({ |
||||
|
|
||||
|
model: Block, |
||||
|
|
||||
|
}); |
||||
|
}); |
||||
@ -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; |
||||
|
}, |
||||
|
|
||||
|
}); |
||||
|
}); |
||||
@ -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; |
||||
|
}, |
||||
|
|
||||
|
}); |
||||
|
}); |
||||
@ -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'; |
||||
|
} |
||||
|
}; |
||||
|
}); |
||||
@ -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(); |
||||
|
|
||||
|
}); |
||||
|
}); |
||||
@ -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…
Reference in new issue