Browse Source

Update on Css Composer

pull/14/head
Artur Arseniev 10 years ago
parent
commit
d728546855
  1. 28
      src/css_composer/main.js
  2. 53
      src/css_composer/view/CssRuleView.js
  3. 62
      src/css_composer/view/CssRulesView.js
  4. 26
      src/editor/view/EditorView.js
  5. 37
      src/style_manager/view/PropertyCompositeView.js
  6. 73
      src/style_manager/view/PropertyView.js
  7. 23
      src/style_manager/view/SectorsView.js

28
src/css_composer/main.js

@ -1,15 +1,16 @@
define(function(require) {
/**
* @class CssManager
* @class CssComposer
* @param {Object} config Configurations
*
* */
var CssManager = function(config)
var CssComposer = function(config)
{
var c = config || {},
def = require('./config/config'),
CssRule = require('./model/CssRule'),
CssRules = require('./model/CssRules');
CssRules = require('./model/CssRules'),
CssRulesView = require('./view/CssRulesView');
for (var name in def) {
if (!(name in c))
@ -17,7 +18,11 @@ define(function(require) {
}
//this.qset = { '' : CssRules, '340px': CssRules };
var rules = new CssRules([]);
var rules = new CssRules([]),
rulesView = new CssRulesView({
collection: rules,
config: c,
});
return {
@ -27,7 +32,8 @@ define(function(require) {
*
* @return {Object} Model class
* */
addRule: function(name){
addRule: function(Rule){
return rules.add(Rule);
/*
var label = name;
var c = this.getRule(name);
@ -78,6 +84,7 @@ define(function(require) {
* Compare 2 arrays to check if are the same
* @param {Array} arr1
* @param {Array} arr2
*
* @return {Boolean}
*/
same: function(a1, a2){
@ -107,9 +114,18 @@ define(function(require) {
return rules;
},
/**
* Render block of CSS rules
*
* @return {Object}
*/
render: function(){
return rulesView.render().el;
}
};
};
return CssManager;
return CssComposer;
});

53
src/css_composer/view/CssRuleView.js

@ -0,0 +1,53 @@
define(['backbone'],
function (Backbone) {
/**
* @class CssRuleView
* */
return Backbone.View.extend({
tagName: 'style',
initialize: function(o) {
this.config = o.config || {};
this.listenTo(this.model, 'change:style', this.render);
},
/**
* Returns string of selectors
* @return {String}
*/
renderSelectors: function(){
var sel = [];
this.model.get('selectors').each(function(m){
sel.push('.' + m.get('name'));
});
return sel.join('');
},
/**
* Returns string of properties
* @return {String}
*/
renderProperties: function(){
var sel = [],
props = this.model.get('style');
for (var prop in props){
sel.push(prop + ':' + props[prop] + ';');
}
return sel.join('');
},
/*
http://stackoverflow.com/questions/524696/how-to-create-a-style-tag-with-javascript
*/
render : function(){
if(!this.selStr)
this.selStr = this.renderSelectors();
var prpStr = this.renderProperties();
this.$el.html(this.selStr + '{' + prpStr + '}');
return this;
},
});
});

62
src/css_composer/view/CssRulesView.js

@ -0,0 +1,62 @@
define(['backbone','./CssRuleView'],
function (Backbone, CssRuleView) {
/**
* @class CssRulesView
* */
return Backbone.View.extend({
initialize: function(o) {
this.config = o.config;
this.preview = o.preview;
this.pfx = this.config.stylePrefix;
this.listenTo( this.collection, 'add', this.addTo );
this.listenTo( this.collection, 'reset', this.render );
},
/**
* Add to collection
* @param {Object} model
* */
addTo: function(model){
console.log('Added');
this.addToCollection(model);
},
/**
* Add new object to collection
* @param {Object} model
* @param {Object} fragmentEl
*
* @return {Object}
* */
addToCollection: function(model, fragmentEl){
var fragment = fragmentEl || null;
var viewObject = CssRuleView;
var view = new viewObject({
model: model,
config: this.config,
});
var rendered = view.render().el;
if(fragment)
fragment.appendChild( rendered );
else
this.$el.append(rendered);
return rendered;
},
render: function() {
var fragment = document.createDocumentFragment();
this.$el.empty();
this.collection.each(function(model){
this.addToCollection(model, fragment);
}, this);
this.$el.append(fragment);
return this;
}
});
});

26
src/editor/view/EditorView.js

@ -4,30 +4,34 @@ function(Backbone){
* @class EditorView
* */
return Backbone.View.extend({
initialize: function() {
this.cv = this.model.get('Canvas');
this.pn = this.model.get('Panels');
this.className = this.model.config.stylePrefix + 'editor';
this.cv = this.model.get('Canvas');
this.pn = this.model.get('Panels');
this.css = this.model.get('CssComposer');
this.className = this.model.config.stylePrefix + 'editor';
},
render: function(){
this.$el.empty();
this.$cont = $('body ' + this.model.config.container);
this.model.set('$editor', this.$el);
if(this.cv)
this.$el.append(this.cv.render());
if(this.pn)
this.$el.append(this.pn.render());
if(this.css)
this.$el.append(this.css.render());
this.$el.attr('class', this.className);
this.$cont.html(this.$el);
if(this.pn)
this.pn.active();

37
src/style_manager/view/PropertyCompositeView.js

@ -1,36 +1,36 @@
define(['backbone','./PropertyView', 'text!./../templates/propertyComposite.html','require'],
define(['backbone','./PropertyView', 'text!./../templates/propertyComposite.html','require'],
function (Backbone, PropertyView, propertyTemplate, require) {
/**
/**
* @class PropertyCompositeView
* */
return PropertyView.extend({
template: _.template(propertyTemplate),
initialize: function(o) {
PropertyView.prototype.initialize.apply(this, arguments);
_.bindAll(this, 'build');
this.config = o.config;
this.className = this.className + ' '+ this.pfx +'composite';
},
/**
* Renders input
*
*
* @return void
* */
renderInput: function() {
var props = this.model.get('properties');
if(props && props.length){
if(!this.$input)
if(!this.$input)
this.$input = $('<input>', {value: 0, type: 'hidden' });
if(!this.props){
var Properties = require('./../model/Properties');
this.props = new Properties(props);
this.model.set('properties', this.props);
}
if(!this.$props){
//Avoid style for children
this.props.each(function(prop, index){
@ -43,15 +43,16 @@ define(['backbone','./PropertyView', 'text!./../templates/propertyComposite.html
console.warn(prop.get('property')+' of type composite not yet allowed.');
}
},this);
var PropertiesView = require('./PropertiesView');
var that = this;
var propsView = new PropertiesView({
config : this.config,
collection : this.props,
collection : this.props,
target : this.target,
propTarget : this.propTarget,
onChange : function(el, model){
var result = that.build(el, model);
var result = that.build(el, model);
that.model.set('value', result);
},
onInputRender : function(property, mIndex){
@ -67,10 +68,10 @@ define(['backbone','./PropertyView', 'text!./../templates/propertyComposite.html
}
}
},
/**
* Get default value of the property
*
*
* @return string
* */
getDefaultValue: function(){
@ -80,12 +81,12 @@ define(['backbone','./PropertyView', 'text!./../templates/propertyComposite.html
});
return str.replace(/ +$/,'');
},
/**
* Extract string from composite value
* @param integer Index
* @param object Property model
*
*
* @return string
* */
valueOnIndex: function(index, model){
@ -102,12 +103,12 @@ define(['backbone','./PropertyView', 'text!./../templates/propertyComposite.html
}
return result;
},
/**
* Build composite value
* @param Object Selected element
* @param Object Property model
*
*
* @return string
* */
build: function(selectedEl, propertyModel){

73
src/style_manager/view/PropertyView.js

@ -5,8 +5,8 @@ define(['backbone', 'text!./../templates/propertyLabel.html'],
* */
return Backbone.View.extend({
template: _.template(propertyTemplate),
templateLabel: _.template(propertyTemplate),
template: _.template(propertyTemplate),
templateLabel: _.template(propertyTemplate),
events: {
'change' : 'valueChanged',
@ -30,46 +30,26 @@ define(['backbone', 'text!./../templates/propertyLabel.html'],
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){
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');
},
/**
* Rerender property for the new selected component, if necessary
* @param {Array[Model, value, options]} e
*
* Fired when the target is updated
* */
componentSelected: function(e){
this.selectedComponent = this.target.get('selectedComponent');
targetUpdated: function(){
this.selectedComponent = this.propTarget.model;
if(this.selectedComponent){
//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() ){
if(!this.sameValue())
this.renderInputRequest();
}
}
},
/**
* Checks if the value from selected component is the same with
* the value of the model
* Checks if the value from selected component is the
* same of the value of the model
*
* @return boolean
* @return {Boolean}
* */
sameValue: function(){
return this.getComponentValue() == (this.model.get('value') + this.model.get('unit'));
@ -88,7 +68,7 @@ define(['backbone', 'text!./../templates/propertyLabel.html'],
if(this.selectedComponent.get('style')[this.property])
this.componentValue = this.selectedComponent.get('style')[this.property];
else
this.componentValue = this.defaultValue + (this.unit ? this.unit : '');
this.componentValue = this.defaultValue + (this.unit || '');
// Check if wrap inside function is required
if(this.func){
@ -97,11 +77,11 @@ define(['backbone', 'text!./../templates/propertyLabel.html'],
this.componentValue = v;
}
//This allow to ovveride the normal flow of selecting component value,
//useful in composite properties
// This allow to ovveride the normal flow of selecting component value,
// useful in composite properties
if(this.customValue && typeof this.customValue === "function"){
var index = this.model.collection.indexOf(this.model);
var t = this.customValue(this, index);
var index = this.model.collection.indexOf(this.model);
var t = this.customValue(this, index);
if(t)
this.componentValue = t;
}
@ -110,7 +90,7 @@ define(['backbone', 'text!./../templates/propertyLabel.html'],
},
/**
* Fetch string from function type value
* Fetch the string from function type value
* @param {String} v Function type value
*
* @return {String}
@ -124,8 +104,6 @@ define(['backbone', 'text!./../templates/propertyLabel.html'],
* @param {Object} e Events
* @param {Mixed} val Value
* @param {Object} opt Options
*
* @return void
* */
valueChanged: function(e, val, opt){
if(!this.selectedComponent)
@ -156,7 +134,7 @@ define(['backbone', 'text!./../templates/propertyLabel.html'],
componentCss[this.property] = value;
this.selectedComponent.set('style', componentCss, { avoidStore : avSt});
}
this.selectedValue = value;//TODO ?
this.selectedValue = value;
if(this.onChange && typeof this.onChange === "function"){
this.onChange(this.selectedComponent, this.model);
@ -165,9 +143,8 @@ define(['backbone', 'text!./../templates/propertyLabel.html'],
/**
* Set value to the input
* @param String value
*
* @return void
* @param {String} value
* @param {Boolean} force
* */
setValue: function(value, force){
var f = force===0 ? 0 : 1;
@ -177,13 +154,11 @@ define(['backbone', 'text!./../templates/propertyLabel.html'],
}
if(this.$input)
this.$input.val(v);
this.model.set({value: v},{silent: true});
this.model.set({value: v}, {silent: true});
},
/**
* Render label
*
* @return void
* */
renderLabel: function(){
this.$el.html( this.templateLabel({
@ -196,8 +171,6 @@ define(['backbone', 'text!./../templates/propertyLabel.html'],
/**
* Render field property
*
* @return void
* */
renderField : function() {
this.renderTemplate();
@ -207,8 +180,6 @@ define(['backbone', 'text!./../templates/propertyLabel.html'],
/**
* Render loaded template
*
* @return void
* */
renderTemplate: function(){
this.$el.append( this.template({
@ -221,8 +192,6 @@ define(['backbone', 'text!./../templates/propertyLabel.html'],
/**
* Renders input, to override
*
* @return void
* */
renderInput: function(){
console.warn("No render input implemented for '"+this.model.get('type')+"'");
@ -230,8 +199,6 @@ define(['backbone', 'text!./../templates/propertyLabel.html'],
/**
* Request to render input of the property
*
* @return void
* */
renderInputRequest: function(){
this.renderInput();
@ -243,8 +210,6 @@ define(['backbone', 'text!./../templates/propertyLabel.html'],
/**
* Clean input
*
* @return void
* */
cleanValue: function(){
this.setValue('');

23
src/style_manager/view/SectorsView.js

@ -9,10 +9,11 @@ define(['backbone','./SectorView'],
this.config = o.config;
this.pfx = this.config.stylePrefix;
this.target = o.target || {};
// The taget that will emit events for properties
this.propTarget = {};
_.extend(this.propTarget, Backbone.Events);
this.listenTo( this.target ,'change:selectedComponent', this.targetUpdated);
this.listenTo( this.target, 'change:selectedComponent', this.targetUpdated);
},
@ -21,21 +22,31 @@ define(['backbone','./SectorView'],
*/
targetUpdated: function() {
var el = this.target.get('selectedComponent');
if(!el)
return;
var classes = el.get('classes');
var pt = this.propTarget;
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');
// Hydrate styles from component element
iContainer.set('style', el.get('style'));
cssC.addRule(iContainer);
el.set('style', {});
pt.model = iContainer;
pt.trigger('update');
return;
}
}
pt.model = el;
pt.trigger('update');
},
render: function() {

Loading…
Cancel
Save