diff --git a/src/commands/view/OpenStyleManager.js b/src/commands/view/OpenStyleManager.js index 4cab47f1c..da42937b4 100644 --- a/src/commands/view/OpenStyleManager.js +++ b/src/commands/view/OpenStyleManager.js @@ -24,11 +24,13 @@ define(['StyleManager'], function(StyleManager) { // Class Manager container this.clm = em.get('ClassManager'); if(this.clm){ + /* this.$clm = new this.clm.ClassTagsView({ collection: new this.clm.ClassTags([]), config: this.clm.config, }).render().el; this.$cn2.append(this.$clm); + */ } // Style Manager manager container diff --git a/src/css_manager/config/config.js b/src/css_manager/config/config.js new file mode 100644 index 000000000..7ec604b92 --- /dev/null +++ b/src/css_manager/config/config.js @@ -0,0 +1,8 @@ +define(function () { + return { + + // Style prefix + stylePrefix : 'css-', + + }; +}); \ No newline at end of file diff --git a/src/css_manager/main.js b/src/css_manager/main.js new file mode 100644 index 000000000..20e63a356 --- /dev/null +++ b/src/css_manager/main.js @@ -0,0 +1,64 @@ +define(function(require) { + /** + * @class CssManager + * @param {Object} config Configurations + * + * */ + var CssManager = function(config) + { + var c = config || {}, + def = require('./config/config'); + this.CssRules = require('./model/CssRules'); + + for (var name in def) { + if (!(name in c)) + c[name] = def[name]; + } + + this.rules = new this.CssRules([]); + this.config = c; + }; + + CssManager.prototype = { + + /** + * Add new class to collection only if it's not already exists + * @param {String} name Class name + * + * @return {Object} Model class + * */ + addRule: function(name){ + var label = name; + var c = this.getClass(name); + if(!c) + return this.classes.add({name: name, label: label}); + return c; + }, + + /** + * Get class by its name + * @param {Array[String]} ids Array of ids + * @param {String} status Rule status + * @param {String} set Query set + * + * @return {Object|null} + * */ + getRule : function(ids, status, set) { + var res = this.classes.where({name: id}); + return res.length ? res[0] : null; + }, + + /** + * Get collection of css rules + * + * @return {Object} + * */ + getRules : function() { + return this.rules; + }, + + }; + + return ClassManager; + +}); \ No newline at end of file diff --git a/src/css_manager/model/CssRule.js b/src/css_manager/model/CssRule.js new file mode 100644 index 000000000..f53aba979 --- /dev/null +++ b/src/css_manager/model/CssRule.js @@ -0,0 +1,16 @@ +define(['backbone'], + function (Backbone) { + /** + * @class CssRule + * */ + return Backbone.Model.extend({ + + defaults: { + classes: {}, + style: {}, + stylable: true, + state: '', + }, + + }); +}); diff --git a/src/css_manager/model/CssRules.js b/src/css_manager/model/CssRules.js new file mode 100644 index 000000000..04f382fac --- /dev/null +++ b/src/css_manager/model/CssRules.js @@ -0,0 +1,11 @@ +define(['backbone','./CssRule'], + function (Backbone, CssRule) { + /** + * @class CssRules + * */ + return Backbone.Collection.extend({ + + model: CssRule, + + }); +}); diff --git a/src/style_manager/view/PropertyView.js b/src/style_manager/view/PropertyView.js index f7cc5ce59..ab6670898 100644 --- a/src/style_manager/view/PropertyView.js +++ b/src/style_manager/view/PropertyView.js @@ -13,22 +13,22 @@ define(['backbone', 'text!./../templates/propertyLabel.html'], }, initialize: function(o) { - this.config = o.config; - this.pfx = this.config.stylePrefix; - this.target = o.target || {}; - this.onChange = o.onChange || {}; - this.onInputRender = o.onInputRender || {}; + this.config = o.config; + this.pfx = this.config.stylePrefix || ''; + this.target = o.target || {}; + this.onChange = o.onChange || {}; + this.onInputRender = o.onInputRender || {}; this.customValue = o.customValue || {}; - this.func = this.model.get('functionName'); - this.defaultValue = this.model.get('defaults'); - this.property = this.model.get('property'); - this.units = this.model.get('units'); - this.min = this.model.get('min') || this.model.get('min')===0 ? this.model.get('min') : -5000; - this.max = this.model.get('max') || this.model.get('max')===0 ? this.model.get('max') : 5000; - this.unit = this.model.get('unit') ? this.model.get('unit') : (this.units.length ? this.units[0] : ''); - this.list = this.model.get('list'); - this.input = this.$input = null; - this.className = this.pfx + 'property'; + this.func = this.model.get('functionName'); + this.defaultValue = this.model.get('defaults'); + this.property = this.model.get('property'); + this.units = this.model.get('units'); + this.min = this.model.get('min') || this.model.get('min')===0 ? this.model.get('min') : -5000; + this.max = this.model.get('max') || this.model.get('max')===0 ? this.model.get('max') : 5000; + this.unit = this.model.get('unit') ? this.model.get('unit') : (this.units.length ? this.units[0] : ''); + this.list = this.model.get('list'); + this.input = this.$input = null; + this.className = this.pfx + 'property'; this.selectedComponent = this.target.get('selectedComponent'); if(this.selectedComponent){ @@ -41,13 +41,20 @@ define(['backbone', 'text!./../templates/propertyLabel.html'], /** * Rerender property for the new selected component, if necessary - * @param Array [Model, value, options] + * @param {Array[Model, value, options]} e * - * @return void * */ componentSelected: function(e){ this.selectedComponent = this.target.get('selectedComponent'); if(this.selectedComponent){ + /* + var classes = this.selectedComponent.get('classes'); + if(classes.length){ + var valid = _.filter(classes.models, function(item){ return item.get('active'); }); + var ids = _.pluck(valid, 'cid'); + var cssBlock = '';//this.sm.get('CssManager').getRule(ids, 'status', 'mediaq'); + } + */ //I will rerender it only if the assigned one is different from the actuale value //console.log('property '+this.property+" view: "+this.componentValue+" model: "+ this.model.get('value')); if( !this.sameValue() ){ @@ -63,14 +70,14 @@ define(['backbone', 'text!./../templates/propertyLabel.html'], * @return boolean * */ sameValue: function(){ - return this.getComponentValue() == (this.model.get('value')+this.model.get('unit')); + return this.getComponentValue() == (this.model.get('value') + this.model.get('unit')); }, /** * Get the value from the selected component of this property * - * @return string + * @return {String} * */ getComponentValue: function(){ if(!this.selectedComponent) @@ -102,9 +109,9 @@ define(['backbone', 'text!./../templates/propertyLabel.html'], /** * Fetch string from function type value - * @param string Function type value + * @param {String} v Function type value * - * @return string + * @return {String} * */ fetchFromFunction: function(v){ return v.substring(v.indexOf("(") + 1, v.lastIndexOf(")")); @@ -113,8 +120,8 @@ define(['backbone', 'text!./../templates/propertyLabel.html'], /** * Property was changed, so I need to update the component too * @param {Object} e Events - * @param {Mixed} val Value - * @param {Object} opt Options + * @param {Mixed} val Value + * @param {Object} opt Options * * @return void * */ diff --git a/test/specs/class_manager/e2e/ClassManager.js b/test/specs/class_manager/e2e/ClassManager.js index ba5602b76..8467cce67 100644 --- a/test/specs/class_manager/e2e/ClassManager.js +++ b/test/specs/class_manager/e2e/ClassManager.js @@ -6,6 +6,24 @@ define( run : function(){ describe('E2E tests', function() { + /** + * Create tags viewer + * @param {Object} ctx + */ + var instClassTagViewer = function(ctx){ + var $clm; + var clm = ctx.gjs.editor.get('ClassManager'); + clm.config.target = ctx.gjs.editor; + if(clm){ + $clm = new clm.ClassTagsView({ + collection: new clm.ClassTags([]), + config: clm.config, + }).render(); + ctx.$fixture.append($clm.el); + } + return $clm; + }; + before(function () { this.$fixtures = $("#fixtures"); this.$fixture = $('
'); @@ -14,6 +32,7 @@ define( beforeEach(function () { var Grapes = require('editor/main'); this.gjs = new Grapes({ + stylePrefix: '', storageType: 'none', storageManager: { storageType: 'none', @@ -35,32 +54,28 @@ define( this.$fixture.remove(); }); + + it('Assign correctly new class to component', function() { var wrp = this.gjs.editor.get('Components').getWrapper().get('components'); var model = wrp.add({}); model.get('classes').length.should.equal(0); // Init Class Manager and set editor as a target - var $clm; - var clm = this.gjs.editor.get('ClassManager'); - clm.config.target = this.gjs.editor; - if(clm){ - $clm = new clm.ClassTagsView({ - collection: new clm.ClassTags([]), - config: clm.config, - }).render(); - this.$fixture.append($clm.el); - } + var $clm = instClassTagViewer(this); // Select element this.gjs.editor.set('selectedComponent', model); $clm.addNewTag('test'); + model.get('classes').length.should.equal(1); model.get('classes').at(0).get('name').should.equal('test'); }); + + it('Classes from components are correctly imported inside main container', function() { var wrp = this.gjs.editor.get('Components').getWrapper().get('components'); var model = wrp.add([ @@ -70,6 +85,8 @@ define( this.gjs.editor.get('ClassManager').getClasses().length.should.equal(4); }); + + it('Class imported into component is the same model from main container', function() { var wrp = this.gjs.editor.get('Components').getWrapper().get('components'); var model = wrp.add({ @@ -80,6 +97,39 @@ define( clModel.should.deep.equal(clModel2); }); + + + it('Can assign only one time the same class on selected component and the class viewer', function() { + var wrp = this.gjs.editor.get('Components').getWrapper().get('components'); + var model = wrp.add({}); + + var $clm = instClassTagViewer(this); + // Select element + this.gjs.editor.set('selectedComponent', model); + + $clm.addNewTag('test'); + $clm.addNewTag('test'); + + model.get('classes').length.should.equal(1); + model.get('classes').at(0).get('name').should.equal('test'); + + $clm.collection.length.should.equal(1); + $clm.collection.at(0).get('name').should.equal('test'); + }); + + it('Removing from container removes also from selected component', function() { + + var wrp = this.gjs.editor.get('Components').getWrapper().get('components'); + var model = wrp.add({}); + var $clm = instClassTagViewer(this); + this.gjs.editor.set('selectedComponent', model); + $clm.addNewTag('test'); + $clm.collection.at(0).destroy(); + + model.get('classes').length.should.equal(0); + + }); + }); } }; diff --git a/test/specs/class_manager/model/ClassModels.js b/test/specs/class_manager/model/ClassModels.js index 3ec640ba7..4f93c67d0 100644 --- a/test/specs/class_manager/model/ClassModels.js +++ b/test/specs/class_manager/model/ClassModels.js @@ -23,10 +23,20 @@ define([path + 'ClassTag', this.obj.has('label').should.equal(true); }); + it('Has active property', function() { + this.obj.has('active').should.equal(true); + }); + it('escapeName test', function() { this.obj.escapeName('@Te sT*').should.equal('-te-st-'); }); + it('Name is corrected at instantiation', function() { + this.obj = new ClassTag({ name: '@Te sT*'}); + this.obj.get('name').should.equal('-te-st-'); + }); + + }); describe('ClassTags', function() { diff --git a/test/specs/class_manager/view/ClassTagView.js b/test/specs/class_manager/view/ClassTagView.js index 9d425ab8d..d6eeca2c0 100644 --- a/test/specs/class_manager/view/ClassTagView.js +++ b/test/specs/class_manager/view/ClassTagView.js @@ -54,6 +54,14 @@ define([path + 'ClassTagView', 'ClassManager/model/ClassTags'], var $el = this.view.$el; $el.find('#close').should.have.property(0); }); + it('Has checkbox', function() { + var $el = this.view.$el; + $el.find('#checkbox').should.have.property(0); + }); + it('Has label', function() { + var $el = this.view.$el; + $el.find('#tag-label').should.have.property(0); + }); }); @@ -65,6 +73,24 @@ define([path + 'ClassTagView', 'ClassManager/model/ClassTags'], this.$fixture.html().should.be.empty; }); + it('Checkbox toggles status', function() { + var spy = sinon.spy(); + this.view.model.on("change:active", spy); + this.view.model.set('active', true); + this.view.$el.find('#checkbox').trigger('click'); + this.view.model.get('active').should.equal(false); + spy.called.should.equal(true); + }); + + it('Label toggles status', function() { + var spy = sinon.spy(); + this.view.model.on("change:active", spy); + this.view.model.set('active', true); + this.view.$el.find('#tag-label').trigger('click'); + this.view.model.get('active').should.equal(false); + spy.called.should.equal(true); + }); + }); } };