grapesjs_codeapps
Version:
Free and Open Source Web Builder Framework/SC Modification
128 lines (109 loc) • 3.63 kB
JavaScript
// Specs: https://mjml.io/documentation/#mjml-column
import { mjml2html } from 'mjml';
export default (
editor,
{ dc, opt, defaultModel, defaultView, coreMjmlModel, coreMjmlView, sandboxEl }
) => {
const type = 'mj-column';
const clmPadd = opt.columnsPadding;
dc.addType(type, {
model: defaultModel.extend(
{
...coreMjmlModel,
defaults: {
...defaultModel.prototype.defaults,
'custom-name': 'Column',
draggable: '[data-gjs-type=mj-section]',
stylable: [
'background-color',
'vertical-align',
'width',
'border-radius',
'border-top-left-radius',
'border-top-right-radius',
'border-bottom-left-radius',
'border-bottom-right-radius',
'border',
'border-width',
'border-style',
'border-color'
]
}
},
{
isComponent(el) {
if (el.tagName == type.toUpperCase()) {
return { type };
}
}
}
),
view: defaultView.extend({
...coreMjmlView,
tagName: 'div',
attributes: {
style: 'pointer-events: all;' + (clmPadd ? `padding: ${clmPadd};` : '')
},
getTemplateFromMjml() {
let mjmlTmpl = this.getMjmlTemplate();
let innerMjml = this.getInnerMjmlTemplate();
const htmlOutput = mjml2html(`${mjmlTmpl.start}
${innerMjml.start}${innerMjml.end}${mjmlTmpl.end}`);
let html = htmlOutput.html;
// I need styles for responsive columns
let styles = [];
sandboxEl.innerHTML = html;
var styleArr = Array.from(sandboxEl.querySelectorAll('style'));
styleArr.forEach(item => {
styles.push(item.innerHTML);
});
let content = html.replace(/<body(.*)>/, '<body>');
let start = content.indexOf('<body>') + 6;
let end = content.indexOf('</body>');
sandboxEl.innerHTML = content.substring(start, end).trim();
let componentEl = this.getTemplateFromEl(sandboxEl);
// Copy all rendered attributes (TODO need for all)
let attributes = {};
const elAttrs = componentEl.attributes;
for (let elAttr, i = 0, len = elAttrs.length; i < len; i++) {
elAttr = elAttrs[i];
attributes[elAttr.name] = elAttr.value;
}
return {
attributes,
content: componentEl.innerHTML,
style: styles.join(' ')
};
},
render() {
this.renderAttributes();
const mjmlResult = this.getTemplateFromMjml();
this.el.innerHTML = mjmlResult.content;
this.$el.attr(mjmlResult.attributes);
editor.addComponents(`<style>${mjmlResult.style}</style>`);
this.getChildrenContainer().innerHTML = this.model.get('content');
this.renderChildren();
this.el.style = this.el.getAttribute('style') + this.attributes.style;
return this;
},
getMjmlTemplate() {
// Need it for responsive columns
let cols = this.model.collection.length - 1;
cols = cols ? cols : 0;
let addColmn = Array(cols)
.fill('<mj-column></mj-column>')
.join('');
return {
start: `<mjml><mj-body><mj-container>`,
end: `${addColmn}</mj-container></mj-body></mjml>`
};
},
getTemplateFromEl(sandboxEl) {
return sandboxEl.firstChild.querySelector('div');
},
getChildrenSelector() {
return 'tbody';
}
})
});
};