diff --git a/.gitignore b/.gitignore
index c9f7cd07..51c95140 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,15 @@ npm-debug.log
config/development.*
config/production.*
dump.rdb
+
+public/mosaico/uploads/*
+!public/mosaico/uploads/README.md
+public/mosaico/custom/*
+!public/mosaico/custom/README.md
+public/mosaico/templates/*
+!public/mosaico/templates/versafix-1
+
+public/grapejs/uploads/*
+!public/grapejs/uploads/README.md
+public/grapejs/templates/*
+!public/grapejs/templates/demo
diff --git a/app.js b/app.js
index 51a4a915..6252b44b 100644
--- a/app.js
+++ b/app.js
@@ -35,6 +35,9 @@ let webhooks = require('./routes/webhooks');
let subscription = require('./routes/subscription');
let archive = require('./routes/archive');
let api = require('./routes/api');
+let editorapi = require('./routes/editorapi');
+let grapejs = require('./routes/grapejs');
+let mosaico = require('./routes/mosaico');
let app = express();
@@ -205,6 +208,9 @@ app.use('/webhooks', webhooks);
app.use('/subscription', subscription);
app.use('/archive', archive);
app.use('/api', api);
+app.use('/editorapi', editorapi);
+app.use('/grapejs', grapejs);
+app.use('/mosaico', mosaico);
// catch 404 and forward to error handler
app.use((req, res, next) => {
diff --git a/config/default.toml b/config/default.toml
index c547295e..55b7f786 100644
--- a/config/default.toml
+++ b/config/default.toml
@@ -24,6 +24,8 @@ title="mailtrain"
# Enabled HTML editors
editors=[
["summernote", "Summernote"],
+ ["grapejs", "GrapeJS"],
+ ["mosaico", "Mosaico"],
["codeeditor", "Code Editor"]
]
@@ -123,3 +125,13 @@ host="127.0.0.1"
# How many parallel sender processes to spawn
# You can use more than 1 process only if you have Redis enabled
processes=1
+
+[mosaico]
+# Installed templates
+templates=[["versafix-1", "Versafix One"]]
+# Inject custom scripts from public/mosaico/custom/
+# customscripts=["some-lib.js", "my-mosaico-plugin.js"]
+
+[grapejs]
+# Installed templates
+templates=[["demo", "Demo Template"]]
diff --git a/languages/mailtrain.pot b/languages/mailtrain.pot
index aa434c94..5630ab85 100644
--- a/languages/mailtrain.pot
+++ b/languages/mailtrain.pot
@@ -8,7 +8,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"POT-Creation-Date: 2017-03-07 19:52+0000\n"
+"POT-Creation-Date: 2017-03-10 08:57+0000\n"
#: views/archive/layout.hbs:1
#: views/layout.hbs:1
@@ -65,7 +65,7 @@ msgstr ""
#: views/users/forgot.hbs:1
#: views/users/login.hbs:1
#: views/users/reset.hbs:1
-#: app.js:169
+#: app.js:172
msgid "Home"
msgstr ""
@@ -118,7 +118,7 @@ msgstr ""
#: views/campaigns/delivered.hbs:7
#: views/campaigns/opened.hbs:7
#: views/campaigns/unsubscribed.hbs:7
-#: views/lists/subscription/import-failed.hbs:9
+#: views/lists/subscription/import-failed.hbs:8
#: views/lists/view.hbs:18
#: views/triggers/triggered.hbs:6
msgid "Address"
@@ -216,6 +216,7 @@ msgstr ""
#: views/lists/create.hbs:7
#: views/lists/edit.hbs:10
#: views/lists/lists.hbs:8
+#: views/mosaico/editor.hbs:3
#: views/partials/merge-tag-reference.hbs:4
#: views/templates/create.hbs:9
#: views/templates/edit.hbs:8
@@ -1451,6 +1452,7 @@ msgstr ""
#: views/lists/fields/edit.hbs:30
#: views/lists/fields/fields.hbs:8
+#: views/mosaico/editor.hbs:2
#: views/partials/merge-tag-reference.hbs:3
msgid "Merge tag"
msgstr ""
@@ -1789,10 +1791,17 @@ msgid "Failed addresses"
msgstr ""
#: views/lists/subscription/import-failed.hbs:6
+msgid ""
+"Role-based addresses like postmaster@example.com are blocked when "
+"importing. Subscribers with role-based email addresses can join your list "
+"using the subscription form"
+msgstr ""
+
+#: views/lists/subscription/import-failed.hbs:7
msgid "see here"
msgstr ""
-#: views/lists/subscription/import-failed.hbs:10
+#: views/lists/subscription/import-failed.hbs:9
msgid "Fail reason"
msgstr ""
@@ -1908,17 +1917,76 @@ msgstr ""
msgid "Restart"
msgstr ""
+#: views/mosaico/editor.hbs:1
+#: views/partials/merge-tag-reference.hbs:1
+msgid "Merge tag reference"
+msgstr ""
+
+#: views/mosaico/editor.hbs:4
+msgid "MOSAICO Responsive Email Designer"
+msgstr ""
+
+#: views/mosaico/editor.hbs:5
+msgid "Sucessfully saved"
+msgstr ""
+
+#: views/mosaico/editor.hbs:6
+msgid "An error occured while saving the document"
+msgstr ""
+
+#: views/mosaico/editor.hbs:7
+msgid "Unsaved changes will be lost. Close now?"
+msgstr ""
+
+#: views/mosaico/editor.hbs:8
+#: views/mosaico/editor.hbs:9
+msgid "Tags"
+msgstr ""
+
#: views/partials/codeeditor.hbs:1
+#: views/partials/grapejs.hbs:1
+#: views/partials/mosaico.hbs:1
#: views/partials/summernote.hbs:1
msgid "Template content (HTML)"
msgstr ""
+#: views/partials/editor-navbar.hbs:1
+msgid "SAVE"
+msgstr ""
+
+#: views/partials/editor-navbar.hbs:2
+msgid "SAVING"
+msgstr ""
+
+#: views/partials/editor-navbar.hbs:3
+msgid "CLOSE"
+msgstr ""
+
+#: views/partials/grapejs.hbs:2
+msgid "Open GrapeJS"
+msgstr ""
+
#: views/partials/html-preview.hbs:1
msgid "Toggle HTML preview"
msgstr ""
-#: views/partials/merge-tag-reference.hbs:1
-msgid "Merge tag reference"
+#: views/partials/html-to-text.hbs:1
+msgid ""
+"To extract the text from HTML click here."
+msgstr ""
+
+#: views/partials/html-to-text.hbs:2
+msgid ""
+"Please note that your existing plaintext in the field above will be "
+"overwritten. This feature uses the Premailer API, a third party service. Their Terms of "
+"Service and Privacy Policy apply."
+msgstr ""
+
+#: views/partials/html-to-text.hbs:3
+msgid "An error occurred while talking to the server"
msgstr ""
#: views/partials/merge-tag-reference.hbs:2
@@ -1929,6 +1997,10 @@ msgid ""
"text value used when TAG_NAME
is empty."
msgstr ""
+#: views/partials/mosaico.hbs:2
+msgid "Open Mosaico"
+msgstr ""
+
#: views/partials/plaintext.hbs:1
msgid "Template content (plaintext)"
msgstr ""
@@ -2891,6 +2963,31 @@ msgstr ""
msgid "Please enter a new password."
msgstr ""
+#: lib/editor-helpers.js:16
+#: routes/templates.js:109
+msgid "Could not find template with specified ID"
+msgstr ""
+
+#: lib/editor-helpers.js:32
+#: routes/archive.js:140
+#: routes/campaigns.js:131
+#: routes/campaigns.js:295
+#: routes/campaigns.js:390
+#: routes/campaigns.js:435
+#: routes/campaigns.js:475
+#: routes/campaigns.js:739
+#: routes/campaigns.js:762
+#: routes/campaigns.js:781
+#: routes/campaigns.js:803
+#: routes/triggers.js:146
+msgid "Could not find campaign with specified ID"
+msgstr ""
+
+#: lib/editor-helpers.js:46
+#: routes/editorapi.js:276
+msgid "Invalid resource type"
+msgstr ""
+
#: lib/feed.js:31
msgid "Bad status code %s"
msgstr ""
@@ -3364,37 +3461,26 @@ msgstr ""
#: routes/archive.js:31
#: routes/archive.js:43
#: routes/archive.js:55
-#: app.js:211
+#: app.js:217
msgid "Not Found"
msgstr ""
#: routes/archive.js:116
-#: services/sender.js:447
+#: services/sender.js:451
msgid "Received status code %s from %s"
msgstr ""
-#: routes/archive.js:140
-#: routes/campaigns.js:131
-#: routes/campaigns.js:295
-#: routes/campaigns.js:390
-#: routes/campaigns.js:435
-#: routes/campaigns.js:475
-#: routes/campaigns.js:739
-#: routes/campaigns.js:762
-#: routes/campaigns.js:781
-#: routes/campaigns.js:803
-#: routes/triggers.js:146
-msgid "Could not find campaign with specified ID"
-msgstr ""
-
#: routes/archive.js:148
#: routes/campaigns.js:789
msgid "Attachment not found"
msgstr ""
#: routes/campaigns.js:26
+#: routes/editorapi.js:33
#: routes/fields.js:13
+#: routes/grapejs.js:13
#: routes/lists.js:49
+#: routes/mosaico.js:14
#: routes/segments.js:13
#: routes/settings.js:23
#: routes/templates.js:17
@@ -3520,6 +3606,19 @@ msgstr ""
msgid "Could not delete attachment"
msgstr ""
+#: routes/editorapi.js:39
+msgid "Invalid editor name"
+msgstr ""
+
+#: routes/editorapi.js:220
+#: routes/editorapi.js:246
+msgid "Method not supported"
+msgstr ""
+
+#: routes/editorapi.js:316
+msgid "Invalid resource type or ID"
+msgstr ""
+
#: routes/fields.js:28
#: routes/fields.js:64
#: routes/fields.js:118
@@ -3891,10 +3990,6 @@ msgstr ""
msgid "Template created"
msgstr ""
-#: routes/templates.js:109
-msgid "Could not find template with specified ID"
-msgstr ""
-
#: routes/templates.js:140
msgid "Template settings updated"
msgstr ""
diff --git a/package.json b/package.json
index a22bb2c2..dab0933f 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"jsxgettext-andris": "^0.9.0-patch.1"
},
"dependencies": {
+ "async": "^2.1.5",
"aws-sdk": "^2.24.0",
"bcrypt-nodejs": "0.0.3",
"body-parser": "^1.17.1",
@@ -51,8 +52,10 @@
"express-session": "^1.15.1",
"faker": "^4.1.0",
"feedparser": "^2.1.0",
+ "file-type": "^4.1.0",
"geoip-ultralight": "^0.1.5",
"gettext-parser": "^1.2.2",
+ "gm": "^1.23.0",
"handlebars": "^4.0.6",
"hbs": "^4.0.1",
"he": "^1.1.1",
@@ -60,21 +63,27 @@
"humanize": "0.0.9",
"is-url": "^1.2.2",
"isemail": "^2.2.1",
+ "jquery-file-upload-middleware": "^0.1.8",
"jsdom": "^9.11.0",
"juice": "^4.0.2",
"libmime": "^3.1.0",
"marked": "^0.3.6",
+ "memory-cache": "^0.1.6",
"mkdirp": "^0.5.1",
"moment-timezone": "^0.5.11",
"morgan": "^1.8.1",
"multer": "^1.3.0",
+ "multiparty": "^4.1.3",
"mysql": "^2.13.0",
+ "node-gettext": "^2.0.0-rc.0",
+ "node-mocks-http": "^1.6.1",
"nodemailer": "^3.1.5",
"nodemailer-openpgp": "^1.0.2",
"npmlog": "^4.0.2",
"openpgp": "^2.4.0",
"passport": "^0.3.2",
"passport-local": "^1.0.0",
+ "premailer-api": "^1.0.4",
"redfour": "^1.0.0",
"redis": "^2.6.5",
"request": "^2.80.0",
@@ -83,7 +92,6 @@
"slugify": "^1.1.0",
"smtp-server": "^2.0.2",
"striptags": "^3.0.1",
- "toml": "^2.3.2",
- "node-gettext": "^2.0.0-rc.0"
+ "toml": "^2.3.2"
}
}