diff --git a/src/style_manager/model/Property.js b/src/style_manager/model/Property.js index 3e0de3f21..37934ec87 100644 --- a/src/style_manager/model/Property.js +++ b/src/style_manager/model/Property.js @@ -346,6 +346,65 @@ export default class Property extends Model { getParentTarget() { return this.__parentTarget || null; } + + isVisible(target) { + const trg = target; + const id = this.getId(); + const property = this.getName(); + const toRequire = this.get('toRequire'); + const requires = this.get('requires'); + const requiresParent = this.get('requiresParent'); + const sectors = this.sector?.collection || null; + const selected = this.em?.getSelected() || null; + const unstylable = trg?.get('unstylable'); + const stylableReq = trg?.get('stylable-require'); + let stylable = trg?.get('stylable'); + + // Stylable could also be an array indicating with which property + // the target could be styled + if (isArray(stylable)) { + stylable = stylable.indexOf(property) >= 0; + } + + // Check if the property was signed as unstylable + if (isArray(unstylable)) { + stylable = unstylable.indexOf(property) < 0; + } + + // Check if the property is available only if requested + if (toRequire) { + stylable = !target || (stylableReq && (stylableReq.indexOf(id) >= 0 || stylableReq.indexOf(property) >= 0)); + } + + // Check if the property is available based on other property's values + if (sectors && requires) { + const properties = keys(requires); + sectors.forEach(sector => { + sector.getProperties().forEach(model => { + if (includes(properties, model.id)) { + const values = requires[model.id]; + stylable = stylable && includes(values, model.get('value')); + } + }); + }); + } + + // Check if the property is available based on parent's property values + if (requiresParent) { + const parent = selected && selected.parent(); + const parentEl = parent && parent.getEl(); + if (parentEl) { + const styles = window.getComputedStyle(parentEl); + each(requiresParent, (values, property) => { + stylable = stylable && styles[property] && includes(values, styles[property]); + }); + } else { + stylable = false; + } + } + + return stylable; + } } Property.callParentInit = function (property, ctx, props, opts = {}) { diff --git a/src/style_manager/model/Sector.js b/src/style_manager/model/Sector.js index 022aee7ff..e9ef29054 100644 --- a/src/style_manager/model/Sector.js +++ b/src/style_manager/model/Sector.js @@ -15,6 +15,7 @@ export default class Sector extends Model { id: '', name: '', open: true, + visible: true, buildProps: '', extendBuilded: 1, properties: [], diff --git a/src/style_manager/model/Sectors.js b/src/style_manager/model/Sectors.js index 11d9fe1af..66043547f 100644 --- a/src/style_manager/model/Sectors.js +++ b/src/style_manager/model/Sectors.js @@ -16,4 +16,13 @@ export default class Sectors extends Collection { const prev = opts.previousModels || []; prev.forEach(sect => sect.get('properties').reset()); } + + __targetUpdated() { + const sectors = this.collection; + // Enable all + sectors.forEach(sector => {}); + // Check for property + const component = this.em.getSelected(); + const target = this.module.getLastSelected(); + } } diff --git a/src/style_manager/view/SectorsView.js b/src/style_manager/view/SectorsView.js index 6586573a1..35539a5a0 100644 --- a/src/style_manager/view/SectorsView.js +++ b/src/style_manager/view/SectorsView.js @@ -192,11 +192,9 @@ export default Backbone.View.extend({ }, render() { - const frag = document.createDocumentFragment(); - const $el = this.$el; - const pfx = this.pfx; - const ppfx = this.ppfx; + const { $el, pfx, ppfx } = this; $el.empty(); + const frag = document.createDocumentFragment(); this.collection.each(model => this.addToCollection(model, frag)); $el.append(frag); $el.addClass(`${pfx}sectors ${ppfx}one-bg ${ppfx}two-color`); diff --git a/test/specs/style_manager/model/Models.js b/test/specs/style_manager/model/Models.js index 1f9c01788..366e4ae61 100644 --- a/test/specs/style_manager/model/Models.js +++ b/test/specs/style_manager/model/Models.js @@ -1,5 +1,4 @@ import Sector from 'style_manager/model/Sector'; -import Sectors from 'style_manager/model/Sectors'; import Property from 'style_manager/model/Property'; import PropertyNumber from 'style_manager/model/PropertyNumber'; import Properties from 'style_manager/model/Properties'; @@ -104,22 +103,6 @@ describe('Sector', () => { }); }); -describe('Sectors', () => { - var obj; - - beforeEach(() => { - obj = new Sectors(); - }); - - afterEach(() => { - obj = null; - }); - - test('Object exists', () => { - expect(obj).toBeTruthy(); - }); -}); - describe('Property', () => { var obj; diff --git a/test/specs/style_manager/model/Sectors.js b/test/specs/style_manager/model/Sectors.js new file mode 100644 index 000000000..706482d9c --- /dev/null +++ b/test/specs/style_manager/model/Sectors.js @@ -0,0 +1,103 @@ +import Editor from 'editor/model/Editor'; +import Sectors from 'style_manager/model/Sectors'; + +describe('Sectors', () => { + let obj; + + beforeEach(() => { + obj = new Sectors(); + }); + + afterEach(() => { + obj = null; + }); + + test('Object exists', () => { + expect(obj).toBeTruthy(); + }); + + describe('Sector visibility', () => { + let em; + let sm; + let domc; + let s1; + let s2; + + beforeEach(() => { + em = new Editor({ + mediaCondition: 'max-width', + avoidInlineStyle: true, + styleManager: { + sectors: [ + { + id: 'sector-1', + name: 'First sector', + properties: ['width', 'min-width', 'height', 'min-height'], + }, + { + id: 'sector-2', + name: 'Second sector', + properties: ['color', 'font-size'], + }, + ], + }, + }); + domc = em.get('DomComponents'); + sm = em.get('StyleManager'); + em.get('PageManager').onLoad(); + sm.onLoad(); + s1 = sm.getSector('sector-1'); + s2 = sm.getSector('sector-2'); + }); + + afterEach(() => { + em.destroy(); + }); + + test('All sectors should exist', () => { + console.log(sm.getSectors().map(s => s.id)); + [s1, s2].forEach(sector => expect(sector).toBeTruthy()); + }); + + test('All sectors and properties are visible by default', () => { + [s1, s2].forEach(sector => { + expect(sector.get('visible')).toBe(true); + sector.getProperties().forEach(prop => { + expect(prop.get('visible')).toBe(true); + }); + }); + }); + + test('Sectors are properly enabled with stylable component', () => { + const stylable = ['width', 'height']; + const cmp = domc.addComponent({ stylable }); + em.setSelected(cmp); + + expect(s1.get('visible')).toBe(true); + expect(s2.get('visible')).toBe(false); + s1.getProperties().forEach(prop => { + const isVisible = stylable.indexOf(prop.getName()) >= 0; + expect(prop.get('visible')).toBe(isVisible); + }); + s2.getProperties().forEach(prop => { + expect(prop.get('visible')).toBe(false); + }); + }); + + test('Sectors are properly enabled with unstylable component', () => { + const unstylable = ['color']; + const cmp = domc.addComponent({ unstylable }); + em.setSelected(cmp); + + expect(s1.get('visible')).toBe(true); + expect(s2.get('visible')).toBe(true); + s1.getProperties().forEach(prop => { + expect(prop.get('visible')).toBe(true); + }); + s2.getProperties().forEach(prop => { + const isVisible = unstylable.indexOf(prop.getName()) < 0; + expect(prop.get('visible')).toBe(!isVisible); + }); + }); + }); +});