Browse Source

Merge branch 'css-composer' into dev with few updates

pull/14/head
Artur Arseniev 10 years ago
parent
commit
2273fb8cfa
  1. 2
      src/class_manager/config/config.js
  2. 15
      src/class_manager/view/ClassTagView.js
  3. 102
      src/code_manager/main.js
  4. 63
      src/code_manager/model/CssGenerator.js
  5. 27
      src/code_manager/model/HtmlGenerator.js
  6. 4
      src/commands/view/ExportTemplate.js
  7. 2
      src/style_manager/view/SectorsView.js
  8. 1
      test/runner/main.js
  9. 25
      test/specs/class_manager/view/ClassTagView.js
  10. 39
      test/specs/code_manager/main.js
  11. 106
      test/specs/code_manager/model/CodeModels.js

2
src/class_manager/config/config.js

@ -11,7 +11,7 @@ define(function () {
label: 'Classes',
// Label for states
statesLabel: 'State',
statesLabel: '',
};
});

15
src/class_manager/view/ClassTagView.js

@ -13,6 +13,7 @@ define(['backbone', 'text!./../template/classTag.html'],
this.config = o.config || {};
this.coll = o.coll || null;
this.pfx = this.config.stylePrefix || '';
this.target = this.config.target;
this.className = this.pfx + 'tag';
this.closeId = this.pfx + 'close';
this.chkId = this.pfx + 'checkbox';
@ -28,6 +29,7 @@ define(['backbone', 'text!./../template/classTag.html'],
changeStatus: function(){
this.model.set('active', !this.model.get('active'));
this.target.trigger('targetClassUpdated');
},
/**
@ -35,13 +37,15 @@ define(['backbone', 'text!./../template/classTag.html'],
* @param {Object} e
*/
removeTag: function(e){
var comp = this.config.target.get('selectedComponent');
var comp = this.target.get('selectedComponent');
if(comp)
comp.get('classes').remove(this.model);
if(this.coll)
if(this.coll){
this.coll.remove(this.model);
this.target.trigger('targetClassRemoved');
}
this.remove();
},
@ -53,10 +57,13 @@ define(['backbone', 'text!./../template/classTag.html'],
if(!this.$chk)
this.$chk = this.$el.find('#' + this.pfx + 'checkbox');
if(this.model.get('active'))
if(this.model.get('active')){
this.$chk.removeClass('fa-circle-o').addClass('fa-dot-circle-o');
else
this.$el.removeClass('opac50');
}else{
this.$chk.removeClass('fa-dot-circle-o').addClass('fa-circle-o');
this.$el.addClass('opac50');
}
},
/** @inheritdoc */

102
src/code_manager/main.js

@ -2,7 +2,7 @@ define(function(require) {
/**
* @class CodeManager
* @param {Object} Configurations
*
*
* @return {Object}
* */
function CodeManager(config)
@ -21,38 +21,38 @@ define(function(require) {
if (!(name in c))
c[name] = defaults[name];
}
this.gi = new gInterface();
this.generators = {};
this.defaultGenerators = {};
this.currentGenerator = null;
this.ei = new eInterface();
this.editors = {};
this.defaultEditors = {};
this.currentEditor = null;
var geHtml = new gHtml(),
geCss = new gCss(),
geJson = new gJson(),
edCM = new eCM();
this.defaultGenerators[geHtml.getId()] = geHtml;
this.defaultGenerators[geCss.getId()] = geCss;
this.defaultGenerators[geJson.getId()] = geJson;
this.defaultEditors[edCM.getId()] = edCM;
this.EditorView = editorView;
this.config = c;
}
CodeManager.prototype = {
/**
* Add new code generator
* @param {GeneratorInterface} generator
*
*
* @return this
* */
addGenerator : function(generator)
@ -63,43 +63,43 @@ define(function(require) {
console.warn("addGenerator: method '"+ method +"' was not found");
return;
}
var id = generator.getId();
this.generators[id] = generator;
if(!this.currentGenerator)
this.currentGenerator = id;
return this;
},
/**
* Returns generator
* @param {String}|{Integer} id Generator ID
*
*
* @return {GeneratorInterface}|null
* */
getGenerator : function(id)
{
if(id && this.generators[id])
generator = this.generators[id];
return generator ? generator : null;
},
/**
* Returns generators
*
*
* @return {Array}
* */
getGenerators : function()
{
return this.generators;
},
/**
* Get current generator
*
*
* @return {GeneratorInterface}
* */
getCurrentGenerator : function()
@ -108,11 +108,11 @@ define(function(require) {
this.loadDefaultGenerators();
return this.getGenerator(this.currentGenerator);
},
/**
* Set current generator
* @param {Integer} id Generator ID
*
*
* @return this
* */
setCurrentGenerator : function(id)
@ -120,10 +120,10 @@ define(function(require) {
this.currentGenerator = id;
return this;
},
/**
* Load default generators
*
*
* @return this
* */
loadDefaultGenerators : function()
@ -131,14 +131,14 @@ define(function(require) {
for (var id in this.defaultGenerators) {
this.addGenerator(this.defaultGenerators[id]);
}
return this;
},
/**
* Add new editor
* @param {EditorInterface} editor
*
*
* @return this
* */
addEditor : function(editor)
@ -149,43 +149,43 @@ define(function(require) {
console.warn("addEditor: method '"+ method +"' was not found");
return;
}
var id = editor.getId();
this.editors[id] = editor;
if(!this.currentEditor)
this.currentEditor = id;
return this;
},
/**
* Returns editor
* @param {String}|{Integer} id Editor ID
*
*
* @return {EditorInterface}|null
* */
getEditor : function(id)
{
if(id && this.editors[id])
editor = this.editors[id];
return editor ? editor : null;
},
/**
* Returns editors
*
*
* @return {Array}
* */
getEditors : function()
{
return this.editors;
},
/**
* Get current editor
*
*
* @return {EditorInterface}
* */
getCurrentEditor : function()
@ -194,11 +194,11 @@ define(function(require) {
this.loadDefaultEditors();
return this.getEditor(this.currentEditor);
},
/**
* Set current editor
* @param {Integer} id Editor ID
*
*
* @return this
* */
setCurrentEditor : function(id)
@ -206,10 +206,10 @@ define(function(require) {
this.currentEditor = id;
return this;
},
/**
* Load default editors
*
*
* @return this
* */
loadDefaultEditors : function()
@ -217,38 +217,38 @@ define(function(require) {
for (var id in this.defaultEditors) {
this.addEditor(this.defaultEditors[id]);
}
return this;
},
/**
* Get code by name
* @param {Backbone.Model} model Model
* @param {String}|{Integer} v Id of code generator
*
*
* @return {String}|null
* */
getCode : function(model, v)
getCode : function(model, v, em)
{
var id = v || this.currentGenerator,
generator = this.generators[id];
return generator ? generator.build(model) : null;
return generator ? generator.build(model, em) : null;
},
/**
* Update editor content
* @param {EditorInteface} editor Editor
* @param {String} code Code value
*
*
* @return void
* */
updateEditor : function(editor, code)
{
editor.setContent(code);
},
};
return CodeManager;
});

63
src/code_manager/model/CssGenerator.js

@ -1,44 +1,71 @@
define(['backbone'],
define(['backbone'],
function (Backbone) {
/**
* @class CssGenerator
* */
return Backbone.Model.extend({
initialize: function(){
this.buff = [];
},
/** @inheritdoc */
getId : function()
{
return 'css';
return 'css';
},
/** @inheritdoc */
build: function(model)
build: function(model, cssc)
{
var coll = model.get('components') || model,
code = '';
coll.each(function(m){
var css = m.get('style'),
cln = m.get('components'); // Children
var css = m.get('style'),
cls = m.get('classes'),
cln = m.get('components');
// Get id-relative style
if(css && Object.keys(css).length !== 0){
code += '#' + m.cid + '{';
for(var prop in css)
if(css.hasOwnProperty(prop))
code += prop + ': ' + css[prop] + ';';
code += prop + ':' + css[prop] + ';';
code += '}';
}
if(cssc && cls.length){
var rule = cssc.getRule(cls.models);
if(rule){
var selectors = rule.get('selectors');
var ruleStyle = rule.get('style');
var strSel = '';
selectors.each(function(selector){
strSel += '.' + selector.get('name');
});
if(this.buff.indexOf(strSel) < 0){
this.buff.push(strSel);
code += strSel + '{';
if(ruleStyle && Object.keys(ruleStyle).length !== 0){
for(var prop2 in ruleStyle)
if(ruleStyle.hasOwnProperty(prop2))
code += prop2 + ':' + ruleStyle[prop2] + ';';
}
code += '}';
}
}
}
if(cln.length)
code += this.build(cln);
code += this.build(cln, cssc);
}, this);
return code;
},
});
});

27
src/code_manager/model/HtmlGenerator.js

@ -16,15 +16,18 @@ define(['backbone'],
code = '';
coll.each(function(m){
var tag = m.get('tagName'), // Tag name
sTag = 0, // Single tag
attr = '', // Attributes string
cln = m.get('components'); // Children
_.each(m.get('attributes'),function(value, prop){
var tag = m.get('tagName'), // Tag name
sTag = 0, // Single tag
attr = '', // Attributes string
attrId = '',
strCls = '',
cln = m.get('components'), // Children
attrs = m.get('attributes'),
classes = m.get('classes');
_.each(attrs,function(value, prop){
if(prop == 'onmousedown')
return;
attr += value && prop!='style' ? ' ' + prop + '="' + value + '" ' : '';
attr += value && prop!='style' ? ' ' + prop + '="' + value + '"' : '';
});
if(m.get('type') == 'image'){
@ -33,7 +36,15 @@ define(['backbone'],
attr += 'src="' + m.get('src') + '"';
}
code += '<'+tag+' id="'+m.cid+'"' + attr + (sTag ? '/' : '') + '>' + m.get('content');
if(!_.isEmpty(m.get('style')))
attrId = ' id="' + m.cid + '" ';
classes.each(function(m){
strCls += ' ' + m.get('name');
});
strCls = strCls !== '' ? ' class="' + strCls.trim() + '"' : '';
code += '<' + tag + strCls + attrId + attr + (sTag ? '/' : '') + '>' + m.get('content');
if(cln.length)
code += this.build(cln);

4
src/commands/view/ExportTemplate.js

@ -9,6 +9,7 @@ define(function() {
this.components = em.get('Canvas').getWrapper().get('components');
this.modal = em.get('Modal') || null;
this.cm = em.get('CodeManager') || null;
this.cssc = em.get('CssComposer') || null;
this.enable();
},
@ -62,7 +63,8 @@ define(function() {
}
this.htmlEditor.setContent( this.cm.getCode(this.components, 'html') );
this.cssEditor.setContent( this.cm.getCode(this.components, 'css') );
this.cm.getGenerator('css').buff = [];
this.cssEditor.setContent( this.cm.getCode(this.components, 'css', this.cssc));
if(this.sender)
this.sender.set('active',false);

2
src/style_manager/view/SectorsView.js

@ -13,7 +13,7 @@ define(['backbone','./SectorView'],
// The taget that will emit events for properties
this.propTarget = {};
_.extend(this.propTarget, Backbone.Events);
this.listenTo( this.target, 'change:selectedComponent targetClassAdded', this.targetUpdated);
this.listenTo( this.target, 'change:selectedComponent targetClassAdded targetClassRemoved targetClassUpdated', this.targetUpdated);
},

1
test/runner/main.js

@ -14,6 +14,7 @@ require(['../src/config/require-config.js', 'config/config.js'], function() {
'specs/dom_components/main.js',
'specs/class_manager/main.js',
'specs/css_composer/main.js',
'specs/code_manager/main.js',
], function(chai)
{
var should = chai.should(),

25
test/specs/class_manager/view/ClassTagView.js

@ -12,16 +12,19 @@ define([path + 'ClassTagView', 'ClassManager/model/ClassTags'],
});
beforeEach(function () {
var coll = new ClassTags();
this.coll = new ClassTags();
this.testLabel = 'TestLabel';
var model = coll.add({
var model = this.coll.add({
name: 'test',
label: this.testLabel,
});
this.view = new ClassTagView({
config : {},
model: model
model: model,
coll: this.coll
});
this.view.target = { get:function(){} };
_.extend(this.view.target, Backbone.Events);
this.$fixture.empty().appendTo(this.$fixtures);
this.$fixture.html(this.view.render().el);
});
@ -73,6 +76,14 @@ define([path + 'ClassTagView', 'ClassManager/model/ClassTags'],
this.$fixture.html().should.be.empty;
});
it('On remove triggers event', function() {
var spy = sinon.spy();
sinon.stub(this.view.target, 'get').returns(0);
this.view.target.on("targetClassRemoved", spy);
this.view.$el.find('#close').trigger('click');
spy.called.should.equal(true);
});
it('Checkbox toggles status', function() {
var spy = sinon.spy();
this.view.model.on("change:active", spy);
@ -82,6 +93,14 @@ define([path + 'ClassTagView', 'ClassManager/model/ClassTags'],
spy.called.should.equal(true);
});
it('On toggle triggers event', function() {
var spy = sinon.spy();
sinon.stub(this.view.target, 'get').returns(0);
this.view.target.on("targetClassUpdated", spy);
this.view.$el.find('#checkbox').trigger('click');
spy.called.should.equal(true);
});
it('Label toggles status', function() {
var spy = sinon.spy();
this.view.model.on("change:active", spy);

39
test/specs/code_manager/main.js

@ -0,0 +1,39 @@
var modulePath = './../../../test/specs/code_manager';
define([
'CodeManager',
modulePath + '/model/CodeModels',
//modulePath + '/view/ClassTagView',
//modulePath + '/view/ClassTagsView',
//modulePath + '/e2e/ClassManager'
],
function(
CodeManager,
Models
) {
describe('Code Manager', function() {
describe('Main', function() {
beforeEach(function () {
this.obj = new CodeManager();
});
afterEach(function () {
delete this.obj;
});
it('Object exists', function() {
CodeManager.should.be.exist;
});
});
Models.run();
//ClassTagView.run();
//ClassTagsView.run();
//e2e.run();
});
});

106
test/specs/code_manager/model/CodeModels.js

@ -0,0 +1,106 @@
var path = 'CodeManager/model/';
define([path + 'HtmlGenerator',
path + 'CssGenerator',
'DomComponents/model/Component',
'CssComposer'],
function(HtmlGenerator, CssGenerator, Component, CssComposer) {
return {
run : function(){
describe('HtmlGenerator', function() {
beforeEach(function () {
this.obj = new HtmlGenerator();
});
afterEach(function () {
delete this.obj;
});
it('Build correctly one component', function() {
var comp = new Component();
this.obj.build(comp).should.equal('');
});
it('Build correctly empty component inside', function() {
var comp = new Component();
var m1 = comp.get('components').add({});
this.obj.build(comp).should.equal('<div></div>');
});
it('Build correctly not empty component inside', function() {
var comp = new Component();
var m1 = comp.get('components').add({
tagName: 'article',
attributes: {
'data-test1': 'value1',
'data-test2': 'value2'
}
});
this.obj.build(comp).should.equal('<article data-test1="value1" data-test2="value2"></article>');
});
it('Build correctly component with classes', function() {
var comp = new Component();
var m1 = comp.get('components').add({
tagName: 'article',
attributes: {
'data-test1': 'value1',
'data-test2': 'value2'
}
});
['class1', 'class2'].forEach(function(item){
m1.get('classes').add({name: item});
});
this.obj.build(comp).should.equal('<article class="class1 class2" data-test1="value1" data-test2="value2"></article>');
});
});
describe('CssGenerator', function() {
beforeEach(function () {
this.obj = new CssGenerator();
});
afterEach(function () {
delete this.obj;
});
it('Build correctly one component', function() {
var comp = new Component();
this.obj.build(comp).should.equal('');
});
it('Build correctly empty component inside', function() {
var comp = new Component();
var m1 = comp.get('components').add({tagName: 'article'});
this.obj.build(comp).should.equal('');
});
it('Build correctly component with style inside', function() {
var comp = new Component();
var m1 = comp.get('components').add({
tagName: 'article',
style: {
'prop1': 'value1',
'prop2': 'value2'
}
});
this.obj.build(comp).should.equal('#' + m1.cid +'{prop1:value1;prop2:value2;}');
});
it('Build correctly component with class styled', function() {
var comp = new Component();
var m1 = comp.get('components').add({tagName: 'article'});
var cls1 = m1.get('classes').add({name: 'class1'});
var cssc = new CssComposer();
var rule = cssc.newRule(cls1);
rule.set('style',{'prop1':'value1', 'prop2':'value2'});
cssc.addRule(rule);
this.obj.build(comp, cssc).should.equal('.class1{prop1:value1;prop2:value2;}');
});
})
}
};
});
Loading…
Cancel
Save