diff --git a/assets/js/src/newsletter_editor/components/save.js b/assets/js/src/newsletter_editor/components/save.js index d6365db08c..6382a833fe 100644 --- a/assets/js/src/newsletter_editor/components/save.js +++ b/assets/js/src/newsletter_editor/components/save.js @@ -3,8 +3,10 @@ define([ 'mailpoet', 'backbone', 'backbone.marionette', - 'jquery' - ], function(App, MailPoet, Backbone, Marionette, jQuery) { + 'jquery', + 'blob', + 'filesaver' + ], function(App, MailPoet, Backbone, Marionette, jQuery, Blob, FileSaver) { "use strict"; @@ -54,31 +56,15 @@ define([ }; Module.exportTemplate = function(options) { - if (!window.Blob || !window.URL) { - // TODO: Gracefully exit on incompatible browsers - console.log('Template export requires a browser with Blob and URL support.'); - return; - } - var data = _.extend(options || {}, { body: App.getBody(), }); + var blob = new Blob( + [JSON.stringify(data)], + { type: 'application/json;charset=utf-8' } + ); - // Create a template file and force download it - - var blob = new window.Blob([JSON.stringify(data)], { type: 'application/json' }), - url = window.URL.createObjectURL(blob), - anchor = document.createElement('a'); - - anchor.href = url; - anchor.download = 'template.json'; - anchor.style.display = 'none'; - document.body.appendChild(anchor); - - anchor.click(); - - window.URL.revokeObjectURL(url); - document.body.removeChild(anchor); + FileSaver.saveAs(blob, 'template.json'); }; Module.SaveView = Marionette.LayoutView.extend({ diff --git a/assets/js/src/newsletters/templates.jsx b/assets/js/src/newsletters/templates.jsx index 6f9c771a57..c14932b874 100644 --- a/assets/js/src/newsletters/templates.jsx +++ b/assets/js/src/newsletters/templates.jsx @@ -1,6 +1,7 @@ define( [ 'react', + 'underscore', 'mailpoet', 'react-router', 'classnames', @@ -8,6 +9,7 @@ define( ], function( React, + _, MailPoet, Router, classNames, @@ -33,12 +35,21 @@ define( handleSubmit: function(e) { e.preventDefault(); - var reader = new FileReader(), + if (_.size(this.refs.templateFile.files) <= 0) return false; + + var file = _.first(this.refs.templateFile.files), + reader = new FileReader(), saveTemplate = this.saveTemplate; + reader.onload = function(e) { - saveTemplate(JSON.parse(e.target.result)); + try { + saveTemplate(JSON.parse(e.target.result)); + } catch (err) { + MailPoet.Notice.error('This template file appears to be malformed. Please try another one.'); + } }.bind(this); - reader.readAsText(this.refs.templateFile.files[0]); + + reader.readAsText(file); }, render: function() { return ( diff --git a/package.json b/package.json index 2b86b9fde7..45272ebf50 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,8 @@ "install": "napa" }, "napa": { + "blob": "eligrey/Blob.js.git", + "filesaver": "eligrey/FileSaver.js.git", "sticky-kit": "leafo/sticky-kit.git" }, "dependencies": { @@ -23,9 +25,9 @@ "moment": "^2.10.3", "napa": "^1.2.0", "papaparse": "4.1.1", - "react": "0.14.0", + "react": "^0.14.1", "react-checkbox-group": "0.2.2", - "react-dom": "^0.14.0", + "react-dom": "^0.14.1", "react-infinity": "1.2.2", "react-prefixr": "0.1.0", "react-router": "^1.0.0-rc3", diff --git a/webpack.config.js b/webpack.config.js index f6838db52d..5f0580f756 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -21,7 +21,9 @@ baseConfig = { 'backbone.supermodel$': 'backbone.supermodel/build/backbone.supermodel.js', 'sticky-kit': 'sticky-kit/jquery.sticky-kit', 'interact$': 'interact.js/interact.js', - 'spectrum$': 'spectrum-colorpicker/spectrum.js' + 'spectrum$': 'spectrum-colorpicker/spectrum.js', + 'blob$': 'blob/Blob.js', + 'filesaver$': 'filesaver/FileSaver.js' }, }, node: { @@ -41,6 +43,10 @@ baseConfig = { include: require.resolve('underscore'), loader: 'expose-loader?_', }, + { + include: /Blob.js$/, + loader: 'exports-loader?window.Blob', + }, { test: /backbone.supermodel/, loader: 'exports-loader?Backbone.SuperModel', @@ -82,6 +88,8 @@ config.push(_.extend({}, baseConfig, { 'select2', 'spectrum', 'sticky-kit', + 'blob', + 'filesaver', 'newsletter_editor/communicationsFix.js', 'newsletter_editor/App', @@ -145,6 +153,8 @@ config.push(_.extend({}, baseConfig, { 'backbone.supermodel', 'backbone.radio', 'select2', + 'blob', + 'filesaver', 'newsletter_editor/communicationsFix.js', 'newsletter_editor/App', @@ -209,6 +219,8 @@ config.push(_.extend({}, baseConfig, { 'sticky-kit': 'sticky-kit/jquery.sticky-kit', 'backbone.marionette': 'backbone.marionette/lib/backbone.marionette', 'backbone.supermodel$': 'backbone.supermodel/build/backbone.supermodel.js', + 'blob$': 'blob/Blob.js', + 'filesaver$': 'filesaver/FileSaver.js' }, }, externals: {