Integration of custom version of grapesjs-mjml

This commit is contained in:
Dominique Da Silva 2019-11-09 01:56:40 +00:00
parent 8ccb8e374b
commit 523f921088
8 changed files with 354 additions and 391 deletions

View file

@ -1,248 +1,161 @@
.gjs-clm-tags .gjs-sm-title, /* Editor Customization */
.gjs-sm-sector .gjs-sm-title {
border-top: none; .gjs-four-color {
color: #f45e43;
} }
.gjs-clm-tags .gjs-clm-tag { .gjs-four-color-h:hover {
/* background-color: $tag-color; */ color: #f45e43;
border: none;
box-shadow: none;
padding: 5px 8px;
text-shadow: none;
}
.gjs-field {
background-color: rgba(0, 0, 0, 0.15);
box-shadow: none;
}
.gjs-btnt.gjs-pn-active,
.gjs-pn-btn.gjs-pn-active {
box-shadow: none;
} }
.gjs-pn-btn:hover { .gjs-pn-btn:hover {
color: rgba(255, 255, 255, 0.75); color: #f45e43;
} }
.gjs-btnt.gjs-pn-active, .gjs-mdl-title {
.gjs-color-active, color: #f45e43;
.gjs-pn-btn.gjs-pn-active,
.gjs-pn-btn:active,
.gjs-block:hover {
color: #f45e43; /* #f46d4c,#e4505d */
} }
#gjs-rte-toolbar .gjs-rte-btn, .gjs-cv-canvas {
.gjs-btn-prim, width: calc(100% - 230px);
.gjs-btnt,
.gjs-clm-tags .gjs-sm-composite.gjs-clm-field,
.gjs-clm-tags .gjs-sm-field.gjs-sm-composite,
.gjs-clm-tags .gjs-sm-stack #gjs-sm-add,
.gjs-color-main,
.gjs-mdl-dialog,
.gjs-off-prv,
.gjs-pn-btn,
.gjs-pn-panel,
.gjs-sm-sector .gjs-sm-composite.gjs-clm-field,
.gjs-sm-sector .gjs-sm-field.gjs-sm-composite,
.gjs-sm-sector .gjs-sm-stack #gjs-sm-add {
color: #888686;
} }
#gjs-rte-toolbar, .gjs-pn-options {
.gjs-bg-main, right: 230px;
.gjs-clm-select option,
.gjs-clm-tags .gjs-sm-colorp-c,
.gjs-editor,
.gjs-mdl-dialog,
.gjs-nv-item .gjs-nv-title-c,
.gjs-off-prv,
.gjs-pn-panel,
.gjs-select option,
.gjs-sm-sector .gjs-sm-colorp-c,
.gjs-sm-select option,
.gjs-sm-unit option,
.sp-container,
.gjs-block {
background-color: #2c2e35;
} }
.gjs-import-label, .gjs-pn-views {
.gjs-export-label { width: 230px;
margin-bottom: 10px;
font-size: 13px;
} }
.gjs-mdl-dialog .gjs-btn-import { .gjs-pn-views .gjs-pn-buttons {
margin-top: 10px; justify-content: space-around;
margin: 0 16px;
} }
.gjs-pn-views-container {
width: 230px;
}
.gjs-mdl-dialog {
max-width: 1060px;
}
/* Code Mirror styles */
.CodeMirror { .CodeMirror {
border-radius: 3px; background: #15202d !important;
height: 450px; height: 450px;
font-family: sans-serif, monospace;
letter-spacing: 0.3px;
font-size: 12px;
} }
/* Extra */ .CodeMirror-gutters {
background: #1e2837 !important;
.gjs-block {
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 3px;
margin: 10px 2.5% 5px;
box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.15);
transition: box-shadow 0.2s ease 0s;
} }
.gjs-block:hover { .CodeMirror-linenumber {
box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.15); color: #3b4555 !important;
} }
#gjs-pn-views-container.gjs-pn-panel { /* Panels buttons */
padding: 39px 0 0;
.gjs-pn-devices-c {
padding-left: 5px;
} }
#gjs-pn-views.gjs-pn-panel { .gjs-pn-options {
padding: 0; padding-right: 10px;
border: none;
} }
#gjs-pn-views .gjs-pn-btn { .gjs-pn-devices-c .fa-desktop {
margin: 0; margin-right: 10px;
height: 40px;
padding: 10px;
width: 25%;
border-bottom: 2px solid rgba(0, 0, 0, 0.3);
} }
#gjs-pn-views .gjs-pn-active { .gjs-pn-options .fa-repeat,
/* .gjs-pn-devices-c .fa-arrows-alt {
color: rgba(255, 255, 255, 0.9); margin-right: 4px;
border-bottom: 2px solid #f45e43; padding-right: 16px;
*/ border-right: dotted 1px #3b4555;
border-radius: 0;
} }
#gjs-pn-devices-c { .gjs-pn-devices-c .fa-arrows-alt {
padding-left: 30px; padding-left: 16px
} }
#gjs-pn-options { .gjs-pn-devices-c .fa-arrows-alt.gjs-pn-active {
padding-right: 30px; border: none;
} }
.gjs-sm-composite .gjs-sm-properties {
display: flex; /* .gjs-pn-options .fa-undo {
flex-flow: row wrap; margin-left: 4px;
justify-content: space-between; padding-left: 16px;
border-left: dotted 1px #3b4555;
} */
/* MJML Plugin Styles */
/* Edit modal container */
.gjs-edit-container {
padding: 0;
} }
#gjs-sm-border-top-left-radius, /* Edit modal help */
#gjs-sm-border-top-right-radius, .gjs-edit-help {
#gjs-sm-border-bottom-left-radius, color: #7d7d91;
#gjs-sm-border-bottom-right-radius, font-size: 0.8rem;
#gjs-sm-margin-top, padding: 12px;
#gjs-sm-margin-bottom, padding-top: 0;
#gjs-sm-margin-right,
#gjs-sm-margin-left,
#gjs-sm-padding-top,
#gjs-sm-padding-bottom,
#gjs-sm-padding-right,
#gjs-sm-padding-left {
flex: 999 1 60px;
} }
#gjs-sm-border-width, /* Edit modal button save */
#gjs-sm-border-style, .gjs-edit-btn-save,
#gjs-sm-border-color { .gjs-btn-import {
flex: 999 1 80px; float: right;
font-size: 14px;
padding: 8px 16px;
margin: 12px 0 5px 0;
background: #c54b36;
} }
#gjs-sm-margin-left,
#gjs-sm-padding-left { /* Modal dialog */
order: 2;
.gjs-mdl-dialog-lg {
width: 700px;
} }
#gjs-sm-margin-right,
#gjs-sm-padding-right {
order: 3;
}
#gjs-sm-margin-bottom,
#gjs-sm-padding-bottom {
order: 4;
}
.gjs-field-radio {
width: 100%;
}
.gjs-field-radio #gjs-sm-input-holder {
display: flex;
}
.gjs-radio-item {
flex: 1 0 auto;
text-align: center;
}
.gjs-sm-sector .gjs-sm-property.gjs-sm-list {
width: 50%;
}
.gjs-mdl-content {
border-top: none;
}
.gjs-sm-sector .gjs-sm-property .gjs-sm-layer.gjs-sm-active {
background-color: rgba(255, 255, 255, 0.09);
}
/*
#gjs-pn-views-container,
#gjs-pn-views{
min-width: 270px;
}
*/
.gjs-f-button::before { content: 'B'; }
.gjs-f-divider::before { content: 'D'; }
.gjs-mdl-dialog-sm { .gjs-mdl-dialog-sm {
width: 300px; width: 300px;
} }
.gjs-mdl-dialog form .gjs-sm-property { .gjs-mdl-dialog form .gjs-sm-property {
font-size: 12px; font-size: 12px;
margin-bottom: 15px; margin-bottom: 15px;
} }
.gjs-mdl-dialog form .gjs-sm-label { .gjs-mdl-dialog form .gjs-sm-label {
margin-bottom: 5px; margin-bottom: 5px;
} }
.anim-spin { .anim-spin {
animation: 0.5s linear 0s normal none infinite running spin; animation: 0.5s linear 0s normal none infinite running spin;
} }
.form-status { .form-status {
float: right; float: right;
font-size: 14px; font-size: 14px;
} }
.text-danger { .text-danger {
color: #f92929; color: #f92929;
} }
@keyframes spin { @keyframes spin {
0% { 0% {
transform: rotate(0deg); transform: rotate(0deg);
} }
100% { 100% {
transform: rotate(360deg); transform: rotate(360deg);
} }
} }

File diff suppressed because one or more lines are too long

View file

@ -3,84 +3,70 @@
<mj-title>Hello World</mj-title> <mj-title>Hello World</mj-title>
</mj-head> </mj-head>
<mj-body> <mj-body>
<mj-container>
<!-- Company Header --> <!-- Company Header -->
<mj-section background-color="#f0f0f0"> <mj-section background-color="#f0f0f0">
<mj-column> <mj-column>
<mj-text font-style="italic" font-size="20" color="#626262"> <mj-text font-style="italic" font-size="20px" color="#626262">My Company</mj-text>
My Company </mj-column>
</mj-text> </mj-section>
</mj-column>
</mj-section>
<!-- Image Header --> <!-- Image Header -->
<mj-section background-url="./images/clouds.jpg" background-size="cover" background-repeat="no-repeat"> <mj-section background-url="./images/clouds.jpg" background-size="cover" background-repeat="no-repeat">
<mj-column> <mj-column>
<mj-text align="center" color="#fff" font-size="40" font-family="Helvetica Neue" padding-top="30px" padding-bottom="30px">Slogan here</mj-text> <mj-text align="center" color="#fff" font-size="40px" font-family="Helvetica Neue" padding-top="30px" padding-bottom="30px">Slogan here</mj-text>
<mj-button background-color="#F63A4D" href="#"> <mj-button background-color="#F63A4D" href="#">Promotion</mj-button>
Promotion </mj-column>
</mj-button> </mj-section>
</mj-column>
</mj-section>
<!-- Intro text --> <!-- Intro text -->
<mj-section background-color="#fafafa"> <mj-section background-color="#fafafa">
<mj-column width="400"> <mj-column width="400px">
<mj-text font-style="italic" font-size="20" font-family="Helvetica Neue" color="#cc2d2d">Attention!</mj-text> <mj-text font-style="italic" font-size="20px" font-family="Helvetica Neue" color="#cc2d2d">Attention!</mj-text>
<mj-text color="#525252"> <mj-text color="#525252">The MJML Mode is currently experimental and there're a few bugs you should avoid.
The MJML Mode is currently experimental and there're a few bugs you should avoid. <!-- <ul>
<ul> <li>Don't import the mj-head if you import a custom template.</li>
<li>Don't toggle visibility in the layer manager.</li> <li>Don't duplicate mj-image as the duplicate is missing the src attribute on export. This bug is probably not limited to mj-image.</li>
<li>Don't import the mj-head if you import a custom template.</li> <li>Don't use % values.</li>
<li>Don't duplicate mj-image as the duplicate is missing the src attribute on export. This bug is probably not limited to mj-image.</li> <li>Toggling visibility in the layer manager have no effect.</li>
<li>Don't use % values.</li> </ul> -->
</ul> It's generally working great and very promising. Thanks to @artf for making this all possible.
It's generally working great and very promising. Thanks to @artf for making this all possible.
</mj-text> </mj-text>
<mj-button background-color="#F45E43" href="https://github.com/artf/grapesjs-mjml">Learn more about GrapesJS MJML</mj-button> <mj-button background-color="#F45E43" href="https://github.com/artf/grapesjs-mjml">Learn more about GrapesJS MJML</mj-button>
</mj-column> </mj-column>
</mj-section> </mj-section>
<mj-raw>
<!-- Side image --> <!-- Side image -->
<mj-section background-color="white"> </mj-raw>
<mj-column> <mj-section background-color="white">
<mj-image src="./images/bird-1.jpg" /> <mj-column>
</mj-column> <mj-image src="./images/bird-1.jpg"></mj-image>
<mj-column> </mj-column>
<mj-text font-style="italic" font-size="20" font-family="Helvetica Neue" color="#626262"> <mj-column>
Amazing Birds <mj-text font-style="italic" font-size="20px" font-family="Helvetica Neue" color="#626262">Amazing Birds</mj-text>
</mj-text> <mj-text color="#525252">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum enim eget magna efficitur, eu semper augue semper. Aliquam erat volutpat. Cras id dui lectus. Vestibulum sed finibus lectus.</mj-text>
<mj-text color="#525252"> </mj-column>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum enim eget magna efficitur, eu semper augue semper. Aliquam erat volutpat. Cras id dui lectus. Vestibulum sed finibus lectus.</mj-text> </mj-section>
</mj-column>
</mj-section>
<!-- Icons --> <!-- Icons -->
<mj-section background-color="#fbfbfb"> <mj-section background-color="#fbfbfb">
<mj-column> <mj-column>
<mj-image width="200" src="./images/bird-2.jpg" /> <mj-image width="200px" src="./images/bird-2.jpg"></mj-image>
</mj-column> </mj-column>
<mj-column> <mj-column>
<mj-image width="200" src="./images/bird-3.jpg" /> <mj-image width="200px" src="./images/bird-3.jpg"></mj-image>
</mj-column> </mj-column>
<mj-column> <mj-column>
<mj-image width="200" src="./images/bird-4.jpg" /> <mj-image width="200px" src="./images/bird-4.jpg"></mj-image>
</mj-column> </mj-column>
</mj-section> </mj-section>
<!-- Footer --> <!-- Footer -->
<mj-section background-color="#e7e7e7"> <mj-section background-color="#e7e7e7">
<mj-column> <mj-column>
<mj-text color="#525252"> <mj-text color="#525252">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum enim eget magna efficitur, eu semper augue semper. Aliquam erat volutpat. Cras id dui lectus. Vestibulum sed finibus lectus, sit amet suscipit nibh. Proin nec commodo purus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum enim eget magna efficitur, eu semper augue semper. Aliquam erat volutpat. Cras id dui lectus. Vestibulum sed finibus lectus, sit amet suscipit nibh. Proin nec commodo purus. Sed eget Sed eget nulla elit. Nulla aliquet mollis faucibus.</mj-text>
nulla elit. Nulla aliquet mollis faucibus. <mj-button href="#">Hello There!</mj-button>
</mj-text> <mj-social>
<mj-button href="#">Hello There!</mj-button> <mj-social-element name="facebook"></mj-social-element>
<mj-social display="facebook twitter" /> <mj-social-element name="twitter"></mj-social-element>
</mj-column> </mj-social>
</mj-section> </mj-column>
</mj-section>
</mj-container>
</mj-body> </mj-body>
</mjml> </mjml>

View file

@ -11,7 +11,7 @@ Alerts: ...
/* --- General -------- */ /* --- General -------- */
form { form {
margin: .5em 0 1em; margin: .5em 0 1em;
} }
.form-group { .form-group {
@ -57,10 +57,10 @@ input[type='url'],
textarea, textarea,
select { select {
-webkit-appearance: none; -webkit-appearance: none;
-moz-appearance: none; -moz-appearance: none;
appearance: none; appearance: none;
background-color: transparent; background: #FFF;
border: 2px solid #DCE4EC; border: 2px solid #d3d7db;
border-radius: 4px; border-radius: 4px;
box-shadow: none; box-shadow: none;
box-sizing: border-box; box-sizing: border-box;
@ -85,10 +85,11 @@ select:focus {
} }
input[readonly] { input[readonly] {
color: #999999; color: #92908e;
} }
input[readonly]:focus { input[readonly]:focus {
border-color: #DCE4EC; border-color: #C5CCD2;
} }
input[type="checkbox"], input[type="checkbox"],
@ -135,7 +136,7 @@ textarea {
border-top-right-radius: 4px; border-top-right-radius: 4px;
} }
.input-group-addon > * { .input-group-addon>* {
line-height: 2.8em; line-height: 2.8em;
} }
@ -156,15 +157,34 @@ textarea {
display: none; display: none;
} }
.alert-success { color: #397740; background-color: #DEF0D9; border-color: #CFEAC8; } .alert-success {
.alert-info { color: #33708E; background-color: #D9EDF6; border-color: #BCDFF0; } color: #397740;
.alert-warning { color: #8A6D3F; background-color: #FCF8E4; border-color: #F9F2CE; } background-color: #DEF0D9;
.alert-danger { color: #AA4144; background-color: #F2DEDE; border-color: #EBCCCC; } border-color: #CFEAC8;
}
.alert-info {
color: #33708E;
background-color: #D9EDF6;
border-color: #BCDFF0;
}
.alert-warning {
color: #8A6D3F;
background-color: #FCF8E4;
border-color: #F9F2CE;
}
.alert-danger {
color: #AA4144;
background-color: #F2DEDE;
border-color: #EBCCCC;
}
/* --- GPG Key ------------- */ /* --- GPG Key ------------- */
.form-group.gpg > label { .form-group.gpg>label {
display: inline-block; display: inline-block;
} }
@ -213,4 +233,4 @@ form a {
form a:hover { form a:hover {
text-decoration: underline; text-decoration: underline;
} }

View file

@ -18,6 +18,10 @@
width: 100%; width: 100%;
} }
.gjs-one-bg {
background: #373d49;
}
#toast-container { #toast-container {
top: auto !important; top: auto !important;
bottom: 5px; bottom: 5px;
@ -31,8 +35,12 @@
font-family: Helvetica, sans-serif; font-family: Helvetica, sans-serif;
} }
#toast-container > div { #toast-container > div {
opacity: 0.95; opacity: 0.98;
} }
.toast-warning {
background-color: rgb(226, 116, 13)
}
#merge-tag-reference-container { #merge-tag-reference-container {
text-align: left; text-align: left;
font-size: 14px; font-size: 14px;
@ -40,6 +48,10 @@
#merge-tag-reference-container table th { #merge-tag-reference-container table th {
padding: 5px 20px 5px 0; padding: 5px 20px 5px 0;
} }
[data-tooltip]::after {
font-size: 11px;
}
</style> </style>
@ -135,52 +147,52 @@
'X-CSRF-TOKEN': '{{csrfToken}}', 'X-CSRF-TOKEN': '{{csrfToken}}',
}, },
}, },
styleManager: {
clearProperties: true,
},
container : '#gjs', container : '#gjs',
fromElement: false, fromElement: false,
avoidInlineStyle: 0,
plugins: [], plugins: [],
pluginsOpts: {}, pluginsOpts: {},
}; };
if (mode === 'mjml') { if (mode === 'mjml') {
var serializer = new XMLSerializer(); var doc = document.createElement('mjml');
var doc = new DOMParser().parseFromString(resource.editorData.mjml, 'text/xml'); doc.innerHTML = resource.editorData.mjml.replace(/<[/]?mjml>/g, '');
// convert relative to absolute urls // Document head with title
['mj-wrapper', 'mj-section', 'mj-navbar', 'mj-hero', 'mj-image'].forEach(function(tagName) { var head = doc.getElementsByTagName('mj-head')[0];
var elements = doc.getElementsByTagName(tagName); if (!head) {
document.createElement('mj-head')
for (var i = 0; i < elements.length; i++) { document.prepend(head);
var node = elements[i];
var attrName = tagName === 'mj-image' ? 'src' : 'background-url';
var url = node.getAttribute(attrName);
if (url && url.substring(0, 2) === './') {
var absoluteUrl = serviceUrl + 'grapejs/templates/' + resource.editorData.template + '/' + url.substring(2);
node.setAttribute(attrName, absoluteUrl);
}
}
});
var title = doc.getElementsByTagName('mj-title')[0];
if (title) {
title.textContent = resource.name;
} }
var head = doc.getElementsByTagName('mj-head')[0]; var title = head.getElementsByTagName('mj-title')[0];
var mjHead = head ? serializer.serializeToString(head) : '<mj-head></mj-head>'; if (title) {
title.textContent = resource.name;
} else {
title = document.createElement('mj-title');
title.textContent = resource.name;
head.prepend(title);
}
var container = doc.getElementsByTagName('mj-container')[0]; c.plugins.push('grapesjs-mjml', 'gjs-preset-mjml');
var mjContainer = container ? serializer.serializeToString(container) : '<mj-container></mj-container>';
c.plugins.push('gjs-mjml', 'gjs-preset-mjml'); c.pluginsOpts['grapesjs-mjml'] = {
c.pluginsOpts['gjs-mjml'] = { editorBackgroundColor: "{{{editor.config.mjml.editorBackgroundColor}}}",
preMjml: '<mjml>' + mjHead + '<mj-body>', canvasBackgroundStyle: "{{{editor.config.mjml.canvasBackgroundStyle}}}",
postMjml: '</mj-body></mjml>', canvasLabelsColor: "{{{editor.config.mjml.canvasLabelsColor}}}",
}; };
c.components = mjContainer;
c.pluginsOpts['gjs-preset-mjml'] = {
mailtrain: {
id: resource.id,
subject: resource.subject,
serviceUrl: serviceUrl,
template: resource.editorData.template
}
};
c.components = doc.outerHTML;
} }
if (mode === 'html') { if (mode === 'html') {
@ -212,10 +224,6 @@
editor.AssetManager.add(data.files); editor.AssetManager.add(data.files);
}); });
function getMjml() {
var c = config.pluginsOpts['gjs-mjml'];
return c.preMjml + editor.getHtml() + c.postMjml;
}
function getPreparedHtml(callback) { function getPreparedHtml(callback) {
var html; var html;
@ -286,7 +294,7 @@
getPreparedHtml(function(html) { getPreparedHtml(function(html) {
var editorData = '{{editor.mode}}' === 'mjml' ? { var editorData = '{{editor.mode}}' === 'mjml' ? {
template: resource.editorData.template, template: resource.editorData.template,
mjml: getMjml(), mjml: editor.getHtml(),
} : { } : {
template: resource.editorData.template, template: resource.editorData.template,
css: editor.getCss(), css: editor.getCss(),
@ -308,6 +316,7 @@
.success(function() { .success(function() {
window.bridge.lastSavedHtml = html; window.bridge.lastSavedHtml = html;
toastr.success('Sucessfully saved'); toastr.success('Sucessfully saved');
editor.UndoManager.clear();
}) })
.fail(function(data) { .fail(function(data) {
toastr.error(data.responseText || 'An error occured while saving the document'); toastr.error(data.responseText || 'An error occured while saving the document');
@ -324,7 +333,8 @@
// Close Button // Close Button
$('#mt-close').on('click', function() { $('#mt-close').on('click', function() {
if (confirm('Unsaved changes will be lost. Close now?') === true) { var haveChanges = (editor.UndoManager.hasUndo() || editor.UndoManager.hasRedo());
if (!haveChanges || confirm('Unsaved changes will be lost. Close now?') === true) {
window.bridge.exit window.bridge.exit
? window.bridge.exit() ? window.bridge.exit()
: window.location.href = '/{{type}}s/edit/{{resource.id}}?tab=template'; : window.location.href = '/{{type}}s/edit/{{resource.id}}?tab=template';
@ -346,26 +356,20 @@
var testContentEl = testContainer.querySelector('input[name=html]'); var testContentEl = testContainer.querySelector('input[name=html]');
cmdm.add('send-test', { cmdm.add('send-test', {
run(editor, sender) { run(editor, sender = {}) {
// TODO: Show a spinner // TODO: Show a spinner
getPreparedHtml(function(html) { getPreparedHtml(function(html) {
sender.set('active', 0);
var mdlDialog = document.querySelector('.gjs-mdl-dialog'); var mdlDialog = document.querySelector('.gjs-mdl-dialog');
testContentEl.value = html; testContentEl.value = html;
mdlDialog.className += ' ' + mdlClass; mdlDialog.className += ' ' + mdlClass;
testContainer.style.display = 'block'; testContainer.style.display = 'block';
md.setTitle('Test your Newsletter'); md.setTitle('Test your Newsletter');
var modalContent = $('<div>').append(testContainer).html(); var modalContent = $('<div/>').append(testContainer)[0].outerHTML;
for(var i=0; i<100; i++) { md.setContent(modalContent);
try {
md.setContent(modalContent);
break;
} catch(err) {}
}
testContainerCopy = $(".gjs-mdl-dialog #test-form"); testContainerCopy = $(".gjs-mdl-dialog #test-form");
var statusFormElC = document.querySelector('.gjs-mdl-dialog .form-status'); var statusFormElC = document.querySelector('.gjs-mdl-dialog .form-status');
var statusFormEl = document.querySelector('.gjs-mdl-dialog .form-status i'); var statusFormEl = document.querySelector('.gjs-mdl-dialog .form-status i');
@ -380,7 +384,7 @@
statusFormElC.style.opacity = '0'; statusFormElC.style.opacity = '0';
statusFormEl.removeAttribute('data-tooltip'); statusFormEl.removeAttribute('data-tooltip');
md.close(); md.close();
toastr.success('Testmail sent'); toastr.success('Test mail sent');
} else if (res.errors) { } else if (res.errors) {
statusFormEl.className = 'fa fa-exclamation-circle'; statusFormEl.className = 'fa fa-exclamation-circle';
statusFormEl.setAttribute('data-tooltip', res.errors); statusFormEl.setAttribute('data-tooltip', res.errors);
@ -403,51 +407,40 @@
var email = $('.gjs-mdl-dialog #test-form input[name=email]').val(); var email = $('.gjs-mdl-dialog #test-form input[name=email]').val();
isValidEmail(email) && localStorage.setItem('testemail', email); isValidEmail(email) && localStorage.setItem('testemail', email);
}); });
md.open(); md.open();
md.getModel().once('change:open', function() { md.onceClose(function() {
md.setContent(' ');
mdlDialog.className = mdlDialog.className.replace(mdlClass, ''); mdlDialog.className = mdlDialog.className.replace(mdlClass, '');
sender.set && sender.set('active', 0);
//clean status //clean status
}); });
}); });
} }
}); });
pnm.addButton('options', {
id: 'send-test',
className: 'fa fa-paper-plane',
command: 'send-test',
attributes: {
'title': 'Test Newsletter',
'data-tooltip-pos': 'bottom',
},
});
// Merge Tag Reference command // Merge Tag Reference command
var mergeTagReferenceContainer = document.getElementById('merge-tag-reference-container'); var mergeTagReferenceContainer = document.getElementById('merge-tag-reference-container');
cmdm.add('open-merge-tag-reference', { cmdm.add('open-merge-tag-reference', {
run(editor, sender) { run(editor, sender = {}) {
sender.set('active', 0);
var mdlDialog = document.querySelector('.gjs-mdl-dialog'); var mdlDialog = document.querySelector('.gjs-mdl-dialog');
mdlDialog.className += ' gjs-mdl-dialog-lg'; mdlDialog.className += ' gjs-mdl-dialog-lg';
mergeTagReferenceContainer.style.display = 'block'; mergeTagReferenceContainer.style.display = 'block';
md.setTitle('Merge tag reference'); md.setTitle('Merge tag reference');
for(var i=0; i<100; i++) { md.setContent(mergeTagReferenceContainer);
try {
md.setContent(mergeTagReferenceContainer);
break;
} catch(err) {}
}
md.open(); md.open();
md.getModel().once('change:open', function() { md.onceClose(function() {
md.setContent(' ');
mdlDialog.className = mdlDialog.className.replace('gjs-mdl-dialog-lg', ''); mdlDialog.className = mdlDialog.className.replace('gjs-mdl-dialog-lg', '');
sender.set && sender.set('active', 0);
}); });
} }
}); });
// Add buttons
pnm.addButton('options', { pnm.addButton('options', {
id: 'view-merge-tag-reference', id: 'view-merge-tag-reference',
className: 'fa fa-tags', className: 'fa fa-tags',
@ -459,20 +452,56 @@
}); });
pnm.addButton('options', {
id: 'send-test',
className: 'fa fa-paper-plane',
command: 'send-test',
attributes: {
'title': 'Test Newsletter',
'data-tooltip-pos': 'bottom'
},
});
// Simple warn notifier // Simple warn notifier
var origWarn = console.warn;
toastr.options = { toastr.options = {
closeButton: true, closeButton: true,
preventDuplicates: true, preventDuplicates: true,
showDuration: 250, showDuration: 250,
hideDuration: 150 hideDuration: 150
}; };
console.warn = function(msg) {
toastr.warning(msg); console.lastLog = [];
origWarn(msg); console.origWarn = console.warn.bind(console);
console.origError = console.error.bind(console);
var console2toastrTimeout;
var console2toastr = function(callback, args) {
clearTimeout(console2toastrTimeout);
var messages = Array.from(args).map((e) => typeof (e) === 'object' ? e.message : e);
messages.forEach(function (msg) {
if (console.lastLog.indexOf(msg) === -1) callback(msg);
});
console.lastLog = messages;
console2toastrTimeout = setTimeout(function () { console.lastLog.length = 0; }, 1000);
}; };
console.warn = function() {
console2toastr(toastr.warning.bind(toastr), arguments);
console.origWarn.apply(console, arguments);
};
console.error = function () {
console2toastr(toastr.error.bind(toastr), arguments);
console.origError.apply(console, arguments);
};
// Disable history to use delete key
history.pushState(null, null, location.href);
window.onpopstate = function () {
history.go(1);
};
// Beautify tooltips // Beautify tooltips

View file

@ -4,20 +4,20 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>GrapesJS Newsletter Editor</title> <title>GrapesJS Newsletter Editor</title>
<link rel="stylesheet" href="/grapejs/dist/css/grapes.min.css?v=0.14.25"> <link rel="stylesheet" href="/grapejs/dist/css/grapes.min.css?v=0.15.8">
<link rel="stylesheet" href="/grapejs/dist/css/toastr.min.css?v=2.1.3"> <link rel="stylesheet" href="/grapejs/dist/css/toastr.min.css?v=2.1.3">
<link rel="stylesheet" href="/grapejs/dist/css/material.css"> <link rel="stylesheet" href="/grapejs/dist/css/material.css">
<link rel="stylesheet" href="/grapejs/dist/css/tooltip.css"> <link rel="stylesheet" href="/grapejs/dist/css/tooltip.css">
<script src="/javascript/jquery-2.2.1.min.js"></script> <script src="/javascript/jquery-2.2.1.min.js"></script>
<script src="/grapejs/dist/js/grapes.min.js?v=0.14.25"></script> <script src="/grapejs/dist/js/grapes.min.js?v=0.15.8"></script>
<script src="/grapejs/dist/js/toastr.min.js?v=2.1.3"></script> <script src="/grapejs/dist/js/toastr.min.js?v=2.1.3"></script>
<script src="/grapejs/dist/js/ajaxable.min.js?v=0.2.3"></script> <script src="/grapejs/dist/js/ajaxable.min.js?v=0.2.3"></script>
{{#switch editor.mode}} {{#switch editor.mode}}
{{#case "mjml"}} {{#case "mjml"}}
<link rel="stylesheet" href="/grapejs/dist/css/grapesjs-mjml.css?v=0.0.7"> <link rel="stylesheet" href="/grapejs/dist/css/grapesjs-mjml.css?v=0.0.8">
<script src="/grapejs/dist/js/grapesjs-mjml.min.js?v=0.0.27"></script> <script src="/grapejs/dist/js/grapesjs-mjml-custom.min.js?v=0.1.16"></script>
<script src="/grapejs/dist/js/grapesjs-preset-mjml.js"></script> <script src="/grapejs/dist/js/grapesjs-preset-mjml.js"></script>
{{/case}} {{/case}}
{{#case "html"}} {{#case "html"}}

View file

@ -3,19 +3,30 @@
<mj-title>{{title}}</mj-title> <mj-title>{{title}}</mj-title>
<mj-font name="Lato" href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic" /> <mj-font name="Lato" href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic" />
<mj-attributes> <mj-attributes>
<mj-all font-size="15px" color="#2D3E4F" font-family="Lato, Helvetica, Arial, sans-serif" /> <mj-all font-size="14px" color="#2D3E4F" font-family="Lato, Helvetica, Arial, sans-serif" />
<mj-class name="h1" font-size="42px" line-height="68px" color="#b4bcc2" /> <mj-class name="h1" font-size="36px" line-height="40px" color="#c2c9ce" />
<mj-class name="h3" font-size="24px" line-height="32px" /> <mj-class name="h3" font-size="24px" line-height="32px" />
<mj-class name="p" font-size="15px" line-height="24px" /> <mj-class name="p" font-size="15px" line-height="24px" />
<mj-class name="small" font-size="12px" line-height="16px" color="#999999" /> <mj-class name="small" font-size="12px" line-height="16px" color="#999999" />
<mj-class name="hr" border-width="1px" border-style="solid" border-color="#e4e5e6" /> <mj-class name="hr" border-width="2px" border-style="solid" border-color="#dadddf" />
<mj-class name="button" font-size="16px" background-color="#2D3E4F" color="white" align="left" inner-padding="16px 24px" border-radius="6px" /> <mj-class name="button" font-size="16px" background-color="#2D3E4F" color="white" align="left" inner-padding="16px 24px" border-radius="6px" css-class="button" />
<mj-class name="footer-text" font-size="12px" line-height="18px" color="#999999" /> <mj-class name="footer-text" font-size="12px" line-height="18px" color="#999999" />
</mj-attributes> </mj-attributes>
<mj-style>
a {
color:#2D3E4F;
text-decoration: none;
}
a:hover {
color:#1F68D5;
text-decoration: underline #ADBED7;
}
.button td a:hover {
background: #1e2a36 !important;
}
</mj-style>
</mj-head> </mj-head>
<mj-body> <mj-body background-color="#fbfafa">
<mj-container width="560" background-color="#ffffff">
<mj-raw> <mj-raw>
{{#if isWeb}} {{#if isWeb}}
<style> <style>
@ -52,11 +63,8 @@
<mj-raw> <mj-raw>
{{#if isWeb}} {{#if isWeb}}
<!-- fixes https://github.com/mjmlio/mjml/issues/359 -->
{{> subscription_footer_scripts btnBgColor='#2D3E4F' btnBgColorHover='#1A242F'}} {{> subscription_footer_scripts btnBgColor='#2D3E4F' btnBgColorHover='#1A242F'}}
{{/if}} {{/if}}
</mj-raw> </mj-raw>
</mj-container>
</mj-body> </mj-body>
</mjml> </mjml>

View file

@ -23,33 +23,6 @@
el.value = moment.tz.guess() || ''; el.value = moment.tz.guess() || '';
}); });
} }
// Fixes MJML Button until they do ...
// https://github.com/mjmlio/mjml/issues/359
var btnBgColor = '{{btnBgColor}}';
var btnBgColorHover = '{{btnBgColorHover}}';
if (btnBgColor) {
var s = document.createElement('style');
var c = document.createTextNode(
'.td-btn:hover { background-color: ' + btnBgColorHover + '; }' +
'.td-btn { cursor: pointer !important; }' +
'.a-btn { background-color: transparent !important; }'
);
s.appendChild(c);
document.getElementsByTagName('head')[0].appendChild(s);
forEach(document.querySelectorAll('a'), function(i, a) {
if (a.parentNode.getAttribute('bgcolor') === btnBgColor) {
a.target = '_self';
a.className += 'a-btn';
a.parentNode.className += 'td-btn';
a.parentNode.onclick = function() {
a.click();
};
}
});
}
})(); })();
</script> </script>