diff --git a/src/css_composer/model/CssRule.js b/src/css_composer/model/CssRule.js index b02fb1f67..ed7b72ad4 100644 --- a/src/css_composer/model/CssRule.js +++ b/src/css_composer/model/CssRule.js @@ -23,6 +23,11 @@ module.exports = Backbone.Model.extend(Styleable).extend({ // Indicates if the rule is stylable stylable: true, + + // If true, sets '!important' on all properties + // You can use an array to specify properties to set important + // Used in view + important: 0, }, @@ -63,12 +68,13 @@ module.exports = Backbone.Model.extend(Styleable).extend({ /** * Returns CSS string of the rule + * @param {Object} [opts={}] Options * @return {string} */ - toCSS() { + toCSS(opts = {}) { let result = ''; const media = this.get('mediaText'); - const style = this.styleToString(); + const style = this.styleToString(opts); const selectors = this.selectorsToString(); if (selectors && style) { diff --git a/src/css_composer/view/CssRuleView.js b/src/css_composer/view/CssRuleView.js index dea7503e1..6fb35ee16 100644 --- a/src/css_composer/view/CssRuleView.js +++ b/src/css_composer/view/CssRuleView.js @@ -1,74 +1,22 @@ -var Backbone = require('backbone'); - -module.exports = Backbone.View.extend({ +module.exports = require('backbone').View.extend({ tagName: 'style', - initialize(o) { - this.config = o.config || {}; - this.listenTo(this.model, 'change:style', this.render); - this.listenTo(this.model, 'change:state', this.render); - this.listenTo(this.model, 'destroy remove', this.remove); - this.listenTo(this.model, 'change:mediaText', this.render); - this.listenTo(this.model.get('selectors'), 'change', this.selChanged); - }, - - /** - * Triggered when some selector is changed - * @private - */ - selChanged() { - this.selStr = this.renderSelectors(); - this.render(); - }, - /** - * Returns string of selectors - * @return {String} - * @private - */ - renderSelectors() { - const sel = []; + initialize(o = {}) { + this.config = o.config || {}; const model = this.model; - model.get('selectors').each(model => sel.push(model.getFullName())); - const sels = sel.join(''); - const add = model.get('selectorsAdd'); - return sels + (sels && add ? ', ' : '') + add; + const toTrack = 'change:style change:state change:mediaText'; + this.listenTo(model, toTrack, this.render); + this.listenTo(model, 'destroy remove', this.remove); + this.listenTo(model.get('selectors'), 'change', this.render); }, - /** - * Returns string of properties - * @return {String} - * @private - */ - renderProperties() { - var sel = [], - props = this.model.get('style'); - for (var prop in props){ - sel.push(prop + ':' + props[prop] + ';'); - } - return sel.join(''); - }, render() { - var block = '', - selStr = '', - o = ''; - if(!this.selStr) - this.selStr = this.renderSelectors(); - var prpStr = this.renderProperties(); - var stateStr = this.model.get('state'); - var mediaText = this.model.get('mediaText'); - if(this.selStr){ - stateStr = stateStr ? ':' + stateStr : ''; - block = prpStr !== '' ? '{' + prpStr + '}' : ''; - } - o = this.selStr && block ? this.selStr + stateStr + block : ''; - - if(mediaText && o) - o = '@media ' + mediaText + '{' + o + '}'; - - this.$el.html(o); + const model = this.model; + const important = model.get('important'); + this.el.innerHTML = this.model.toCSS({important}); return this; }, diff --git a/src/domain_abstract/model/Styleable.js b/src/domain_abstract/model/Styleable.js index eaa6df2c5..1a04ec388 100644 --- a/src/domain_abstract/model/Styleable.js +++ b/src/domain_abstract/model/Styleable.js @@ -1,9 +1,11 @@ -import { isString } from 'underscore'; +import { isString, isArray } from 'underscore'; import ParserHtml from 'parser/model/ParserHtml'; const parseStyle = ParserHtml().parseStyle; export default { + parseStyle, + /** * To trigger the style change event on models I have to * pass a new object instance @@ -80,14 +82,18 @@ export default { /** * Returns string of style properties + * @param {Object} [opts={}] Options * @return {String} */ - styleToString() { + styleToString(opts = {}) { const result = []; const style = this.getStyle(); for (let prop in style) { - result.push(`${prop}:${style[prop]};`); + const imp = opts.important; + const important = isArray(imp) ? imp.indexOf(prop) >= 0 : imp; + const value = `${style[prop]}${important ? ' !important' : ''}`; + result.push(`${prop}:${value};`); } return result.join(''); diff --git a/src/style_manager/view/SectorsView.js b/src/style_manager/view/SectorsView.js index 05ae7016b..754dcdd2a 100644 --- a/src/style_manager/view/SectorsView.js +++ b/src/style_manager/view/SectorsView.js @@ -80,6 +80,7 @@ module.exports = Backbone.View.extend({ rules.add(helperRule); } + helperRule.set('important', 1); helperRule.setStyle(style); pt.helper = helperRule; }; @@ -130,11 +131,6 @@ module.exports = Backbone.View.extend({ if (state) { const ruleState = cc.getIdRule(id, opts); state && appendStateRule(ruleState && ruleState.getStyle()); - if (ruleState) { - console.log(ruleState, ruleState.toCSS()); - } else { - console.log('NO RULE'); - } } pt.model = model; diff --git a/test/specs/css_composer/index.js b/test/specs/css_composer/index.js index ae2e509ff..3d4b21569 100644 --- a/test/specs/css_composer/index.js +++ b/test/specs/css_composer/index.js @@ -167,6 +167,8 @@ describe('Css Composer', () => { const rule = obj.getIdRule(name); expect(rule.selectorsToString()).toEqual(`#${name}`); expect(rule.styleToString()).toEqual(`color:red;`); + expect(rule.styleToString({important: 1})).toEqual(`color:red !important;`); + expect(rule.styleToString({important: ['color']})).toEqual(`color:red !important;`); }); it('Create a rule with id selector and state by using setIdRule()', () => { diff --git a/test/specs/css_composer/view/CssRuleView.js b/test/specs/css_composer/view/CssRuleView.js index 218177efc..55dee4e1b 100644 --- a/test/specs/css_composer/view/CssRuleView.js +++ b/test/specs/css_composer/view/CssRuleView.js @@ -26,26 +26,6 @@ module.exports = { expect(CssRuleView).toExist(); }); - it('Correct behaviour of renderSelectors with single selector', () => { - obj.model.get('selectors').add({name: 'test'}); - expect(obj.renderSelectors()).toEqual('.test'); - }); - - it('Correct behaviour of renderSelectors with multiple selectors', () => { - obj.model.get('selectors').add([{name: 'test2'}, {name: 'test1'}]); - expect(obj.renderSelectors()).toEqual('.test2.test1'); - }); - - it('Correct behaviour of renderProperties with single property', () => { - obj.model.set('style', {'prop': 'value'}); - expect(obj.renderProperties()).toEqual('prop:value;'); - }); - - it('Correct behaviour of renderProperties with multiple properties', () => { - obj.model.set('style', {'prop2': 'value2', 'prop3': 'value3'}); - expect(obj.renderProperties()).toEqual('prop2:value2;prop3:value3;'); - }); - it('Empty style inside', function() { expect(fixtures.innerHTML).toEqual(''); });