diff --git a/assets/js/src/newsletter_editor/behaviors/TextEditorBehavior.js b/assets/js/src/newsletter_editor/behaviors/TextEditorBehavior.js new file mode 100644 index 0000000000..6761da0ae1 --- /dev/null +++ b/assets/js/src/newsletter_editor/behaviors/TextEditorBehavior.js @@ -0,0 +1,76 @@ +/** + * Text Editor Behavior + * + * Adds TinyMCE text editing capabilities to a view + */ +define([ + 'backbone.marionette', + 'underscore', + 'newsletter_editor/behaviors/BehaviorsLookup' + ], function(Marionette, _, BehaviorsLookup) { + + BehaviorsLookup.TextEditorBehavior = Marionette.Behavior.extend({ + defaults: { + selector: '.mailpoet_content', + toolbar1: "bold italic link unlink forecolor mailpoet_shortcodes", + toolbar2: "", + validElements: "p[class|style],span[class|style],a[href|class|title|target|style],strong[class|style],em[class|style],strike,br", + invalidElements: "script", + blockFormats: 'Paragraph=p', + plugins: "link textcolor colorpicker mailpoet_shortcodes", + configurationFilter: function(originalConfig) { return originalConfig; }, + }, + onDomRefresh: function() { + var that = this; + if (this.view.disableTextEditor === true) { + return; + } + + this.$(this.options.selector).tinymce(this.options.configurationFilter({ + inline: true, + + menubar: false, + toolbar1: this.options.toolbar1, + toolbar2: this.options.toolbar2, + + valid_elements: this.options.validElements, + invalid_elements: this.options.invalidElements, + block_formats: this.options.blockFormats, + relative_urls: false, + remove_script_host: false, + convert_urls: true, + urlconverter_callback: function(url, node, on_save, name) { + if (url.match(/\[.+\]/g)) { + // Do not convert URLs with shortcodes + return url; + } + + return this.documentBaseURI.toAbsolute( + url, + this.settings.remove_script_host + ); + }, + + plugins: this.options.plugins, + + setup: function(editor) { + editor.on('change', function(e) { + that.view.triggerMethod('text:editor:change', editor.getContent()); + }); + + editor.on('click', function(e) { + editor.focus(); + }); + + editor.on('focus', function(e) { + that.view.triggerMethod('text:editor:focus'); + }); + + editor.on('blur', function(e) { + that.view.triggerMethod('text:editor:blur'); + }); + }, + })); + } + }); +}); diff --git a/assets/js/src/newsletter_editor/blocks/footer.js b/assets/js/src/newsletter_editor/blocks/footer.js index 5a5259ac4f..e1f93f2a4b 100644 --- a/assets/js/src/newsletter_editor/blocks/footer.js +++ b/assets/js/src/newsletter_editor/blocks/footer.js @@ -42,53 +42,31 @@ define([ modelEvents: _.extend({ 'change:styles.block.backgroundColor change:styles.text.fontColor change:styles.text.fontFamily change:styles.text.fontSize change:styles.text.textAlign change:styles.link.fontColor change:styles.link.textDecoration': 'render', }, _.omit(base.BlockView.prototype.modelEvents, 'change')), + behaviors: _.extend({}, base.BlockView.prototype.behaviors, { + TextEditorBehavior: { + configurationFilter: function(originalSettings) { + return _.extend({}, originalSettings, { + mailpoet_shortcodes: App.getConfig().get('shortcodes').toJSON(), + mailpoet_shortcodes_window_title: MailPoet.I18n.t('shortcodesWindowTitle'), + }); + } + }, + }), onDragSubstituteBy: function() { return Module.FooterWidgetView; }, onRender: function() { this.toolsView = new Module.FooterBlockToolsView({ model: this.model }); this.toolsRegion.show(this.toolsView); }, - onDomRefresh: function() { - this.attachTextEditor(); + onTextEditorChange: function(newContent) { + this.model.set('text', newContent); }, - attachTextEditor: function() { - var that = this; - this.$('.mailpoet_content').tinymce({ - inline: true, - - menubar: false, - toolbar: "bold italic link unlink forecolor mailpoet_shortcodes", - - valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],strong[class|style],em[class|style],strike,br", - invalid_elements: "script", - block_formats: 'Paragraph=p', - relative_urls: false, - remove_script_host: false, - - plugins: "link textcolor colorpicker mailpoet_shortcodes", - - setup: function(editor) { - editor.on('change', function(e) { - that.model.set('text', editor.getContent()); - }); - - editor.on('click', function(e) { - editor.focus(); - }); - - editor.on('focus', function(e) { - that.disableDragging(); - that.disableShowingTools(); - }); - - editor.on('blur', function(e) { - that.enableDragging(); - that.enableShowingTools(); - }); - }, - - mailpoet_shortcodes: App.getConfig().get('shortcodes').toJSON(), - mailpoet_shortcodes_window_title: MailPoet.I18n.t('shortcodesWindowTitle'), - }); + onTextEditorFocus: function() { + this.disableDragging(); + this.disableShowingTools(); + }, + onTextEditorBlur: function() { + this.enableDragging(); + this.enableShowingTools(); }, disableDragging: function() { this.$('.mailpoet_content').addClass('mailpoet_ignore_drag'); diff --git a/assets/js/src/newsletter_editor/blocks/header.js b/assets/js/src/newsletter_editor/blocks/header.js index daa7752bce..b1d2e6c8cd 100644 --- a/assets/js/src/newsletter_editor/blocks/header.js +++ b/assets/js/src/newsletter_editor/blocks/header.js @@ -42,53 +42,31 @@ define([ modelEvents: _.extend({ 'change:styles.block.backgroundColor change:styles.text.fontColor change:styles.text.fontFamily change:styles.text.fontSize change:styles.text.textAlign change:styles.link.fontColor change:styles.link.textDecoration': 'render', }, _.omit(base.BlockView.prototype.modelEvents, 'change')), + behaviors: _.extend({}, base.BlockView.prototype.behaviors, { + TextEditorBehavior: { + configurationFilter: function(originalSettings) { + return _.extend({}, originalSettings, { + mailpoet_shortcodes: App.getConfig().get('shortcodes').toJSON(), + mailpoet_shortcodes_window_title: MailPoet.I18n.t('shortcodesWindowTitle'), + }); + } + }, + }), onDragSubstituteBy: function() { return Module.HeaderWidgetView; }, onRender: function() { this.toolsView = new Module.HeaderBlockToolsView({ model: this.model }); this.toolsRegion.show(this.toolsView); }, - onDomRefresh: function() { - this.attachTextEditor(); + onTextEditorChange: function(newContent) { + this.model.set('text', newContent); }, - attachTextEditor: function() { - var that = this; - this.$('.mailpoet_content').tinymce({ - inline: true, - - menubar: false, - toolbar: "bold italic link unlink forecolor mailpoet_shortcodes", - - valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],strong[class|style],em[class|style],strike,br", - invalid_elements: "script", - block_formats: 'Paragraph=p', - relative_urls: false, - remove_script_host: false, - - plugins: "link textcolor colorpicker mailpoet_shortcodes", - - setup: function(editor) { - editor.on('change', function(e) { - that.model.set('text', editor.getContent()); - }); - - editor.on('click', function(e) { - editor.focus(); - }); - - editor.on('focus', function(e) { - that.disableDragging(); - that.disableShowingTools(); - }); - - editor.on('blur', function(e) { - that.enableDragging(); - that.enableShowingTools(); - }); - }, - - mailpoet_shortcodes: App.getConfig().get('shortcodes').toJSON(), - mailpoet_shortcodes_window_title: MailPoet.I18n.t('shortcodesWindowTitle'), - }); + onTextEditorFocus: function() { + this.disableDragging(); + this.disableShowingTools(); + }, + onTextEditorBlur: function() { + this.enableDragging(); + this.enableShowingTools(); }, disableDragging: function() { this.$('.mailpoet_content').addClass('mailpoet_ignore_drag'); diff --git a/assets/js/src/newsletter_editor/blocks/text.js b/assets/js/src/newsletter_editor/blocks/text.js index 9b8941be7f..a5ff0df4c5 100644 --- a/assets/js/src/newsletter_editor/blocks/text.js +++ b/assets/js/src/newsletter_editor/blocks/text.js @@ -25,12 +25,30 @@ define([ className: "mailpoet_block mailpoet_text_block mailpoet_droppable_block", getTemplate: function() { return templates.textBlock; }, modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'), // Prevent rerendering on model change due to text editor redrawing + behaviors: _.extend({}, base.BlockView.prototype.behaviors, { + TextEditorBehavior: { + toolbar1: "formatselect bold italic forecolor | link unlink", + toolbar2: "alignleft aligncenter alignright alignjustify | bullist numlist blockquote | code mailpoet_shortcodes", + validElements: "p[class|style],span[class|style],a[href|class|title|target|style],h1[class|style],h2[class|style],h3[class|style],ol[class|style],ul[class|style],li[class|style],strong[class|style],em[class|style],strike,br,blockquote[class|style],table[class|style],tr[class|style],th[class|style],td[class|style]", + invalidElements: "script", + blockFormats: 'Heading 1=h1;Heading 2=h2;Heading 3=h3;Paragraph=p', + plugins: "link code textcolor colorpicker mailpoet_shortcodes", + configurationFilter: function(originalSettings) { + return _.extend({}, originalSettings, { + mailpoet_shortcodes: App.getConfig().get('shortcodes').toJSON(), + mailpoet_shortcodes_window_title: MailPoet.I18n.t('shortcodesWindowTitle'), + }); + } + }, + }), initialize: function(options) { base.BlockView.prototype.initialize.apply(this, arguments); this.renderOptions = _.defaults(options.renderOptions || {}, { disableTextEditor: false, }); + + this.disableTextEditor = this.renderOptions.disableTextEditor; }, onDragSubstituteBy: function() { return Module.TextWidgetView; }, onRender: function() { @@ -42,53 +60,18 @@ define([ }); this.toolsRegion.show(this.toolsView); }, - onDomRefresh: function() { - this.attachTextEditor(); + onTextEditorChange: function(newContent) { + this.model.set('text', newContent); }, - attachTextEditor: function() { - var that = this; - if (!this.renderOptions.disableTextEditor) { - this.$('.mailpoet_content').tinymce({ - inline: true, - - menubar: false, - toolbar1: "formatselect bold italic forecolor | link unlink", - toolbar2: "alignleft aligncenter alignright alignjustify | bullist numlist blockquote | code mailpoet_shortcodes", - - //forced_root_block: 'p', - valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],h1[class|style],h2[class|style],h3[class|style],ol[class|style],ul[class|style],li[class|style],strong[class|style],em[class|style],strike,br,blockquote[class|style],table[class|style],tr[class|style],th[class|style],td[class|style]", - invalid_elements: "script", - block_formats: 'Heading 1=h1;Heading 2=h2;Heading 3=h3;Paragraph=p', - relative_urls: false, - remove_script_host: false, - - plugins: "link code textcolor colorpicker mailpoet_shortcodes", - - setup: function(editor) { - editor.on('change', function(e) { - that.model.set('text', editor.getContent()); - }); - - editor.on('click', function(e) { - editor.focus(); - }); - - editor.on('focus', function(e) { - that.disableDragging(); - that.disableShowingTools(); - }); - - editor.on('blur', function(e) { - that.enableDragging(); - that.enableShowingTools(); - }); - }, - - mailpoet_shortcodes: App.getConfig().get('shortcodes').toJSON(), - mailpoet_shortcodes_window_title: MailPoet.I18n.t('shortcodesWindowTitle'), - }); - } + onTextEditorFocus: function() { + this.disableDragging(); + this.disableShowingTools(); }, + onTextEditorBlur: function() { + this.enableDragging(); + this.enableShowingTools(); + }, + disableDragging: function() { this.$('.mailpoet_content').addClass('mailpoet_ignore_drag'); }, diff --git a/webpack.config.js b/webpack.config.js index a45a3aec17..777c939823 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -150,6 +150,7 @@ config.push(_.extend({}, baseConfig, { 'newsletter_editor/behaviors/ResizableBehavior.js', 'newsletter_editor/behaviors/SortableBehavior.js', 'newsletter_editor/behaviors/ShowSettingsBehavior.js', + 'newsletter_editor/behaviors/TextEditorBehavior.js', 'newsletter_editor/blocks/base.js', 'newsletter_editor/blocks/container.js', 'newsletter_editor/blocks/button.js', @@ -227,6 +228,7 @@ config.push(_.extend({}, baseConfig, { 'newsletter_editor/behaviors/ResizableBehavior.js', 'newsletter_editor/behaviors/SortableBehavior.js', 'newsletter_editor/behaviors/ShowSettingsBehavior.js', + 'newsletter_editor/behaviors/TextEditorBehavior.js', 'newsletter_editor/blocks/base.js', 'newsletter_editor/blocks/container.js', 'newsletter_editor/blocks/button.js',