diff --git a/src/config/require-config.js b/src/config/require-config.js index 84e6cc784..3d2836551 100644 --- a/src/config/require-config.js +++ b/src/config/require-config.js @@ -42,6 +42,7 @@ require.config({ { name: 'RichTextEditor', location: 'rich_text_editor', }, { name: 'ModalDialog', location: 'modal_dialog', }, { name: 'CodeManager', location: 'code_manager', }, + { name: 'CssComposer', location: 'css_composer', }, { name: 'Commands', location: 'commands', }, { name: 'Canvas', location: 'canvas', }, { name: 'Panels', location: 'panels', } diff --git a/src/css_manager/config/config.js b/src/css_composer/config/config.js similarity index 100% rename from src/css_manager/config/config.js rename to src/css_composer/config/config.js diff --git a/src/css_composer/main.js b/src/css_composer/main.js new file mode 100644 index 000000000..b79c15826 --- /dev/null +++ b/src/css_composer/main.js @@ -0,0 +1,115 @@ +define(function(require) { + /** + * @class CssManager + * @param {Object} config Configurations + * + * */ + var CssManager = function(config) + { + var c = config || {}, + def = require('./config/config'), + CssRule = require('./model/CssRule'), + CssRules = require('./model/CssRules'); + + for (var name in def) { + if (!(name in c)) + c[name] = def[name]; + } + + //this.qset = { '' : CssRules, '340px': CssRules }; + var rules = new CssRules([]); + + return { + + /** + * 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.getRule(name); + if(!c) + return this.classes.add({name: name, label: label}); + return c; + */ + }, + + /** + * Get class by its name + * @param {Array} selectors Array of selectors + * @param {String} state Rule status + * @param {String} set Query set + * + * @return {Object|null} + * */ + getRule : function(selectors, state, set) { + var req = _.pluck(selectors, 'cid'); + fRule = null; + rules.each(function(rule){ + if(fRule) + return; + + var sel = _.pluck(rule.get('selectors'), 'cid'); + + if(this.same(req, sel)) + fRule = rule; + }, this); + 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 + * @param {Array} arr2 + * @return {Boolean} + */ + same: function(a1, a2){ + if(a1.length !== a2.length) + return; + + for (var i = 0; i < a1.length; i++) { + var f = 0; + + for (var j = 0; j < a2.length; j++) { + if (a1[i] === a2[j]) + f = 1; + } + + if(f === 0) + return; + } + return true; + }, + + /** + * Get collection of css rules + * + * @return {Object} + * */ + getRules : function() { + return rules; + }, + + }; + }; + + return CssManager; + +}); \ No newline at end of file diff --git a/src/css_composer/model/CssRule.js b/src/css_composer/model/CssRule.js new file mode 100644 index 000000000..54586aa5f --- /dev/null +++ b/src/css_composer/model/CssRule.js @@ -0,0 +1,22 @@ +define(['backbone', './Selectors'], + function (Backbone, Selectors) { + /** + * @class CssRule + * */ + return Backbone.Model.extend({ + + defaults: { + selectors: {}, + style: {}, + stylable: true, + state: '', + }, + + initialize: function(c, opt) { + this.config = c || {}; + this.slct = this.config.selectors || []; + this.set('selectors', new Selectors(this.slct)); + }, + + }); +}); diff --git a/src/css_manager/model/CssRules.js b/src/css_composer/model/CssRules.js similarity index 100% rename from src/css_manager/model/CssRules.js rename to src/css_composer/model/CssRules.js diff --git a/src/css_composer/model/Selectors.js b/src/css_composer/model/Selectors.js new file mode 100644 index 000000000..62f8511fc --- /dev/null +++ b/src/css_composer/model/Selectors.js @@ -0,0 +1,29 @@ +define([ 'backbone', 'require'], + function (Backbone, require) { + /** + * @class Selectors + * */ + + return Backbone.Collection.extend({ + + initialize: function(models, opt){ + + this.model = function(attrs, opts) { + var model; + + switch(1){ + + default: + if(!this.ClassTag) + this.ClassTag = require("ClassManager/model/ClassTag"); + model = new this.ClassTag(attrs, opts); + + } + + return model; + }; + + }, + + }); +}); diff --git a/src/css_manager/main.js b/src/css_manager/main.js deleted file mode 100644 index 20e63a356..000000000 --- a/src/css_manager/main.js +++ /dev/null @@ -1,64 +0,0 @@ -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 deleted file mode 100644 index f53aba979..000000000 --- a/src/css_manager/model/CssRule.js +++ /dev/null @@ -1,16 +0,0 @@ -define(['backbone'], - function (Backbone) { - /** - * @class CssRule - * */ - return Backbone.Model.extend({ - - defaults: { - classes: {}, - style: {}, - stylable: true, - state: '', - }, - - }); -}); diff --git a/src/editor/config/config.js b/src/editor/config/config.js index 9b06d527b..d5094f37f 100644 --- a/src/editor/config/config.js +++ b/src/editor/config/config.js @@ -64,6 +64,9 @@ define(function () { //Configurations for Class Manager classManager : {}, + //Configurations for Css Composer + cssComposer : {}, + }; return config; }); \ No newline at end of file diff --git a/src/editor/model/Editor.js b/src/editor/model/Editor.js index 6bddebf0b..b33125eee 100644 --- a/src/editor/model/Editor.js +++ b/src/editor/model/Editor.js @@ -6,6 +6,7 @@ define([ 'StorageManager', 'ModalDialog', 'CodeManager', + 'CssComposer', 'Commands', 'Canvas', 'RichTextEditor', @@ -20,6 +21,7 @@ define([ StorageManager, ModalDialog, CodeManager, + CssComposer, Commands, Canvas, RichTextEditor, @@ -53,10 +55,22 @@ define([ this.initComponents(); this.initCanvas(); this.initUndoManager(); + this.initCssComposer(); this.on('change:selectedComponent', this.componentSelected, this); }, + /** + * Initialize Css Composer + * */ + initCssComposer: function() + { + var cfg = this.config.cssComposer, + pfx = cfg.stylePrefix || 'css-'; + cfg.stylePrefix = this.config.stylePrefix + pfx; + this.set('CssComposer', new CssComposer(cfg)); + }, + /** * Initialize Class manager * */ diff --git a/src/style_manager/view/PropertiesView.js b/src/style_manager/view/PropertiesView.js index 846458fbe..492a56d91 100644 --- a/src/style_manager/view/PropertiesView.js +++ b/src/style_manager/view/PropertiesView.js @@ -1,58 +1,60 @@ -define(['backbone','./PropertyView', './PropertyIntegerView', './PropertyRadioView', './PropertySelectView', - './PropertyColorView', './PropertyFileView', './PropertyCompositeView', './PropertyStackView'], - function (Backbone, PropertyView, PropertyIntegerView, PropertyRadioView, PropertySelectView, +define(['backbone','./PropertyView', './PropertyIntegerView', './PropertyRadioView', './PropertySelectView', + './PropertyColorView', './PropertyFileView', './PropertyCompositeView', './PropertyStackView'], + function (Backbone, PropertyView, PropertyIntegerView, PropertyRadioView, PropertySelectView, PropertyColorView, PropertyFileView, PropertyCompositeView, PropertyStackView) { - /** + /** * @class PropertiesView * */ return Backbone.View.extend({ - + 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.customValue = o.customValue || {}; + this.target = o.target || {}; + this.propTarget = o.propTarget || {}; + this.onChange = o.onChange || {}; + this.onInputRender = o.onInputRender || {}; + this.customValue = o.customValue || {}; }, - + render: function() { var fragment = document.createDocumentFragment(); - + this.collection.each(function(model){ var objView = PropertyView; - + switch(model.get('type')){ - case 'integer': + case 'integer': objView = PropertyIntegerView; break; - case 'radio': + case 'radio': objView = PropertyRadioView; break; - case 'select': + case 'select': objView = PropertySelectView; break; - case 'color': + case 'color': objView = PropertyColorView; break; - case 'file': + case 'file': objView = PropertyFileView; break; - case 'composite': + case 'composite': objView = PropertyCompositeView;break; - case 'stack': + case 'stack': objView = PropertyStackView; break; } - + var view = new objView({ model : model, name : model.get('name'), id : this.pfx + model.get('property'), target : this.target, + propTarget : this.propTarget, onChange : this.onChange, onInputRender : this.onInputRender, config : this.config, }); - + if(model.get('type') != 'composite'){ view.customValue = this.customValue; } - + fragment.appendChild(view.render().el); },this); diff --git a/src/style_manager/view/PropertyView.js b/src/style_manager/view/PropertyView.js index 40e6fc25a..2768aaa75 100644 --- a/src/style_manager/view/PropertyView.js +++ b/src/style_manager/view/PropertyView.js @@ -16,6 +16,7 @@ define(['backbone', 'text!./../templates/propertyLabel.html'], this.config = o.config; this.pfx = this.config.stylePrefix || ''; this.target = o.target || {}; + this.propTarget = o.propTarget || {}; this.onChange = o.onChange || {}; this.onInputRender = o.onInputRender || {}; this.customValue = o.customValue || {}; @@ -35,8 +36,17 @@ define(['backbone', 'text!./../templates/propertyLabel.html'], this.componentValue = this.selectedComponent.get('style')[this.property]; } + this.listenTo( this.propTarget, 'update', this.targetUpdated); this.listenTo( this.target ,'change:selectedComponent',this.componentSelected); this.listenTo( this.model ,'change:value', this.valueChanged); + + }, + + /** + * Fired when target is updated + */ + targetUpdated: function() { + console.log('Property: target updated'); }, /** @@ -47,12 +57,6 @@ define(['backbone', 'text!./../templates/propertyLabel.html'], 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() ){ diff --git a/src/style_manager/view/SectorView.js b/src/style_manager/view/SectorView.js index dc583cd48..60fc4e608 100644 --- a/src/style_manager/view/SectorView.js +++ b/src/style_manager/view/SectorView.js @@ -13,6 +13,7 @@ define(['backbone', './PropertiesView', 'text!./../templates/sector.html'], this.config = o.config; this.pfx = this.config.stylePrefix; this.target = o.target || {}; + this.propTarget = o.propTarget || {}; this.open = this.model.get('open'); this.caretR = 'fa-caret-right'; this.caretD = 'fa-caret-down'; @@ -82,6 +83,7 @@ define(['backbone', './PropertiesView', 'text!./../templates/sector.html'], var view = new PropertiesView({ collection : objs, target : this.target, + propTarget : this.propTarget, config : this.config, }); this.$el.append(view.render().el); diff --git a/src/style_manager/view/SectorsView.js b/src/style_manager/view/SectorsView.js index dd472d884..93d3fbb71 100644 --- a/src/style_manager/view/SectorsView.js +++ b/src/style_manager/view/SectorsView.js @@ -9,6 +9,33 @@ define(['backbone','./SectorView'], this.config = o.config; this.pfx = this.config.stylePrefix; this.target = o.target || {}; + this.propTarget = {}; + _.extend(this.propTarget, Backbone.Events); + + this.listenTo( this.target ,'change:selectedComponent', this.targetUpdated); + + }, + + /** + * Fired when target is updated + */ + targetUpdated: function() { + var el = this.target.get('selectedComponent'); + var classes = el.get('classes'); + + if(classes.length){ + var cssC = this.target.get('CssComposer'); + var valid = _.filter(classes.models, function(item){ return item.get('active'); }); + var iContainer = cssC.getRule(valid, 'status', 'mediaq'); + if(!iContainer){ + //console.log(valid); + iContainer = cssC.newRule(valid, 'status', 'mediaq'); + //console.log(iContainer.get('selectors').models); + this.propTarget.target = iContainer; + this.propTarget.trigger('update'); + } + } + }, render: function() { @@ -21,6 +48,7 @@ define(['backbone','./SectorView'], name : obj.get('name'), properties : obj.get('properties'), target : this.target, + propTarget : this.propTarget, config : this.config, }); fragment.appendChild(view.render().el);