diff --git a/src/css_composer/config/config.js b/src/css_composer/config/config.js index 7ec604b92..ae35a997a 100644 --- a/src/css_composer/config/config.js +++ b/src/css_composer/config/config.js @@ -2,7 +2,10 @@ define(function () { return { // Style prefix - stylePrefix : 'css-', + stylePrefix: 'css-', + + // Default CSS style + 'default': '', }; }); \ No newline at end of file diff --git a/src/css_composer/main.js b/src/css_composer/main.js index 29a390807..3d6099201 100644 --- a/src/css_composer/main.js +++ b/src/css_composer/main.js @@ -10,6 +10,7 @@ define(function(require) { def = require('./config/config'), CssRule = require('./model/CssRule'), CssRules = require('./model/CssRules'), + Selectors = require('./model/Selectors'), CssRulesView = require('./view/CssRulesView'); for (var name in def) { @@ -19,28 +20,46 @@ define(function(require) { //this.qset = { '' : CssRules, '340px': CssRules }; var rules = new CssRules([]), - rulesView = new CssRulesView({ - collection: rules, - config: c, - }); + rulesView = new CssRulesView({ + collection: rules, + config: c, + }); return { + Selectors: Selectors, + /** - * Add new class to collection only if it's not already exists - * @param {String} name Class name + * Create new rule and return it. Don't add it to the collection + * @param {Array} selectors Array of selectors + * @param {String} state Css rule state + * @param {String} width For which device this style is oriented * - * @return {Object} Model class + * @return {Object} + * */ + newRule: function(selectors, state, width) { + var s = state || ''; + var w = width || ''; + var rule = new CssRule({ + state: s, + maxWidth: w, + }); + rule.get('selectors').add(selectors); + return rule; + }, + + /** + * Add new rule to the collection if not yet exists + * @param {Object} rule + * + * @return {Object} * */ - addRule: function(Rule){ - return rules.add(Rule); - /* - var label = name; - var c = this.getRule(name); - if(!c) - return this.classes.add({name: name, label: label}); - return c; - */ + addRule: function(rule){ + var models = rule.get('selectors').models; + var r = this.getRule(models, rule.get('state'), rule.get('maxWidth')); + if(!r) + r = rules.add(rule); + return r; }, /** @@ -57,7 +76,6 @@ define(function(require) { rules.each(function(rule){ if(fRule) return; - var sel = _.pluck(rule.get('selectors').models, 'cid'); if(this.same(req, sel)) fRule = rule; @@ -65,20 +83,6 @@ define(function(require) { return fRule; }, - /** - * Create new rule - * @param {Array} selectors Array of selectors - * @param {String} state Rule status - * @param {String} set Query set - * - * @return {Object} - * */ - newRule: function(selectors, state, set) { - var rule = new CssRule({ state: state }); - rule.get('selectors').add(selectors); - return rule; - }, - /** * Compare 2 arrays to check if are the same * @param {Array} arr1 diff --git a/src/css_composer/model/CssRule.js b/src/css_composer/model/CssRule.js index 54586aa5f..169adfeb4 100644 --- a/src/css_composer/model/CssRule.js +++ b/src/css_composer/model/CssRule.js @@ -1,22 +1,28 @@ define(['backbone', './Selectors'], - function (Backbone, Selectors) { - /** - * @class CssRule - * */ - return Backbone.Model.extend({ + function (Backbone, Selectors) { + /** + * @class CssRule + * */ + return Backbone.Model.extend({ - defaults: { - selectors: {}, - style: {}, - stylable: true, - state: '', - }, + defaults: { + // Css selectors + selectors: {}, + // Css properties style + style: {}, + // On which device width this rule should be rendered, eg. @media (max-width: 1000px) + maxWidth: '', + // State of the rule, eg: hover | pressed | focused + state: '', + // Indicates if the rule is stylable + stylable: true, + }, - initialize: function(c, opt) { - this.config = c || {}; - this.slct = this.config.selectors || []; - this.set('selectors', new Selectors(this.slct)); - }, + initialize: function(c, opt) { + this.config = c || {}; + this.slct = this.config.selectors || []; + this.set('selectors', new Selectors(this.slct)); + }, - }); + }); }); diff --git a/test/runner/main.js b/test/runner/main.js index 24824b47e..45ac312fe 100644 --- a/test/runner/main.js +++ b/test/runner/main.js @@ -13,6 +13,7 @@ require(['../src/config/require-config.js', 'config/config.js'], function() { 'specs/asset_manager/view/FileUploader.js', 'specs/dom_components/main.js', 'specs/class_manager/main.js', + 'specs/css_composer/main.js', ], function(chai) { var should = chai.should(), diff --git a/test/specs/css_composer/main.js b/test/specs/css_composer/main.js new file mode 100644 index 000000000..06a8c7e9b --- /dev/null +++ b/test/specs/css_composer/main.js @@ -0,0 +1,84 @@ +var modulePath = './../../../test/specs/css_composer'; + +define([ + 'CssComposer', + modulePath + '/model/CssModels' + ], + function( + CssComposer, + Models, + Selectors + ) { + + describe('Css Composer', function() { + + describe('Main', function() { + + beforeEach(function () { + this.obj = new CssComposer(); + }); + + afterEach(function () { + delete this.obj; + }); + + it('Object exists', function() { + CssComposer.should.be.exist; + }); + + it("Rules are empty", function() { + this.obj.getRules().length.should.equal(0); + }); + + it('Create new rule with correct selectors', function() { + var sel = new this.obj.Selectors(); + var s1 = sel.add({name: 'test1'}); + var rule = this.obj.newRule(sel.models); + rule.get('selectors').at(0).should.deep.equal(s1); + }); + + it('Create new rule correctly', function() { + var sel = new this.obj.Selectors(); + var s1 = sel.add({name: 'test1'}); + var rule = this.obj.newRule(sel.models, 'state1', 'width1'); + rule.get('state').should.equal('state1'); + rule.get('maxWidth').should.equal('width1'); + }); + + it("Add rule to collection", function() { + var sel = new this.obj.Selectors([{name: 'test1'}]); + var rule = this.obj.newRule(sel.models, 'state1', 'width1'); + this.obj.addRule(rule); + this.obj.getRules().length.should.equal(1); + this.obj.getRules().at(0).get('selectors').at(0).get('name').should.equal('test1'); + }); + +/* + it("Don't duplicate rules", function() { + var sel1 = new this.obj.Selectors([{name: 'test1'}]); + var rule1 = this.obj.newRule(sel1.models, 'state1', 'width1'); + var aRule1 = this.obj.addRule(rule1); + + var sel2 = new this.obj.Selectors([{name: 'test1'}]); + var rule2 = this.obj.newRule(sel2.models, 'state1', 'width1'); + var aRule2 = this.obj.addRule(rule2); + + console.log(sel1); + console.log(rule1); + console.log(aRule1); + console.log(sel2); + console.log(rule2); + console.log(aRule2); + console.log(this.obj.getRules().length); + + aRule1.should.deep.equal(aRule2); + + }); +*/ + + }); + + Models.run(); + + }); +}); \ No newline at end of file diff --git a/test/specs/css_composer/model/CssModels.js b/test/specs/css_composer/model/CssModels.js new file mode 100644 index 000000000..4eb223da2 --- /dev/null +++ b/test/specs/css_composer/model/CssModels.js @@ -0,0 +1,60 @@ +var path = 'CssComposer/model/'; +define([path + 'CssRule', + path + 'CssRules', + path + 'Selectors', + 'ClassManager/model/ClassTag'], + function(CssRule, CssRules, Selectors, ClassTag) { + + return { + run : function(){ + describe('CssRule', function() { + + beforeEach(function () { + this.obj = new CssRule(); + }); + + afterEach(function () { + delete this.obj; + }); + + it('Has selectors property', function() { + this.obj.has('selectors').should.equal(true); + }); + + it('Has style property', function() { + this.obj.has('style').should.equal(true); + }); + + it('Has state property', function() { + this.obj.has('state').should.equal(true); + }); + + it('No default selectors', function() { + this.obj.get('selectors').length.should.equal(0); + }); + + }); + + describe('CssRules', function() { + + it('Creates collection item correctly', function() { + var c = new CssRules(); + var m = c.add({}); + m.should.be.an.instanceOf(CssRule); + }); + + }); + + describe('Selectors', function() { + + it('Creates collection item correctly', function() { + var c = new Selectors(); + var m = c.add({}); + m.should.be.an.instanceOf(ClassTag); + }); + + }); + } + }; + +}); \ No newline at end of file