mirror of https://github.com/artf/grapesjs.git
nocodeframeworkdrag-and-dropsite-buildersite-generatortemplate-builderui-builderweb-builderweb-builder-frameworkwebsite-builderno-codepage-builder
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
3.4 KiB
157 lines
3.4 KiB
import { Model } from 'backbone';
|
|
import { result, forEach, isEmpty } from 'underscore';
|
|
import { isComponent, isObject } from 'utils/mixins';
|
|
|
|
const keyAutoW = '__aw';
|
|
const keyAutoH = '__ah';
|
|
|
|
export default Model.extend({
|
|
defaults: () => ({
|
|
x: 0,
|
|
y: 0,
|
|
attributes: {},
|
|
width: null,
|
|
height: null,
|
|
head: [],
|
|
component: '',
|
|
styles: ''
|
|
}),
|
|
|
|
initialize(props, opts = {}) {
|
|
const { config } = opts;
|
|
const { em } = config;
|
|
const { styles, component } = this.attributes;
|
|
const domc = em.get('DomComponents');
|
|
const conf = domc.getConfig();
|
|
const allRules = em.get('CssComposer').getAll();
|
|
this.em = em;
|
|
const modOpts = { em, config: conf, frame: this };
|
|
|
|
if (!isComponent(component)) {
|
|
const wrp = isObject(component) ? component : { components: component };
|
|
!wrp.type && (wrp.type = 'wrapper');
|
|
const Wrapper = domc.getType('wrapper').model;
|
|
this.set('component', new Wrapper(wrp, modOpts));
|
|
}
|
|
|
|
if (!styles) {
|
|
this.set('styles', allRules);
|
|
} else if (!isObject(styles)) {
|
|
allRules.add(styles);
|
|
this.set('styles', allRules);
|
|
}
|
|
|
|
!props.width && this.set(keyAutoW, 1);
|
|
!props.height && this.set(keyAutoH, 1);
|
|
},
|
|
|
|
getComponent() {
|
|
return this.get('component');
|
|
},
|
|
|
|
getStyles() {
|
|
return this.get('styles');
|
|
},
|
|
|
|
disable() {
|
|
this.trigger('disable');
|
|
},
|
|
|
|
remove() {
|
|
this.view = 0;
|
|
const coll = this.collection;
|
|
return coll && coll.remove(this);
|
|
},
|
|
|
|
getHead() {
|
|
return [...this.get('head')];
|
|
},
|
|
|
|
setHead(value) {
|
|
return this.set('head', [...value]);
|
|
},
|
|
|
|
addHeadItem(item) {
|
|
const head = this.getHead();
|
|
head.push(item);
|
|
this.setHead(head);
|
|
},
|
|
|
|
getHeadByAttr(attr, value, tag) {
|
|
const head = this.getHead();
|
|
return head.filter(
|
|
item =>
|
|
item.attributes &&
|
|
item.attributes[attr] == value &&
|
|
(!tag || tag === item.tag)
|
|
)[0];
|
|
},
|
|
|
|
removeHeadByAttr(attr, value, tag) {
|
|
const head = this.getHead();
|
|
const item = this.getHeadByAttr(attr, value, tag);
|
|
const index = head.indexOf(item);
|
|
|
|
if (index >= 0) {
|
|
head.splice(index, 1);
|
|
this.setHead(head);
|
|
}
|
|
},
|
|
|
|
addLink(href) {
|
|
const tag = 'link';
|
|
!this.getHeadByAttr('href', href, tag) &&
|
|
this.addHeadItem({
|
|
tag,
|
|
attributes: {
|
|
href,
|
|
rel: 'stylesheet'
|
|
}
|
|
});
|
|
},
|
|
|
|
removeLink(href) {
|
|
this.removeHeadByAttr('href', href, 'link');
|
|
},
|
|
|
|
addScript(src) {
|
|
const tag = 'script';
|
|
!this.getHeadByAttr('src', src, tag) &&
|
|
this.addHeadItem({
|
|
tag,
|
|
attributes: { src }
|
|
});
|
|
},
|
|
|
|
removeScript(src) {
|
|
this.removeHeadByAttr('src', src, 'script');
|
|
},
|
|
|
|
_emitUpdated(data = {}) {
|
|
this.em.trigger('frame:updated', { frame: this, ...data });
|
|
},
|
|
|
|
toJSON(opts = {}) {
|
|
const obj = Model.prototype.toJSON.call(this, opts);
|
|
const defaults = result(this, 'defaults');
|
|
|
|
delete obj.styles;
|
|
obj[keyAutoW] && delete obj.width;
|
|
obj[keyAutoH] && delete obj.height;
|
|
|
|
// Remove private keys
|
|
forEach(obj, (value, key) => {
|
|
key.indexOf('__') === 0 && delete obj[key];
|
|
});
|
|
|
|
forEach(defaults, (value, key) => {
|
|
if (obj[key] === value) delete obj[key];
|
|
});
|
|
|
|
forEach(['attributes', 'head'], prop => {
|
|
if (isEmpty(obj[prop])) delete obj[prop];
|
|
});
|
|
|
|
return obj;
|
|
}
|
|
});
|
|
|