Obsoleting some old files
Transition to SPA-style client Basis for Mosaico template editor
This commit is contained in:
parent
7750232716
commit
c85f2d4440
942 changed files with 86311 additions and 967 deletions
481
obsolete/views/grapejs/editor.hbs
Normal file
481
obsolete/views/grapejs/editor.hbs
Normal file
|
@ -0,0 +1,481 @@
|
|||
<style>
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
iframe {
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
#gjs-wrapper {
|
||||
position: absolute;
|
||||
top: 34px;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#toast-container {
|
||||
top: auto !important;
|
||||
bottom: 5px;
|
||||
right: 325px;
|
||||
font-size: 13px;
|
||||
font-weight: lighter;
|
||||
}
|
||||
#toast-container > div,
|
||||
#toast-container > div:hover {
|
||||
box-shadow: 0 0 12px rgba(0, 0, 0, 0.1);
|
||||
font-family: Helvetica, sans-serif;
|
||||
}
|
||||
#toast-container > div {
|
||||
opacity: 0.95;
|
||||
}
|
||||
#merge-tag-reference-container {
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
}
|
||||
#merge-tag-reference-container table th {
|
||||
padding: 5px 20px 5px 0;
|
||||
}
|
||||
|
||||
/* Fixed width sidebar */
|
||||
#gjs > .gjs-editor > .gjs-cv-canvas { width: 100% !important; padding-right: 300px !important; }
|
||||
#gjs-pn-views, #gjs-pn-views-container { width: 300px !important; }
|
||||
#gjs-pn-options { right: 300px !important; }
|
||||
#gjs-pn-commands { width: 100% !important; padding-right: 310px !important; }
|
||||
|
||||
/* Hide the fullscreen button - doesn't work from within our iFrame */
|
||||
#gjs-pn-options .gjs-pn-btn.fa.fa-arrows-alt { display: none !important; }
|
||||
|
||||
/* Hide pencil icon on image toolbar, issue #195 */
|
||||
.gjs-toolbar > div > div.fa-pencil { display: none; }
|
||||
</style>
|
||||
|
||||
|
||||
{{> editor_navbar}}
|
||||
|
||||
|
||||
<div id="gjs-wrapper">
|
||||
<div id="gjs" style="height: 0px; overflow: hidden"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Test Newsletter Form -->
|
||||
|
||||
<form id="test-form" class="test-form" action="/editorapi/test?editor=grapejs" method="post" style="display: none">
|
||||
<div class="putsmail-c">
|
||||
<div class="gjs-sm-property" style="font-size: 10px">
|
||||
Hello! I'm a placerholder message.
|
||||
<span class="form-status" style="opacity: 0">
|
||||
<i class="fa fa-refresh anim-spin" aria-hidden="true"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gjs-sm-property">
|
||||
<div class="gjs-field">
|
||||
<span id="gjs-sm-input-holder">
|
||||
<input type="email" name="email" placeholder="Email" required>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gjs-sm-property">
|
||||
<div class="gjs-field">
|
||||
<span id="gjs-sm-input-holder">
|
||||
<input type="text" name="subject" placeholder="Subject" required value="Test {{resource.name}}">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="html">
|
||||
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
||||
<button class="gjs-btn-prim gjs-btn-import" style="width: 100%">SEND</button>
|
||||
</form>
|
||||
|
||||
|
||||
<!-- Merge Tag Reference -->
|
||||
|
||||
{{#if resource.mergeTags}}
|
||||
<div id="merge-tag-reference-container" style="display: none">
|
||||
<table class="">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Merge tag
|
||||
</th>
|
||||
<th>
|
||||
Description
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each resource.mergeTags}}
|
||||
<tr>
|
||||
<th>
|
||||
[{{key}}]
|
||||
</th>
|
||||
<td>
|
||||
{{value}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
||||
<script>
|
||||
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': '{{csrfToken}}' } });
|
||||
|
||||
var serviceUrl = '{{{serviceUrl}}}';
|
||||
var resource = {{{stringifiedResource}}};
|
||||
|
||||
var config = (function(mode) {
|
||||
var c = {
|
||||
clearOnRender: true,
|
||||
height: '100%',
|
||||
storageManager: {
|
||||
type: 'none'
|
||||
},
|
||||
assetManager: {
|
||||
assets: [],
|
||||
upload: '/editorapi/upload?type={{type}}&id={{resource.id}}&editor={{editor.name}}',
|
||||
uploadText: 'Drop images here or click to upload',
|
||||
},
|
||||
container : '#gjs',
|
||||
fromElement: false,
|
||||
plugins: [],
|
||||
pluginsOpts: {},
|
||||
};
|
||||
|
||||
if (mode === 'mjml') {
|
||||
var serializer = new XMLSerializer();
|
||||
var doc = new DOMParser().parseFromString(resource.editorData.mjml, 'text/xml');
|
||||
|
||||
// convert relative to absolute urls
|
||||
['mj-wrapper', 'mj-section', 'mj-navbar', 'mj-hero', 'mj-image'].forEach(function(tagName) {
|
||||
var elements = doc.getElementsByTagName(tagName);
|
||||
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
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 mjHead = head ? serializer.serializeToString(head) : '<mj-head></mj-head>';
|
||||
|
||||
var container = doc.getElementsByTagName('mj-container')[0];
|
||||
var mjContainer = container ? serializer.serializeToString(container) : '<mj-container></mj-container>';
|
||||
|
||||
c.plugins.push('gjs-mjml', 'gjs-preset-mjml');
|
||||
c.pluginsOpts['gjs-mjml'] = {
|
||||
preMjml: '<mjml>' + mjHead + '<mj-body>',
|
||||
postMjml: '</mj-body></mjml>',
|
||||
};
|
||||
c.components = mjContainer;
|
||||
}
|
||||
|
||||
if (mode === 'html') {
|
||||
c.plugins.push('gjs-preset-newsletter');
|
||||
c.pluginsOpts['gjs-preset-newsletter'] = {
|
||||
modalLabelImport: 'Paste all your code here below and click import',
|
||||
modalLabelExport: 'Copy the code and use it wherever you want',
|
||||
codeViewerTheme: 'material',
|
||||
importPlaceholder: '<table class="table"><tr><td class="cell">Hello world!</td></tr></table>',
|
||||
cellStyle: {
|
||||
'font-size': '12px',
|
||||
'font-weight': 300,
|
||||
'vertical-align': 'top',
|
||||
color: 'rgb(111, 119, 125)',
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
}
|
||||
};
|
||||
c.components = resource.editorData.html || resource.html || '';
|
||||
c.style = resource.editorData.css || '';
|
||||
}
|
||||
|
||||
return c;
|
||||
})('{{editor.mode}}');
|
||||
|
||||
var editor = grapesjs.init(config);
|
||||
|
||||
$.getJSON('/editorapi/upload?type={{type}}&id={{resource.id}}&editor={{editor.name}}', function(data) {
|
||||
editor.AssetManager.add(data.files);
|
||||
});
|
||||
|
||||
function getMjml() {
|
||||
var c = config.pluginsOpts['gjs-mjml'];
|
||||
return c.preMjml + editor.getHtml() + c.postMjml;
|
||||
}
|
||||
|
||||
function getPreparedHtml(callback) {
|
||||
var html;
|
||||
|
||||
switch ('{{editor.mode}}') {
|
||||
case 'html':
|
||||
html = editor.runCommand('gjs-get-inlined-html');
|
||||
html = '<!doctype html><html><head><meta charset="utf-8"><title>{{resource.name}}</title></head><body>' + html + '</body></html>';
|
||||
break;
|
||||
case 'mjml':
|
||||
var mjml = editor.runCommand('mjml-get-code');
|
||||
mjml.errors.length && mjml.errors.forEach(function(err) {
|
||||
console.warn(err.formattedMessage);
|
||||
});
|
||||
html = mjml.html;
|
||||
break;
|
||||
}
|
||||
|
||||
var frame = document.createElement('iframe');
|
||||
frame.width = 2048;
|
||||
frame.height = 0;
|
||||
document.body.appendChild(frame);
|
||||
var frameDoc = frame.contentDocument || frame.contentWindow.document;
|
||||
|
||||
var isLocalImage = function(src) {
|
||||
var a1 = document.createElement('a');
|
||||
var a2 = document.createElement('a');
|
||||
a1.href = serviceUrl;
|
||||
a2.href = src;
|
||||
return a1.host === a2.host;
|
||||
};
|
||||
|
||||
frame.onload = function() {
|
||||
var imgs = frameDoc.querySelectorAll('img');
|
||||
|
||||
for (var i = 0; i < imgs.length; i++) {
|
||||
var img = imgs[i];
|
||||
var m = img.src.match(/\/editorapi\/img\?src=([^&]*)/);
|
||||
var encodedSrc = m && m[1] || encodeURIComponent(img.src);
|
||||
if (isLocalImage(decodeURIComponent(encodedSrc))) {
|
||||
img.src = '/editorapi/img?src=' + encodedSrc + '&method=resize¶ms=' + img.clientWidth + '%2C' + img.clientHeight;
|
||||
}
|
||||
}
|
||||
|
||||
html = '<!doctype html>' + frameDoc.documentElement.outerHTML;
|
||||
document.body.removeChild(frame);
|
||||
callback(html);
|
||||
};
|
||||
|
||||
frameDoc.open();
|
||||
frameDoc.write(html);
|
||||
frameDoc.close();
|
||||
}
|
||||
|
||||
|
||||
// Save Button
|
||||
|
||||
window.bridge = window.bridge || {};
|
||||
|
||||
$('#mt-save').on('click', function() {
|
||||
|
||||
if ($(this).hasClass('busy')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$(this).addClass('busy');
|
||||
|
||||
getPreparedHtml(function(html) {
|
||||
var editorData = '{{editor.mode}}' === 'mjml' ? {
|
||||
template: resource.editorData.template,
|
||||
mjml: getMjml(),
|
||||
} : {
|
||||
template: resource.editorData.template,
|
||||
css: editor.getCss(),
|
||||
html: editor.getHtml(),
|
||||
style: editor.getStyle(),
|
||||
components: editor.getComponents(),
|
||||
};
|
||||
|
||||
// TODO: Make templates and campaigns accept partial updates, i.e. don't require 'name' and 'list'
|
||||
var update = {
|
||||
id: resource.id,
|
||||
name: resource.name,
|
||||
{{#if resource.list}} list: resource.list, {{/if}}
|
||||
editorData: JSON.stringify(editorData),
|
||||
html: html,
|
||||
};
|
||||
|
||||
$.post('/editorapi/update?type={{type}}&editor={{editor.name}}', update, null, 'html')
|
||||
.success(function() {
|
||||
window.bridge.lastSavedHtml = html;
|
||||
toastr.success('Sucessfully saved');
|
||||
})
|
||||
.fail(function(data) {
|
||||
toastr.error(data.responseText || 'An error occured while saving the document');
|
||||
})
|
||||
.always(function() {
|
||||
setTimeout(function() {
|
||||
$('#mt-save').removeClass('busy');
|
||||
}, 200); // Don't save too fast
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Close Button
|
||||
|
||||
$('#mt-close').on('click', function() {
|
||||
if (confirm('Unsaved changes will be lost. Close now?') === true) {
|
||||
window.bridge.exit
|
||||
? window.bridge.exit()
|
||||
: window.location.href = '/{{type}}s/edit/{{resource.id}}?tab=template';
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Commands
|
||||
|
||||
var mdlClass = 'gjs-mdl-dialog-sm';
|
||||
var pnm = editor.Panels;
|
||||
var cmdm = editor.Commands;
|
||||
var md = editor.Modal;
|
||||
|
||||
|
||||
// Test email command
|
||||
|
||||
var testContainer = document.getElementById('test-form');
|
||||
var testContentEl = testContainer.querySelector('input[name=html]');
|
||||
|
||||
cmdm.add('send-test', {
|
||||
run(editor, sender) {
|
||||
// TODO: Show a spinner
|
||||
getPreparedHtml(function(html) {
|
||||
sender.set('active', 0);
|
||||
var modalContent = md.getContentEl();
|
||||
var mdlDialog = document.querySelector('.gjs-mdl-dialog');
|
||||
testContentEl.value = html;
|
||||
mdlDialog.className += ' ' + mdlClass;
|
||||
testContainer.style.display = 'block';
|
||||
md.setTitle('Test your Newsletter');
|
||||
md.setContent(testContainer);
|
||||
md.open();
|
||||
md.getModel().once('change:open', function() {
|
||||
mdlDialog.className = mdlDialog.className.replace(mdlClass, '');
|
||||
//clean status
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
pnm.addButton('options', {
|
||||
id: 'send-test',
|
||||
className: 'fa fa-paper-plane',
|
||||
command: 'send-test',
|
||||
attributes: {
|
||||
'title': 'Test Newsletter',
|
||||
'data-tooltip-pos': 'bottom',
|
||||
},
|
||||
});
|
||||
|
||||
var statusFormElC = document.querySelector('.form-status');
|
||||
var statusFormEl = document.querySelector('.form-status i');
|
||||
|
||||
var ajaxTest = ajaxable(testContainer, { headers: { 'X-CSRF-TOKEN': '{{csrfToken}}' } })
|
||||
.onStart(function() {
|
||||
statusFormEl.className = 'fa fa-refresh anim-spin';
|
||||
statusFormElC.style.opacity = '1';
|
||||
statusFormElC.className = 'form-status';
|
||||
})
|
||||
.onResponse(function(res) {
|
||||
if (res.data) {
|
||||
statusFormElC.style.opacity = '0';
|
||||
statusFormEl.removeAttribute('data-tooltip');
|
||||
md.close();
|
||||
toastr.success('Testmail sent');
|
||||
} else if (res.errors) {
|
||||
statusFormEl.className = 'fa fa-exclamation-circle';
|
||||
statusFormEl.setAttribute('data-tooltip', res.errors);
|
||||
statusFormElC.className = 'form-status text-danger';
|
||||
toastr.error(res.errors);
|
||||
}
|
||||
});
|
||||
|
||||
// Remember testemail address
|
||||
|
||||
var isValidEmail = function(email) {
|
||||
return /\S+@\S+\.\S+/.test(email);
|
||||
};
|
||||
|
||||
if (isValidEmail(localStorage.getItem('testemail'))) {
|
||||
$('#test-form input[name=email]').val(localStorage.getItem('testemail'));
|
||||
}
|
||||
|
||||
$('#test-form').on('submit', function() {
|
||||
var email = $('#test-form input[name=email]').val();
|
||||
isValidEmail(email) && localStorage.setItem('testemail', email);
|
||||
});
|
||||
|
||||
|
||||
// Merge Tag Reference command
|
||||
|
||||
var mergeTagReferenceContainer = document.getElementById('merge-tag-reference-container');
|
||||
cmdm.add('open-merge-tag-reference', {
|
||||
run(editor, sender) {
|
||||
sender.set('active', 0);
|
||||
var mdlDialog = document.querySelector('.gjs-mdl-dialog');
|
||||
mdlDialog.className += ' gjs-mdl-dialog-lg';
|
||||
mergeTagReferenceContainer.style.display = 'block';
|
||||
md.setTitle('Merge tag reference');
|
||||
md.setContent(mergeTagReferenceContainer);
|
||||
md.open();
|
||||
md.getModel().once('change:open', function() {
|
||||
mdlDialog.className = mdlDialog.className.replace('gjs-mdl-dialog-lg', '');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
pnm.addButton('options', {
|
||||
id: 'view-merge-tag-reference',
|
||||
className: 'fa fa-tags',
|
||||
command: 'open-merge-tag-reference',
|
||||
attributes: {
|
||||
'title': 'Merge tag reference',
|
||||
'data-tooltip-pos': 'bottom',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// Simple warn notifier
|
||||
|
||||
var origWarn = console.warn;
|
||||
toastr.options = {
|
||||
closeButton: true,
|
||||
preventDuplicates: true,
|
||||
showDuration: 250,
|
||||
hideDuration: 150
|
||||
};
|
||||
console.warn = function(msg) {
|
||||
toastr.warning(msg);
|
||||
origWarn(msg);
|
||||
};
|
||||
|
||||
|
||||
// Beautify tooltips
|
||||
|
||||
$(document).ready(function() {
|
||||
$('*[title]').each(function() {
|
||||
var el = $(this);
|
||||
var title = el.attr('title').trim();
|
||||
if (title) {
|
||||
el.attr('data-tooltip', el.attr('title'));
|
||||
el.attr('title', '');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
34
obsolete/views/grapejs/layout-editor.hbs
Normal file
34
obsolete/views/grapejs/layout-editor.hbs
Normal file
|
@ -0,0 +1,34 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>GrapesJS Newsletter Editor</title>
|
||||
|
||||
<link rel="stylesheet" href="/grapejs/dist/css/grapes.min.css?v=0.5.41">
|
||||
<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/tooltip.css">
|
||||
|
||||
<script src="/javascript/jquery-2.2.1.min.js"></script>
|
||||
<script src="/grapejs/dist/js/grapes.min.js?v=0.5.41"></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>
|
||||
|
||||
{{#switch editor.mode}}
|
||||
{{#case "mjml"}}
|
||||
<link rel="stylesheet" href="/grapejs/dist/css/grapesjs-mjml.css?v=0.0.7">
|
||||
<script src="/grapejs/dist/js/grapesjs-mjml.min.js?v=0.0.7"></script>
|
||||
<script src="/grapejs/dist/js/grapesjs-preset-mjml.js"></script>
|
||||
{{/case}}
|
||||
{{#case "html"}}
|
||||
<link rel="stylesheet" href="/grapejs/dist/css/grapesjs-preset-newsletter.css?v=0.2.3">
|
||||
<script src="/grapejs/dist/js/grapesjs-preset-newsletter.min.js?v=0.2.3"></script>
|
||||
{{/case}}
|
||||
{{/switch}}
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{{{body}}}
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue