diff --git a/src/css_composer/view/CssRulesView.js b/src/css_composer/view/CssRulesView.js index 03b38d74c..42297d6d1 100644 --- a/src/css_composer/view/CssRulesView.js +++ b/src/css_composer/view/CssRulesView.js @@ -1,5 +1,6 @@ const CssRuleView = require('./CssRuleView'); const CssGroupRuleView = require('./CssGroupRuleView'); +const $ = Backbone.$; module.exports = require('backbone').View.extend({ initialize(o) { @@ -40,7 +41,7 @@ module.exports = require('backbone').View.extend({ // I have to render keyframes of the same name together // Unfortunately at the moment I didn't find the way of appending them // if not staticly, via appendData - if (model.get('atRuleType') == 'keyframes') { + if (model.get('atRuleType') === 'keyframes') { const atRule = model.getAtRule(); let atRuleEl = this.atRules[atRule]; @@ -61,19 +62,52 @@ module.exports = require('backbone').View.extend({ rendered = view.render().el; } + const mediaWidth = this.getMediaWidth(model.get('mediaText')); + const styleBlockId = `#${this.pfx}rules-${mediaWidth}`; + if (rendered) { - if (fragment) fragment.appendChild(rendered); - else this.$el.append(rendered); + if (fragment) { + fragment.querySelector(styleBlockId).appendChild(rendered); + } else { + let $stylesContainer = this.$el.find(styleBlockId); + $stylesContainer.append(rendered); + } } return rendered; }, + getMediaWidth(mediaText) { + return ( + mediaText && + mediaText + .replace(`(${this.em.getConfig('mediaCondition')}: `, '') + .replace(')', '') + ); + }, + render() { this.atRules = {}; const $el = this.$el; const frag = document.createDocumentFragment(); $el.empty(); + + // Create devices related DOM structure + const pfx = this.pfx; + this.em + .get('DeviceManager') + .getAll() + .map(model => model.get('widthMedia')) + .sort( + (left, right) => + ((right && right.replace('px', '')) || Number.MAX_VALUE) - + ((left && left.replace('px', '')) || Number.MAX_VALUE) + ) + .forEach(widthMedia => { + const blockId = pfx + 'rules-' + widthMedia; + $(`
`).appendTo(frag); + }); + this.collection.each(model => this.addToCollection(model, frag)); $el.append(frag); $el.attr('class', this.className); diff --git a/src/editor/model/Editor.js b/src/editor/model/Editor.js index 9032fa049..9cdfa75d8 100644 --- a/src/editor/model/Editor.js +++ b/src/editor/model/Editor.js @@ -52,6 +52,7 @@ module.exports = Backbone.Model.extend({ this.set('Config', c); this.set('modules', []); this.set('toLoad', []); + this.set('storables', []); if (c.el && c.fromElement) this.config.components = c.el.innerHTML; diff --git a/test/specs/code_manager/model/CodeModels.js b/test/specs/code_manager/model/CodeModels.js index d625a539d..8ad18e2c1 100644 --- a/test/specs/code_manager/model/CodeModels.js +++ b/test/specs/code_manager/model/CodeModels.js @@ -71,9 +71,12 @@ module.exports = { }); describe('CssGenerator', () => { - var newCssComp = () => new CssComposer().init(); + let newCssComp; + beforeEach(() => { em = new Editor({}); + newCssComp = () => new CssComposer().init({ em }); + cc = em.get('CssComposer'); obj = new CssGenerator(); dcomp = new DomComponents(); diff --git a/test/specs/css_composer/view/CssRulesView.js b/test/specs/css_composer/view/CssRulesView.js index d885fccdc..5feeb93eb 100644 --- a/test/specs/css_composer/view/CssRulesView.js +++ b/test/specs/css_composer/view/CssRulesView.js @@ -1,15 +1,41 @@ -var CssRulesView = require('css_composer/view/CssRulesView'); -var CssRules = require('css_composer/model/CssRules'); +const CssRulesView = require('css_composer/view/CssRulesView'); +const CssRules = require('css_composer/model/CssRules'); +const Editor = require('editor/model/Editor'); module.exports = { run() { describe('CssRulesView', () => { let obj; + const prefix = 'rules-'; + const devices = [ + { + name: 'Mobile portrait', + width: '320px', + widthMedia: '480px' + }, + { + name: 'Tablet', + width: '768px', + widthMedia: '992px' + }, + { + name: 'Desktop', + width: '', + widthMedia: '' + } + ]; beforeEach(function() { - var col = new CssRules([]); + const col = new CssRules([]); obj = new CssRulesView({ - collection: col + collection: col, + config: { + em: new Editor({ + deviceManager: { + devices + } + }) + } }); document.body.innerHTML = '
'; document.body.querySelector('#fixtures').appendChild(obj.render().el); @@ -23,8 +49,22 @@ module.exports = { expect(CssRulesView).toExist(); }); - it('Collection is empty', () => { - expect(obj.$el.html()).toNotExist(); + it('Collection is empty. Styles structure bootstraped', () => { + expect(obj.$el.html()).toExist(); + const foundStylesContainers = obj.$el.find('div'); + expect(foundStylesContainers.length).toEqual(devices.length); + + const sortedDevicesWidthMedia = devices + .map(dvc => dvc.widthMedia) + .sort((left, right) => { + return ( + ((right && right.replace('px', '')) || Number.MAX_VALUE) - + ((left && left.replace('px', '')) || Number.MAX_VALUE) + ); + }); + foundStylesContainers.each(function($styleC, idx) { + expect($styleC.id).toEqual(prefix + sortedDevicesWidthMedia[idx]); + }); }); it('Add new rule', () => { @@ -35,7 +75,7 @@ module.exports = { it('Render new rule', () => { obj.collection.add({}); - expect(obj.$el.html()).toExist(); + expect(obj.$el.find(`#${prefix}`).html()).toExist(); }); }); }