Browse Source

Fix CSS rule rendering with custom media rules

pull/1045/head
Artur Arseniev 9 years ago
parent
commit
c1bffbdef9
  1. 44
      src/css_composer/view/CssRulesView.js
  2. 27
      test/specs/css_composer/view/CssRulesView.js

44
src/css_composer/view/CssRulesView.js

@ -4,7 +4,7 @@ const $ = Backbone.$;
// % is not a valid character for classes
const getBlockId = (pfx, widthMedia) =>
`${pfx}rules-${widthMedia.replace('%', 'pc')}`;
`${pfx}${widthMedia ? `-${widthMedia.replace('%', 'pc')}` : ''}`;
module.exports = require('backbone').View.extend({
initialize(o) {
@ -36,6 +36,11 @@ module.exports = require('backbone').View.extend({
* @private
* */
addToCollection(model, fragmentEl) {
// If the render is not yet started
if (!this.renderStarted) {
return;
}
var fragment = fragmentEl || null;
var viewObject = CssRuleView;
var config = this.config;
@ -66,16 +71,30 @@ module.exports = require('backbone').View.extend({
rendered = view.render().el;
}
const mediaWidth = this.getMediaWidth(model.get('mediaText'));
const styleBlockId = getBlockId(this.pfx, mediaWidth);
const clsName = this.className;
const mediaText = model.get('mediaText');
const defaultBlockId = getBlockId(clsName);
let blockId = defaultBlockId;
// If the rule contains a media query it might have a different container
// for it (eg. rules created with Device Manager)
if (mediaText) {
blockId = getBlockId(clsName, this.getMediaWidth(mediaText));
}
if (rendered) {
if (fragment) {
fragment.querySelector(`#${styleBlockId}`).appendChild(rendered);
} else {
let $stylesContainer = this.$el.find(`#${styleBlockId}`);
$stylesContainer.append(rendered);
const container = fragment || this.el;
let contRules;
// Try to find a specific container for the rule, if it
// containes a media query
try {
contRules = container.querySelector(`#${blockId}`);
} catch (e) {
contRules = container.querySelector(`#${defaultBlockId}`);
}
contRules.appendChild(rendered);
}
return rendered;
@ -91,13 +110,14 @@ module.exports = require('backbone').View.extend({
},
render() {
this.renderStarted = 1;
this.atRules = {};
const $el = this.$el;
const frag = document.createDocumentFragment();
const className = this.className;
$el.empty();
// Create devices related DOM structure
const pfx = this.pfx;
this.em
.get('DeviceManager')
.getAll()
@ -108,12 +128,14 @@ module.exports = require('backbone').View.extend({
((left && left.replace('px', '')) || Number.MAX_VALUE)
)
.forEach(widthMedia => {
$(`<div id="${getBlockId(pfx, widthMedia)}"></div>`).appendTo(frag);
$(`<div id="${getBlockId(className, widthMedia)}"></div>`).appendTo(
frag
);
});
this.collection.each(model => this.addToCollection(model, frag));
$el.append(frag);
$el.attr('class', this.className);
$el.attr('class', className);
return this;
}
});

27
test/specs/css_composer/view/CssRulesView.js

@ -6,7 +6,7 @@ module.exports = {
run() {
describe('CssRulesView', () => {
let obj;
const prefix = 'rules-';
const prefix = 'rules';
const devices = [
{
name: 'Mobile portrait',
@ -62,8 +62,9 @@ module.exports = {
((left && left.replace('px', '')) || Number.MAX_VALUE)
);
});
foundStylesContainers.each(function($styleC, idx) {
expect($styleC.id).toEqual(prefix + sortedDevicesWidthMedia[idx]);
foundStylesContainers.each(($styleC, idx) => {
const width = sortedDevicesWidthMedia[idx];
expect($styleC.id).toEqual(`${prefix}${width ? `-${width}` : ''}`);
});
});
@ -73,6 +74,26 @@ module.exports = {
expect(obj.addToCollection.calledOnce).toExist(true);
});
it('Add correctly rules with different media queries', () => {
const foundStylesContainers = obj.$el.find('div');
const rules = [
{
selectorsAdd: '#testid'
},
{
selectorsAdd: '#testid2',
mediaText: '(max-width: 1000px)'
},
{
selectorsAdd: '#testid2',
mediaText: 'screen and (max-width: 900px) and (min-width: 600px)'
}
];
obj.collection.add(rules);
const stylesCont = obj.el.querySelector(`#${obj.className}`);
expect(stylesCont.children.length).toEqual(rules.length);
});
it('Render new rule', () => {
obj.collection.add({});
expect(obj.$el.find(`#${prefix}`).html()).toExist();

Loading…
Cancel
Save