UNPKG

grapesjs_codeapps

Version:

Free and Open Source Web Builder Framework/SC Modification

178 lines (154 loc) 4.83 kB
import Backbone from 'backbone'; import { extend, isString } from 'underscore'; const SectorView = require('./SectorView'); module.exports = Backbone.View.extend({ initialize(o = {}) { const config = o.config || {}; this.pfx = config.stylePrefix || ''; this.ppfx = config.pStylePrefix || ''; this.target = o.target || {}; this.config = config; // The target that will emit events for properties const target = {}; extend(target, Backbone.Events); const body = document.body; const dummy = document.createElement(`el-${new Date().getTime()}`); body.appendChild(dummy); target.computedDefault = { ...window.getComputedStyle(dummy) }; body.removeChild(dummy); this.propTarget = target; const coll = this.collection; const events = 'component:toggled component:update:classes component:update:state change:device'; this.listenTo(coll, 'add', this.addTo); this.listenTo(coll, 'reset', this.render); this.listenTo(this.target, events, this.targetUpdated); }, /** * Add to collection * @param {Object} model Model * @return {Object} * @private * */ addTo(model) { this.addToCollection(model); }, /** * Fired when target is updated * @private */ targetUpdated() { const em = this.target; const pt = this.propTarget; let model = em.getWrapper(); if (!model) return; const config = em.get('Config'); const state = !config.devicePreviewMode ? model.get('state') : ''; const el = model.getEl(); pt.helper = null; // Create computed style container if (el) { const stateStr = state ? `:${state}` : null; pt.computed = window.getComputedStyle(el, stateStr); } // Create a new rule for the state as a helper const appendStateRule = (style = {}) => { const cc = em.get('CssComposer'); const helperCls = 'hc-state'; const rules = cc.getAll(); let helperRule = cc.getClassRule(helperCls); if (!helperRule) { helperRule = cc.setClassRule(helperCls); } else { // I will make it last again, otherwise it could be overridden rules.remove(helperRule); rules.add(helperRule); } helperRule.set('important', 1); helperRule.setStyle(style); pt.helper = helperRule; }; // console.log(em.get('StyleManager').getModelToStyle(model)); model = em.get('StyleManager').getModelToStyle(model); state && appendStateRule(model.getStyle()); // console.log(model.getStyle()); pt.model = model; pt.trigger('update'); }, /** * Select different target for the Style Manager. * It could be a Component, CSSRule, or a string of any CSS selector * @param {Component|CSSRule|String} target * @return {Styleable} A Component or CSSRule */ setTarget(target, opts = {}) { const em = this.target; const config = em.get('Config'); const { targetIsClass, stylable } = opts; let model = target; if (isString(target)) { let rule; const rules = em.get('CssComposer').getAll(); if (targetIsClass) { rule = rules.filter( rule => rule.get('selectors').getFullString() === target )[0]; } if (!rule) { rule = rules.filter(rule => rule.get('selectorsAdd') === target)[0]; } if (!rule) { rule = rules.add({ selectors: [], selectorsAdd: target }); } stylable && rule.set({ stylable }); model = rule; } const state = !config.devicePreviewMode ? model.get('state') : ''; const pt = this.propTarget; pt.model = model; pt.trigger('styleManager:update', model); return model; }, /** * Add new object to collection * @param {Object} model Model * @param {Object} fragmentEl collection * @return {Object} Object created * @private * */ addToCollection(model, fragmentEl) { var fragment = fragmentEl || null; var view = new SectorView({ model, id: this.pfx + model .get('name') .replace(' ', '_') .toLowerCase(), name: model.get('name') + 'asd', properties: model.get('properties'), target: this.target, propTarget: this.propTarget, config: this.config }); var rendered = view.render().el; if (fragment) { fragment.appendChild(rendered); } else { this.$el.append(rendered); } return rendered; }, render() { const frag = document.createDocumentFragment(); const $el = this.$el; const pfx = this.pfx; const ppfx = this.ppfx; $el.empty(); this.collection.each(model => this.addToCollection(model, frag)); $el.append(frag); $el.addClass(`${pfx}sectors ${ppfx}one-bg ${ppfx}two-color`); return this; } });