From a16b04568506de6ab9c0a888def7f2d860aae2ab Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Wed, 24 Jan 2018 01:34:41 +0100 Subject: [PATCH] Add `atRuleType` to CSSRule --- src/css_composer/model/CssRule.js | 40 ++++++++++++++++------ test/specs/css_composer/model/CssModels.js | 12 ++++++- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/css_composer/model/CssRule.js b/src/css_composer/model/CssRule.js index 1ea86c623..096a542dd 100644 --- a/src/css_composer/model/CssRule.js +++ b/src/css_composer/model/CssRule.js @@ -23,6 +23,9 @@ module.exports = Backbone.Model.extend(Styleable).extend({ // Indicates if the rule is stylable stylable: true, + // Type of at-rule, eg. 'media', 'font-face', etc. + atRuleType: '', + // If true, sets '!important' on all properties // You can use an array to specify properties to set important // Used in view @@ -47,6 +50,18 @@ module.exports = Backbone.Model.extend(Styleable).extend({ this.set('selectors', new Selectors(selectors)); }, + /** + * Returns an at-rule statement if possible, eg. '@media (...)', '@keyframes' + * @return {string} + */ + getAtRule() { + const type = this.get('atRuleType'); + const condition = this.get('mediaText'); + return ( + (type ? `@${type}` : '') + (condition && type ? ` ${condition}` : '') + ); + }, + /** * Return selectors fo the rule as a string * @return {string} @@ -69,7 +84,7 @@ module.exports = Backbone.Model.extend(Styleable).extend({ */ toCSS(opts = {}) { let result = ''; - const media = this.get('mediaText'); + const atRule = this.getAtRule(); const style = this.styleToString(opts); const selectors = this.selectorsToString(); @@ -77,8 +92,8 @@ module.exports = Backbone.Model.extend(Styleable).extend({ result = `${selectors}{${style}}`; } - if (media && result) { - result = `@media ${media}{${result}}`; + if (atRule && result) { + result = `${atRule}{${result}}`; } return result; @@ -93,11 +108,11 @@ module.exports = Backbone.Model.extend(Styleable).extend({ * @return {Boolean} * @private */ - compare(selectors, state, width, ruleProps) { - var otherRule = ruleProps || {}; + compare(selectors, state, width, ruleProps = {}) { var st = state || ''; var wd = width || ''; - var selectorsAdd = otherRule.selectorsAdd || ''; + var selectorsAdd = ruleProps.selectorsAdd || ''; + var atRuleType = ruleProps.atRuleType || ''; var cId = 'cid'; //var a1 = _.pluck(selectors.models || selectors, cId); //var a2 = _.pluck(this.get('selectors').models, cId); @@ -117,11 +132,14 @@ module.exports = Backbone.Model.extend(Styleable).extend({ if (re === 0) return f; } - if (this.get('state') !== st) return f; - - if (this.get('mediaText') !== wd) return f; - - if (this.get('selectorsAdd') !== selectorsAdd) return f; + if ( + this.get('state') !== st || + this.get('mediaText') !== wd || + this.get('selectorsAdd') !== selectorsAdd || + this.get('atRuleType') !== atRuleType + ) { + return f; + } return true; } diff --git a/test/specs/css_composer/model/CssModels.js b/test/specs/css_composer/model/CssModels.js index 44ea7753b..d7c423969 100644 --- a/test/specs/css_composer/model/CssModels.js +++ b/test/specs/css_composer/model/CssModels.js @@ -5,7 +5,7 @@ var Selector = require('selector_manager/model/Selector'); module.exports = { run() { - describe('CssRule', () => { + describe.only('CssRule', () => { let obj; beforeEach(() => { @@ -74,11 +74,21 @@ module.exports = { it('toCSS wraps correctly inside media rule', () => { const media = '(max-width: 768px)'; + obj.set('atRuleType', 'media'); obj.set('mediaText', media); obj.get('selectors').add({ name: 'test1' }); obj.setStyle({ color: 'red' }); expect(obj.toCSS()).toEqual(`@media ${media}{.test1{color:red;}}`); }); + + it('toCSS with a generic at-rule', () => { + obj.set('atRuleType', 'font-face'); + obj.get('selectors').add({ name: 'test1' }); + obj.setStyle({ 'font-family': 'Open Sans' }); + expect(obj.toCSS()).toEqual( + `@font-face{.test1{font-family:Open Sans;}}` + ); + }); }); describe('CssRules', () => {