Wrap editor JS code in AMD modules and load them
This commit is contained in:
@ -1,142 +1,144 @@
|
|||||||
define('handlebars_helpers', ['handlebars'], function(Handlebars) {
|
define('handlebars_helpers', ['handlebars'], function(Handlebars) {
|
||||||
// Handlebars helpers
|
// Handlebars helpers
|
||||||
Handlebars.registerHelper('concat', function() {
|
Handlebars.registerHelper('concat', function() {
|
||||||
var size = (arguments.length - 1),
|
var size = (arguments.length - 1),
|
||||||
output = '';
|
output = '';
|
||||||
for(var i = 0; i < size; i++) {
|
for(var i = 0; i < size; i++) {
|
||||||
output += arguments[i];
|
output += arguments[i];
|
||||||
};
|
};
|
||||||
return output;
|
return output;
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('number_format', function(value, block) {
|
Handlebars.registerHelper('number_format', function(value, block) {
|
||||||
return Number(value).toLocaleString();
|
return Number(value).toLocaleString();
|
||||||
});
|
});
|
||||||
Handlebars.registerHelper('date_format', function(timestamp, block) {
|
Handlebars.registerHelper('date_format', function(timestamp, block) {
|
||||||
if(window.moment) {
|
if(window.moment) {
|
||||||
if(timestamp === undefined || isNaN(timestamp) || timestamp <= 0) {
|
if(timestamp === undefined || isNaN(timestamp) || timestamp <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set date format
|
// set date format
|
||||||
var f = block.hash.format || "MMM Do, YYYY";
|
var f = block.hash.format || "MMM Do, YYYY";
|
||||||
// check if we passed a timestamp
|
// check if we passed a timestamp
|
||||||
if(parseInt(timestamp, 10) == timestamp) {
|
if(parseInt(timestamp, 10) == timestamp) {
|
||||||
return moment.unix(timestamp).format(f);
|
return moment.unix(timestamp).format(f);
|
||||||
} else {
|
} else {
|
||||||
return moment.utc(timestamp).format(f);
|
return moment.utc(timestamp).format(f);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return timestamp;
|
return timestamp;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('cycle', function(value, block) {
|
Handlebars.registerHelper('cycle', function(value, block) {
|
||||||
var values = value.split(' ');
|
var values = value.split(' ');
|
||||||
return values[block.data.index % (values.length + 1)];
|
return values[block.data.index % (values.length + 1)];
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {
|
Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {
|
||||||
switch (operator) {
|
switch (operator) {
|
||||||
case '==':
|
case '==':
|
||||||
return (v1 == v2) ? options.fn(this) : options.inverse(this);
|
return (v1 == v2) ? options.fn(this) : options.inverse(this);
|
||||||
case '===':
|
case '===':
|
||||||
return (v1 === v2) ? options.fn(this) : options.inverse(this);
|
return (v1 === v2) ? options.fn(this) : options.inverse(this);
|
||||||
case '!=':
|
case '!=':
|
||||||
return (v1 != v2) ? options.fn(this) : options.inverse(this);
|
return (v1 != v2) ? options.fn(this) : options.inverse(this);
|
||||||
case '!==':
|
case '!==':
|
||||||
return (v1 !== v2) ? options.fn(this) : options.inverse(this);
|
return (v1 !== v2) ? options.fn(this) : options.inverse(this);
|
||||||
case '<':
|
case '<':
|
||||||
return (v1 < v2) ? options.fn(this) : options.inverse(this);
|
return (v1 < v2) ? options.fn(this) : options.inverse(this);
|
||||||
case '<=':
|
case '<=':
|
||||||
return (v1 <= v2) ? options.fn(this) : options.inverse(this);
|
return (v1 <= v2) ? options.fn(this) : options.inverse(this);
|
||||||
case '>':
|
case '>':
|
||||||
return (v1 > v2) ? options.fn(this) : options.inverse(this);
|
return (v1 > v2) ? options.fn(this) : options.inverse(this);
|
||||||
case '>=':
|
case '>=':
|
||||||
return (v1 >= v2) ? options.fn(this) : options.inverse(this);
|
return (v1 >= v2) ? options.fn(this) : options.inverse(this);
|
||||||
case '&&':
|
case '&&':
|
||||||
return (v1 && v2) ? options.fn(this) : options.inverse(this);
|
return (v1 && v2) ? options.fn(this) : options.inverse(this);
|
||||||
case '||':
|
case '||':
|
||||||
return (v1 || v2) ? options.fn(this) : options.inverse(this);
|
return (v1 || v2) ? options.fn(this) : options.inverse(this);
|
||||||
case 'in':
|
case 'in':
|
||||||
var values = v2.split(',');
|
var values = v2.split(',');
|
||||||
return (v2.indexOf(v1) !== -1) ? options.fn(this) : options.inverse(this);
|
return (v2.indexOf(v1) !== -1) ? options.fn(this) : options.inverse(this);
|
||||||
default:
|
default:
|
||||||
return options.inverse(this);
|
return options.inverse(this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('nl2br', function(value, block) {
|
Handlebars.registerHelper('nl2br', function(value, block) {
|
||||||
return value.gsub("\n", "<br />");
|
return value.gsub("\n", "<br />");
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('json_encode', function(value, block) {
|
Handlebars.registerHelper('json_encode', function(value, block) {
|
||||||
return JSON.stringify(value);
|
return JSON.stringify(value);
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('json_decode', function(value, block) {
|
Handlebars.registerHelper('json_decode', function(value, block) {
|
||||||
return JSON.parse(value);
|
return JSON.parse(value);
|
||||||
});
|
});
|
||||||
Handlebars.registerHelper('url', function(value, block) {
|
Handlebars.registerHelper('url', function(value, block) {
|
||||||
var url = window.location.protocol + "//" + window.location.host + window.location.pathname;
|
var url = window.location.protocol + "//" + window.location.host + window.location.pathname;
|
||||||
|
|
||||||
return url + value;
|
return url + value;
|
||||||
});
|
});
|
||||||
Handlebars.registerHelper('emailFromMailto', function(value) {
|
Handlebars.registerHelper('emailFromMailto', function(value) {
|
||||||
var mailtoMatchingRegex = /^mailto\:/i;
|
var mailtoMatchingRegex = /^mailto\:/i;
|
||||||
if (typeof value === 'string' && value.match(mailtoMatchingRegex)) {
|
if (typeof value === 'string' && value.match(mailtoMatchingRegex)) {
|
||||||
return value.replace(mailtoMatchingRegex, '');
|
return value.replace(mailtoMatchingRegex, '');
|
||||||
} else {
|
} else {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Handlebars.registerHelper('lookup', function(obj, field, options) {
|
Handlebars.registerHelper('lookup', function(obj, field, options) {
|
||||||
return obj && obj[field];
|
return obj && obj[field];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Handlebars.registerHelper('rsa_key', function(value, block) {
|
Handlebars.registerHelper('rsa_key', function(value, block) {
|
||||||
// extract all lines into an array
|
// extract all lines into an array
|
||||||
if(value === undefined) return '';
|
if(value === undefined) return '';
|
||||||
|
|
||||||
var lines = value.trim().split("\n");
|
var lines = value.trim().split("\n");
|
||||||
|
|
||||||
// remove header & footer
|
// remove header & footer
|
||||||
lines.shift();
|
lines.shift();
|
||||||
lines.pop();
|
lines.pop();
|
||||||
|
|
||||||
// return concatenated lines
|
// return concatenated lines
|
||||||
return lines.join('');
|
return lines.join('');
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('trim', function(value, block) {
|
Handlebars.registerHelper('trim', function(value, block) {
|
||||||
if(value === null || value === undefined) return '';
|
if(value === null || value === undefined) return '';
|
||||||
return value.trim();
|
return value.trim();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {{ellipsis}}
|
* {{ellipsis}}
|
||||||
* From: https://github.com/assemble/handlebars-helpers
|
* From: https://github.com/assemble/handlebars-helpers
|
||||||
* @author: Jon Schlinkert <http://github.com/jonschlinkert>
|
* @author: Jon Schlinkert <http://github.com/jonschlinkert>
|
||||||
* Truncate the input string and removes all HTML tags
|
* Truncate the input string and removes all HTML tags
|
||||||
* @param {String} str The input string.
|
* @param {String} str The input string.
|
||||||
* @param {Number} limit The number of characters to limit the string.
|
* @param {Number} limit The number of characters to limit the string.
|
||||||
* @param {String} append The string to append if charaters are omitted.
|
* @param {String} append The string to append if charaters are omitted.
|
||||||
* @return {String} The truncated string.
|
* @return {String} The truncated string.
|
||||||
*/
|
*/
|
||||||
Handlebars.registerHelper('ellipsis', function (str, limit, append) {
|
Handlebars.registerHelper('ellipsis', function (str, limit, append) {
|
||||||
if (append === undefined) {
|
if (append === undefined) {
|
||||||
append = '';
|
append = '';
|
||||||
}
|
}
|
||||||
var sanitized = str.replace(/(<([^>]+)>)/g, '');
|
var sanitized = str.replace(/(<([^>]+)>)/g, '');
|
||||||
if (sanitized.length > limit) {
|
if (sanitized.length > limit) {
|
||||||
return sanitized.substr(0, limit - append.length) + append;
|
return sanitized.substr(0, limit - append.length) + append;
|
||||||
} else {
|
} else {
|
||||||
return sanitized;
|
return sanitized;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('getNumber', function (string) {
|
Handlebars.registerHelper('getNumber', function (string) {
|
||||||
return parseInt(string, 10);
|
return parseInt(string, 10);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
window.Handlebars = Handlebars;
|
||||||
|
});
|
||||||
|
35
assets/js/src/newsletter_editor/App.js
Normal file
35
assets/js/src/newsletter_editor/App.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
define('newsletter_editor/App', [
|
||||||
|
'backbone',
|
||||||
|
'backbone.marionette',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'jquery',
|
||||||
|
'underscore',
|
||||||
|
'handlebars',
|
||||||
|
'handlebars_helpers',
|
||||||
|
], function(Backbone, Marionette, SuperModel, jQuery, _, Handlebars) {
|
||||||
|
var app = new Marionette.Application(), AppView;
|
||||||
|
|
||||||
|
// Decoupled communication between application components
|
||||||
|
app.getChannel = function(channel) {
|
||||||
|
if (channel === undefined) return app.channel;
|
||||||
|
return Radio.channel(channel);
|
||||||
|
};
|
||||||
|
|
||||||
|
AppView = Marionette.LayoutView.extend({
|
||||||
|
el: '#mailpoet_editor',
|
||||||
|
regions: {
|
||||||
|
stylesRegion: '#mailpoet_editor_styles',
|
||||||
|
contentRegion: '#mailpoet_editor_content',
|
||||||
|
sidebarRegion: '#mailpoet_editor_sidebar',
|
||||||
|
bottomRegion: '#mailpoet_editor_bottom',
|
||||||
|
headingRegion: '#mailpoet_editor_heading',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
app.on('start', function(options) {
|
||||||
|
app._appView = new AppView();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.EditorApplication = app;
|
||||||
|
return app;
|
||||||
|
});
|
@ -4,7 +4,16 @@
|
|||||||
*
|
*
|
||||||
* For more check: http://marionettejs.com/docs/marionette.behaviors.html#behaviorslookup
|
* For more check: http://marionettejs.com/docs/marionette.behaviors.html#behaviorslookup
|
||||||
*/
|
*/
|
||||||
BehaviorsLookup = {};
|
define('newsletter_editor/behaviors/behaviorsLookup', [
|
||||||
Backbone.Marionette.Behaviors.behaviorsLookup = function() {
|
'backbone.marionette',
|
||||||
|
], function(Marionette) {
|
||||||
|
|
||||||
|
var BehaviorsLookup = {};
|
||||||
|
Marionette.Behaviors.behaviorsLookup = function() {
|
||||||
return BehaviorsLookup;
|
return BehaviorsLookup;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
window.BehaviorsLookup = BehaviorsLookup;
|
||||||
|
|
||||||
|
return BehaviorsLookup;
|
||||||
|
});
|
||||||
|
@ -3,14 +3,22 @@
|
|||||||
*
|
*
|
||||||
* Adds a color picker integration with the view
|
* Adds a color picker integration with the view
|
||||||
*/
|
*/
|
||||||
BehaviorsLookup.ColorPickerBehavior = Backbone.Marionette.Behavior.extend({
|
define('newsletter_editor/behaviors/ColorPickerBehavior', [
|
||||||
|
'backbone.marionette',
|
||||||
|
'newsletter_editor/behaviors/BehaviorsLookup',
|
||||||
|
'spectrum-colorpicker',
|
||||||
|
], function(Marionette, BehaviorsLookup) {
|
||||||
|
|
||||||
|
BehaviorsLookup.ColorPickerBehavior = Marionette.Behavior.extend({
|
||||||
onRender: function() {
|
onRender: function() {
|
||||||
this.view.$('.mailpoet_color').spectrum({
|
this.view.$('.mailpoet_color').spectrum({
|
||||||
clickoutFiresChange: true,
|
clickoutFiresChange: true,
|
||||||
showInput: true,
|
showInput: true,
|
||||||
showInitial: true,
|
showInitial: true,
|
||||||
preferredFormat: "hex6",
|
preferredFormat: "hex6",
|
||||||
allowEmpty: true,
|
allowEmpty: true,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -5,415 +5,424 @@
|
|||||||
* Allows CollectionView instances that use this behavior to act as drop zones and
|
* Allows CollectionView instances that use this behavior to act as drop zones and
|
||||||
* accept droppables
|
* accept droppables
|
||||||
*/
|
*/
|
||||||
BehaviorsLookup.ContainerDropZoneBehavior = Backbone.Marionette.Behavior.extend({
|
define('newsletter_editor/behaviors/ContainerDropZoneBehavior', [
|
||||||
|
'backbone.marionette',
|
||||||
|
'underscore',
|
||||||
|
'newsletter_editor/behaviors/BehaviorsLookup',
|
||||||
|
'interact.js',
|
||||||
|
], function(Marionette, _, BehaviorsLookup, interact) {
|
||||||
|
|
||||||
|
BehaviorsLookup.ContainerDropZoneBehavior = Marionette.Behavior.extend({
|
||||||
defaults: {
|
defaults: {
|
||||||
columnLimit: 3,
|
columnLimit: 3,
|
||||||
},
|
},
|
||||||
onRender: function() {
|
onRender: function() {
|
||||||
var dragAndDropDisabled = _.isObject(this.view.options.renderOptions) && this.view.options.renderOptions.disableDragAndDrop === true;
|
var dragAndDropDisabled = _.isObject(this.view.options.renderOptions) && this.view.options.renderOptions.disableDragAndDrop === true;
|
||||||
if (!dragAndDropDisabled) {
|
if (!dragAndDropDisabled) {
|
||||||
this.addDropZone();
|
this.addDropZone();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addDropZone: function(_event) {
|
addDropZone: function(_event) {
|
||||||
var that = this,
|
var that = this,
|
||||||
view = this.view,
|
view = this.view,
|
||||||
domElement = that.$el.get(0),
|
domElement = that.$el.get(0),
|
||||||
acceptableElementSelector;
|
acceptableElementSelector;
|
||||||
|
|
||||||
// TODO: Extract this limitation code to be controlled from containers
|
// TODO: Extract this limitation code to be controlled from containers
|
||||||
if (this.view.renderOptions.depth === 0) {
|
if (this.view.renderOptions.depth === 0) {
|
||||||
// Root level accept. Allow only layouts
|
// Root level accept. Allow only layouts
|
||||||
acceptableElementSelector = '.mailpoet_droppable_block.mailpoet_droppable_layout_block';
|
acceptableElementSelector = '.mailpoet_droppable_block.mailpoet_droppable_layout_block';
|
||||||
} else if (this.view.renderOptions.depth === 2) {
|
} else if (this.view.renderOptions.depth === 2) {
|
||||||
// Column level accept. Disallow layouts, allow only content blocks
|
// Column level accept. Disallow layouts, allow only content blocks
|
||||||
acceptableElementSelector = '.mailpoet_droppable_block:not(.mailpoet_droppable_layout_block)';
|
acceptableElementSelector = '.mailpoet_droppable_block:not(.mailpoet_droppable_layout_block)';
|
||||||
} else {
|
} else {
|
||||||
// Layout section container level. Allow nothing.
|
// Layout section container level. Allow nothing.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Simplify target block identification, remove special insertion support
|
// TODO: Simplify target block identification, remove special insertion support
|
||||||
interact(domElement).dropzone({
|
interact(domElement).dropzone({
|
||||||
accept: acceptableElementSelector,
|
accept: acceptableElementSelector,
|
||||||
overlap: 'pointer', // Mouse pointer denotes location of a droppable
|
overlap: 'pointer', // Mouse pointer denotes location of a droppable
|
||||||
ondragenter: function(event) {
|
ondragenter: function(event) {
|
||||||
// 1. Visually mark block as active for dropping
|
// 1. Visually mark block as active for dropping
|
||||||
view.$el.addClass('mailpoet_drop_active');
|
view.$el.addClass('mailpoet_drop_active');
|
||||||
},
|
},
|
||||||
ondragleave: function(event) {
|
ondragleave: function(event) {
|
||||||
// 1. Remove visual markings of active dropping container
|
// 1. Remove visual markings of active dropping container
|
||||||
// 2. Remove visual markings of drop position visualization
|
// 2. Remove visual markings of drop position visualization
|
||||||
that.cleanup();
|
that.cleanup();
|
||||||
},
|
},
|
||||||
ondropmove: function(event) {
|
ondropmove: function(event) {
|
||||||
// 1. Compute actual location of the mouse within the container
|
// 1. Compute actual location of the mouse within the container
|
||||||
// 2. Check if insertion is regular (between blocks) or special (with container insertion)
|
// 2. Check if insertion is regular (between blocks) or special (with container insertion)
|
||||||
// 3a. If insertion is regular, compute position where insertion should happen
|
// 3a. If insertion is regular, compute position where insertion should happen
|
||||||
// 3b. If insertion is special, compute position (which side) and which cell the insertion belongs to
|
// 3b. If insertion is special, compute position (which side) and which cell the insertion belongs to
|
||||||
// 4. If insertion at that position is not visualized, display position visualization there, remove other visualizations from this container
|
// 4. If insertion at that position is not visualized, display position visualization there, remove other visualizations from this container
|
||||||
var dropPosition = that.getDropPosition(
|
var dropPosition = that.getDropPosition(
|
||||||
event.dragmove.pageX,
|
event.dragmove.pageX,
|
||||||
event.dragmove.pageY,
|
event.dragmove.pageY,
|
||||||
view.$el,
|
view.$el,
|
||||||
view.model.get('orientation'),
|
view.model.get('orientation'),
|
||||||
view.model.get('blocks').length
|
view.model.get('blocks').length
|
||||||
),
|
),
|
||||||
element = view.$el,
|
element = view.$el,
|
||||||
markerWidth = '',
|
markerWidth = '',
|
||||||
markerHeight = '',
|
markerHeight = '',
|
||||||
containerOffset = element.offset(),
|
containerOffset = element.offset(),
|
||||||
marker, targetModel, targetView, targetElement,
|
marker, targetModel, targetView, targetElement,
|
||||||
topOffset, leftOffset, isLastBlockInsertion,
|
topOffset, leftOffset, isLastBlockInsertion,
|
||||||
$targetBlock, margin;
|
$targetBlock, margin;
|
||||||
|
|
||||||
if (dropPosition === undefined) return;
|
if (dropPosition === undefined) return;
|
||||||
|
|
||||||
element.find('.mailpoet_drop_marker').remove();
|
element.find('.mailpoet_drop_marker').remove();
|
||||||
|
|
||||||
// Allow empty collections to handle their own drop marking
|
// Allow empty collections to handle their own drop marking
|
||||||
if (view.model.get('blocks').isEmpty()) return;
|
if (view.model.get('blocks').isEmpty()) return;
|
||||||
|
|
||||||
if (view.collection.length === 0) {
|
if (view.collection.length === 0) {
|
||||||
targetElement = element.find(view.childViewContainer);
|
targetElement = element.find(view.childViewContainer);
|
||||||
topOffset = targetElement.offset().top - element.offset().top;
|
topOffset = targetElement.offset().top - element.offset().top;
|
||||||
leftOffset = targetElement.offset().left - element.offset().left;
|
leftOffset = targetElement.offset().left - element.offset().left;
|
||||||
markerWidth = targetElement.width();
|
markerWidth = targetElement.width();
|
||||||
markerHeight = targetElement.height();
|
markerHeight = targetElement.height();
|
||||||
|
} else {
|
||||||
|
isLastBlockInsertion = view.collection.length === dropPosition.index;
|
||||||
|
targetModel = isLastBlockInsertion ? view.collection.at(dropPosition.index - 1) : view.collection.at(dropPosition.index);
|
||||||
|
|
||||||
|
targetView = view.children.findByModel(targetModel);
|
||||||
|
targetElement = targetView.$el;
|
||||||
|
|
||||||
|
topOffset = targetElement.offset().top - containerOffset.top;
|
||||||
|
leftOffset = targetElement.offset().left - containerOffset.left;
|
||||||
|
if (dropPosition.insertionType === 'normal') {
|
||||||
|
if (dropPosition.position === 'after') {
|
||||||
|
// Move the marker to the opposite side of the block
|
||||||
|
if (view.model.get('orientation') === 'vertical') {
|
||||||
|
topOffset += targetElement.outerHeight(true);
|
||||||
} else {
|
} else {
|
||||||
isLastBlockInsertion = view.collection.length === dropPosition.index;
|
leftOffset += targetElement.outerWidth();
|
||||||
targetModel = isLastBlockInsertion ? view.collection.at(dropPosition.index - 1) : view.collection.at(dropPosition.index);
|
|
||||||
|
|
||||||
targetView = view.children.findByModel(targetModel);
|
|
||||||
targetElement = targetView.$el;
|
|
||||||
|
|
||||||
topOffset = targetElement.offset().top - containerOffset.top;
|
|
||||||
leftOffset = targetElement.offset().left - containerOffset.left;
|
|
||||||
if (dropPosition.insertionType === 'normal') {
|
|
||||||
if (dropPosition.position === 'after') {
|
|
||||||
// Move the marker to the opposite side of the block
|
|
||||||
if (view.model.get('orientation') === 'vertical') {
|
|
||||||
topOffset += targetElement.outerHeight(true);
|
|
||||||
} else {
|
|
||||||
leftOffset += targetElement.outerWidth();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (view.model.get('orientation') === 'vertical') {
|
|
||||||
markerWidth = targetElement.outerWidth();
|
|
||||||
} else {
|
|
||||||
markerHeight = targetElement.outerHeight();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (dropPosition.position === 'after') {
|
|
||||||
// Move the marker to the opposite side of the block
|
|
||||||
if (view.model.get('orientation') === 'vertical') {
|
|
||||||
leftOffset += targetElement.outerWidth();
|
|
||||||
} else {
|
|
||||||
topOffset += targetElement.outerHeight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (view.model.get('orientation') === 'vertical') {
|
|
||||||
markerHeight = targetElement.outerHeight(true);
|
|
||||||
} else {
|
|
||||||
markerWidth = targetElement.outerWidth(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
marker = jQuery('<div class="mailpoet_drop_marker"></div>');
|
if (view.model.get('orientation') === 'vertical') {
|
||||||
// Add apropriate CSS classes for position refinement with CSS
|
markerWidth = targetElement.outerWidth();
|
||||||
if (dropPosition.index === 0) {
|
} else {
|
||||||
marker.addClass('mailpoet_drop_marker_first');
|
markerHeight = targetElement.outerHeight();
|
||||||
}
|
}
|
||||||
if (view.collection.length - 1 === dropPosition.index) {
|
} else {
|
||||||
marker.addClass('mailpoet_drop_marker_last');
|
if (dropPosition.position === 'after') {
|
||||||
}
|
// Move the marker to the opposite side of the block
|
||||||
if (dropPosition.index > 0 && view.collection.length - 1 > dropPosition.index) {
|
if (view.model.get('orientation') === 'vertical') {
|
||||||
marker.addClass('mailpoet_drop_marker_middle');
|
leftOffset += targetElement.outerWidth();
|
||||||
}
|
|
||||||
marker.addClass('mailpoet_drop_marker_' + dropPosition.position);
|
|
||||||
|
|
||||||
// Compute margin (optional for each block) that needs to be
|
|
||||||
// compensated for to position marker right in the middle of two
|
|
||||||
// blocks
|
|
||||||
if (dropPosition.position === 'before') {
|
|
||||||
$targetBlock = view.children.findByModel(view.collection.at(dropPosition.index-1)).$el;
|
|
||||||
} else {
|
} else {
|
||||||
$targetBlock = view.children.findByModel(view.collection.at(dropPosition.index)).$el;
|
topOffset += targetElement.outerHeight();
|
||||||
}
|
}
|
||||||
margin = $targetBlock.outerHeight(true) - $targetBlock.outerHeight();
|
}
|
||||||
|
|
||||||
marker.css('top', topOffset - (margin / 2));
|
if (view.model.get('orientation') === 'vertical') {
|
||||||
marker.css('left', leftOffset);
|
markerHeight = targetElement.outerHeight(true);
|
||||||
marker.css('width', markerWidth);
|
} else {
|
||||||
marker.css('height', markerHeight);
|
markerWidth = targetElement.outerWidth(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
element.append(marker);
|
marker = jQuery('<div class="mailpoet_drop_marker"></div>');
|
||||||
},
|
// Add apropriate CSS classes for position refinement with CSS
|
||||||
ondrop: function(event) {
|
if (dropPosition.index === 0) {
|
||||||
// 1. Compute actual location of the mouse
|
marker.addClass('mailpoet_drop_marker_first');
|
||||||
// 2. Check if insertion is regular (between blocks) or special (with container insertion)
|
}
|
||||||
// 3a. If insertion is regular
|
if (view.collection.length - 1 === dropPosition.index) {
|
||||||
// 3a1. compute position where insertion should happen
|
marker.addClass('mailpoet_drop_marker_last');
|
||||||
// 3a2. insert the drop model there
|
}
|
||||||
// 3b. If insertion is special
|
if (dropPosition.index > 0 && view.collection.length - 1 > dropPosition.index) {
|
||||||
// 3b1. compute position (which side) and which cell the insertion belongs to
|
marker.addClass('mailpoet_drop_marker_middle');
|
||||||
// 3b2. remove element at that position from the collection
|
}
|
||||||
// 3b3. create a new collection, insert the removed element to it
|
marker.addClass('mailpoet_drop_marker_' + dropPosition.position);
|
||||||
// 3b4. insert the droppable model at the start or end of the new collection, depending on 3b1. position
|
|
||||||
// 3b5. insert the new collection into the old collection to cell from 3b1.
|
|
||||||
// 4. Perform cleanup actions
|
|
||||||
|
|
||||||
var dropPosition = that.getDropPosition(
|
// Compute margin (optional for each block) that needs to be
|
||||||
event.dragEvent.pageX,
|
// compensated for to position marker right in the middle of two
|
||||||
event.dragEvent.pageY,
|
// blocks
|
||||||
view.$el,
|
if (dropPosition.position === 'before') {
|
||||||
view.model.get('orientation'),
|
$targetBlock = view.children.findByModel(view.collection.at(dropPosition.index-1)).$el;
|
||||||
view.model.get('blocks').length
|
} else {
|
||||||
),
|
$targetBlock = view.children.findByModel(view.collection.at(dropPosition.index)).$el;
|
||||||
droppableModel = event.draggable.getDropModel(),
|
}
|
||||||
droppedView, droppedModel, index, tempCollection, tempCollection2;
|
margin = $targetBlock.outerHeight(true) - $targetBlock.outerHeight();
|
||||||
|
|
||||||
if (dropPosition === undefined) return;
|
marker.css('top', topOffset - (margin / 2));
|
||||||
|
marker.css('left', leftOffset);
|
||||||
|
marker.css('width', markerWidth);
|
||||||
|
marker.css('height', markerHeight);
|
||||||
|
|
||||||
if (dropPosition.insertionType === 'normal') {
|
element.append(marker);
|
||||||
// Normal insertion of dropModel into existing collection
|
},
|
||||||
index = (dropPosition.position === 'after') ? dropPosition.index + 1 : dropPosition.index;
|
ondrop: function(event) {
|
||||||
|
// 1. Compute actual location of the mouse
|
||||||
|
// 2. Check if insertion is regular (between blocks) or special (with container insertion)
|
||||||
|
// 3a. If insertion is regular
|
||||||
|
// 3a1. compute position where insertion should happen
|
||||||
|
// 3a2. insert the drop model there
|
||||||
|
// 3b. If insertion is special
|
||||||
|
// 3b1. compute position (which side) and which cell the insertion belongs to
|
||||||
|
// 3b2. remove element at that position from the collection
|
||||||
|
// 3b3. create a new collection, insert the removed element to it
|
||||||
|
// 3b4. insert the droppable model at the start or end of the new collection, depending on 3b1. position
|
||||||
|
// 3b5. insert the new collection into the old collection to cell from 3b1.
|
||||||
|
// 4. Perform cleanup actions
|
||||||
|
|
||||||
if (view.model.get('orientation') === 'horizontal' && droppableModel.get('type') !== 'container') {
|
var dropPosition = that.getDropPosition(
|
||||||
// Regular blocks always need to be inserted into columns - vertical containers
|
event.dragEvent.pageX,
|
||||||
tempCollection = new (EditorApplication.getBlockTypeModel('container'))({
|
event.dragEvent.pageY,
|
||||||
orientation: 'vertical',
|
view.$el,
|
||||||
});
|
view.model.get('orientation'),
|
||||||
tempCollection.get('blocks').add(droppableModel);
|
view.model.get('blocks').length
|
||||||
view.collection.add(tempCollection, {at: index});
|
),
|
||||||
} else {
|
droppableModel = event.draggable.getDropModel(),
|
||||||
view.collection.add(droppableModel, {at: index});
|
droppedView, droppedModel, index, tempCollection, tempCollection2;
|
||||||
}
|
|
||||||
|
|
||||||
droppedView = view.children.findByModel(droppableModel);
|
if (dropPosition === undefined) return;
|
||||||
} else {
|
|
||||||
// Special insertion by replacing target block with collection
|
|
||||||
// and inserting dropModel into that
|
|
||||||
var tempModel = view.collection.at(dropPosition.index);
|
|
||||||
|
|
||||||
tempCollection = new (EditorApplication.getBlockTypeModel('container'))({
|
if (dropPosition.insertionType === 'normal') {
|
||||||
orientation: (view.model.get('orientation') === 'vertical') ? 'horizontal' : 'vertical',
|
// Normal insertion of dropModel into existing collection
|
||||||
});
|
index = (dropPosition.position === 'after') ? dropPosition.index + 1 : dropPosition.index;
|
||||||
|
|
||||||
view.collection.remove(tempModel);
|
if (view.model.get('orientation') === 'horizontal' && droppableModel.get('type') !== 'container') {
|
||||||
|
// Regular blocks always need to be inserted into columns - vertical containers
|
||||||
|
tempCollection = new (EditorApplication.getBlockTypeModel('container'))({
|
||||||
|
orientation: 'vertical',
|
||||||
|
});
|
||||||
|
tempCollection.get('blocks').add(droppableModel);
|
||||||
|
view.collection.add(tempCollection, {at: index});
|
||||||
|
} else {
|
||||||
|
view.collection.add(droppableModel, {at: index});
|
||||||
|
}
|
||||||
|
|
||||||
if (tempCollection.get('orientation') === 'horizontal') {
|
droppedView = view.children.findByModel(droppableModel);
|
||||||
if (dropPosition.position === 'before') {
|
} else {
|
||||||
tempCollection2 = new (EditorApplication.getBlockTypeModel('container'))({
|
// Special insertion by replacing target block with collection
|
||||||
orientation: 'vertical',
|
// and inserting dropModel into that
|
||||||
});
|
var tempModel = view.collection.at(dropPosition.index);
|
||||||
tempCollection2.get('blocks').add(droppableModel);
|
|
||||||
tempCollection.get('blocks').add(tempCollection2);
|
|
||||||
}
|
|
||||||
tempCollection2 = new (EditorApplication.getBlockTypeModel('container'))({
|
|
||||||
orientation: 'vertical',
|
|
||||||
});
|
|
||||||
tempCollection2.get('blocks').add(tempModel);
|
|
||||||
tempCollection.get('blocks').add(tempCollection2);
|
|
||||||
if (dropPosition.position === 'after') {
|
|
||||||
tempCollection2 = new (EditorApplication.getBlockTypeModel('container'))({
|
|
||||||
orientation: 'vertical',
|
|
||||||
});
|
|
||||||
tempCollection2.get('blocks').add(droppableModel);
|
|
||||||
tempCollection.get('blocks').add(tempCollection2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (dropPosition.position === 'before') {
|
|
||||||
tempCollection.get('blocks').add(droppableModel);
|
|
||||||
}
|
|
||||||
tempCollection.get('blocks').add(tempModel);
|
|
||||||
if (dropPosition.position === 'after') {
|
|
||||||
tempCollection.get('blocks').add(droppableModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
view.collection.add(tempCollection, {at: dropPosition.index});
|
|
||||||
|
|
||||||
// Call post add actions
|
tempCollection = new (EditorApplication.getBlockTypeModel('container'))({
|
||||||
droppedView = view.children.findByModel(tempCollection).children.findByModel(droppableModel);
|
orientation: (view.model.get('orientation') === 'vertical') ? 'horizontal' : 'vertical',
|
||||||
}
|
|
||||||
|
|
||||||
// Call post add actions
|
|
||||||
event.draggable.onDrop({
|
|
||||||
dropBehavior: that,
|
|
||||||
droppedModel: droppableModel,
|
|
||||||
droppedView: droppedView,
|
|
||||||
});
|
|
||||||
|
|
||||||
that.cleanup();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
cleanup: function() {
|
|
||||||
// 1. Remove visual markings of active dropping container
|
|
||||||
this.view.$el.removeClass('mailpoet_drop_active');
|
|
||||||
|
|
||||||
// 2. Remove visual markings of drop position visualization
|
|
||||||
this.view.$('.mailpoet_drop_marker').remove();
|
|
||||||
},
|
|
||||||
getDropPosition: function(eventX, eventY, unsafe) {
|
|
||||||
var SPECIAL_AREA_INSERTION_WIDTH = 0.00, // Disable special insertion. Default: 0.3
|
|
||||||
|
|
||||||
element = this.view.$el,
|
|
||||||
orientation = this.view.model.get('orientation'),
|
|
||||||
|
|
||||||
elementOffset = element.offset(),
|
|
||||||
elementPageX = elementOffset.left,
|
|
||||||
elementPageY = elementOffset.top,
|
|
||||||
elementWidth = element.outerWidth(true),
|
|
||||||
elementHeight = element.outerHeight(true),
|
|
||||||
|
|
||||||
relativeX = eventX - elementPageX,
|
|
||||||
relativeY = eventY - elementPageY,
|
|
||||||
|
|
||||||
relativeOffset, elementLength,
|
|
||||||
|
|
||||||
canAcceptNormalInsertion = this._canAcceptNormalInsertion(),
|
|
||||||
canAcceptSpecialInsertion = this._canAcceptSpecialInsertion(),
|
|
||||||
|
|
||||||
insertionType, index, position, indexAndPosition;
|
|
||||||
|
|
||||||
unsafe = !!unsafe;
|
|
||||||
|
|
||||||
if (this.view.collection.length === 0) {
|
|
||||||
return {
|
|
||||||
insertionType: 'normal',
|
|
||||||
index: 0,
|
|
||||||
position: 'inside',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (orientation === 'vertical') {
|
|
||||||
relativeOffset = relativeX;
|
|
||||||
elementLength = elementWidth;
|
|
||||||
} else {
|
|
||||||
relativeOffset = relativeY;
|
|
||||||
elementLength = elementHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (canAcceptSpecialInsertion && !canAcceptNormalInsertion) {
|
|
||||||
// If normal insertion is not available, dedicate whole element area
|
|
||||||
// to special insertion
|
|
||||||
SPECIAL_AREA_INSERTION_WIDTH = 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (relativeOffset <= elementLength * SPECIAL_AREA_INSERTION_WIDTH && (unsafe || canAcceptSpecialInsertion)) {
|
|
||||||
insertionType = 'special';
|
|
||||||
position = 'before';
|
|
||||||
index = this._computeSpecialIndex(eventX, eventY);
|
|
||||||
} else if (relativeOffset > elementLength * (1 - SPECIAL_AREA_INSERTION_WIDTH) && (unsafe || canAcceptSpecialInsertion)) {
|
|
||||||
insertionType = 'special';
|
|
||||||
position = 'after';
|
|
||||||
index = this._computeSpecialIndex(eventX, eventY);
|
|
||||||
} else {
|
|
||||||
indexAndPosition = this._computeNormalIndex(eventX, eventY);
|
|
||||||
insertionType = 'normal';
|
|
||||||
position = indexAndPosition.position;
|
|
||||||
index = indexAndPosition.index;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!unsafe && orientation === 'vertical' && insertionType === 'special' && this.view.collection.at(index).get('orientation') === 'horizontal') {
|
|
||||||
// Prevent placing horizontal container in another horizontal container,
|
|
||||||
// which would allow breaking the column limit.
|
|
||||||
// Switch that to normal insertion
|
|
||||||
indexAndPosition = this._computeNormalIndex(eventX, eventY);
|
|
||||||
insertionType = 'normal';
|
|
||||||
position = indexAndPosition.position;
|
|
||||||
index = indexAndPosition.index;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (orientation === 'horizontal' && insertionType === 'special') {
|
|
||||||
// Disable special insertion for horizontal containers
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
insertionType: insertionType, // 'normal'|'special'
|
|
||||||
index: index,
|
|
||||||
position: position, // 'inside'|'before'|'after'
|
|
||||||
};
|
|
||||||
},
|
|
||||||
_computeNormalIndex: function(eventX, eventY) {
|
|
||||||
// Normal insertion inserts dropModel before target element if
|
|
||||||
// event happens on the first half of the element and after the
|
|
||||||
// target element if event happens on the second half of the element.
|
|
||||||
// Halves depend on orientation.
|
|
||||||
|
|
||||||
var index = this._computeCellIndex(eventX, eventY),
|
|
||||||
// TODO: Handle case when there are no children, container is empty
|
|
||||||
targetView = this.view.children.findByModel(this.view.collection.at(index)),
|
|
||||||
orientation = this.view.model.get('orientation'),
|
|
||||||
element = targetView.$el,
|
|
||||||
eventOffset, closeOffset, elementDimension;
|
|
||||||
|
|
||||||
if (orientation === 'vertical') {
|
|
||||||
eventOffset = eventY;
|
|
||||||
closeOffset = element.offset().top;
|
|
||||||
elementDimension = element.outerHeight(true);
|
|
||||||
} else {
|
|
||||||
eventOffset = eventX;
|
|
||||||
closeOffset = element.offset().left;
|
|
||||||
elementDimension = element.outerWidth(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eventOffset <= closeOffset + elementDimension / 2) {
|
|
||||||
// First half of the element
|
|
||||||
return {
|
|
||||||
index: index,
|
|
||||||
position: 'before',
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// Second half of the element
|
|
||||||
return {
|
|
||||||
index: index,
|
|
||||||
position: 'after',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_computeSpecialIndex: function(eventX, eventY) {
|
|
||||||
return this._computeCellIndex(eventX, eventY);
|
|
||||||
},
|
|
||||||
_computeCellIndex: function(eventX, eventY) {
|
|
||||||
var orientation = this.view.model.get('orientation'),
|
|
||||||
eventOffset = (orientation === 'vertical') ? eventY : eventX,
|
|
||||||
resultView = this.view.children.find(function(view) {
|
|
||||||
var element = view.$el,
|
|
||||||
closeOffset, farOffset;
|
|
||||||
|
|
||||||
if (orientation === 'vertical') {
|
|
||||||
closeOffset = element.offset().top;
|
|
||||||
farOffset = element.outerHeight(true);
|
|
||||||
} else {
|
|
||||||
closeOffset = element.offset().left;
|
|
||||||
farOffset = element.outerWidth(true);
|
|
||||||
}
|
|
||||||
farOffset += closeOffset;
|
|
||||||
|
|
||||||
return closeOffset <= eventOffset && eventOffset <= farOffset;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var index = (typeof resultView === 'object') ? resultView._index : 0;
|
view.collection.remove(tempModel);
|
||||||
|
|
||||||
return index;
|
if (tempCollection.get('orientation') === 'horizontal') {
|
||||||
|
if (dropPosition.position === 'before') {
|
||||||
|
tempCollection2 = new (EditorApplication.getBlockTypeModel('container'))({
|
||||||
|
orientation: 'vertical',
|
||||||
|
});
|
||||||
|
tempCollection2.get('blocks').add(droppableModel);
|
||||||
|
tempCollection.get('blocks').add(tempCollection2);
|
||||||
|
}
|
||||||
|
tempCollection2 = new (EditorApplication.getBlockTypeModel('container'))({
|
||||||
|
orientation: 'vertical',
|
||||||
|
});
|
||||||
|
tempCollection2.get('blocks').add(tempModel);
|
||||||
|
tempCollection.get('blocks').add(tempCollection2);
|
||||||
|
if (dropPosition.position === 'after') {
|
||||||
|
tempCollection2 = new (EditorApplication.getBlockTypeModel('container'))({
|
||||||
|
orientation: 'vertical',
|
||||||
|
});
|
||||||
|
tempCollection2.get('blocks').add(droppableModel);
|
||||||
|
tempCollection.get('blocks').add(tempCollection2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (dropPosition.position === 'before') {
|
||||||
|
tempCollection.get('blocks').add(droppableModel);
|
||||||
|
}
|
||||||
|
tempCollection.get('blocks').add(tempModel);
|
||||||
|
if (dropPosition.position === 'after') {
|
||||||
|
tempCollection.get('blocks').add(droppableModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
view.collection.add(tempCollection, {at: dropPosition.index});
|
||||||
|
|
||||||
|
// Call post add actions
|
||||||
|
droppedView = view.children.findByModel(tempCollection).children.findByModel(droppableModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call post add actions
|
||||||
|
event.draggable.onDrop({
|
||||||
|
dropBehavior: that,
|
||||||
|
droppedModel: droppableModel,
|
||||||
|
droppedView: droppedView,
|
||||||
|
});
|
||||||
|
|
||||||
|
that.cleanup();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
cleanup: function() {
|
||||||
|
// 1. Remove visual markings of active dropping container
|
||||||
|
this.view.$el.removeClass('mailpoet_drop_active');
|
||||||
|
|
||||||
|
// 2. Remove visual markings of drop position visualization
|
||||||
|
this.view.$('.mailpoet_drop_marker').remove();
|
||||||
|
},
|
||||||
|
getDropPosition: function(eventX, eventY, unsafe) {
|
||||||
|
var SPECIAL_AREA_INSERTION_WIDTH = 0.00, // Disable special insertion. Default: 0.3
|
||||||
|
|
||||||
|
element = this.view.$el,
|
||||||
|
orientation = this.view.model.get('orientation'),
|
||||||
|
|
||||||
|
elementOffset = element.offset(),
|
||||||
|
elementPageX = elementOffset.left,
|
||||||
|
elementPageY = elementOffset.top,
|
||||||
|
elementWidth = element.outerWidth(true),
|
||||||
|
elementHeight = element.outerHeight(true),
|
||||||
|
|
||||||
|
relativeX = eventX - elementPageX,
|
||||||
|
relativeY = eventY - elementPageY,
|
||||||
|
|
||||||
|
relativeOffset, elementLength,
|
||||||
|
|
||||||
|
canAcceptNormalInsertion = this._canAcceptNormalInsertion(),
|
||||||
|
canAcceptSpecialInsertion = this._canAcceptSpecialInsertion(),
|
||||||
|
|
||||||
|
insertionType, index, position, indexAndPosition;
|
||||||
|
|
||||||
|
unsafe = !!unsafe;
|
||||||
|
|
||||||
|
if (this.view.collection.length === 0) {
|
||||||
|
return {
|
||||||
|
insertionType: 'normal',
|
||||||
|
index: 0,
|
||||||
|
position: 'inside',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orientation === 'vertical') {
|
||||||
|
relativeOffset = relativeX;
|
||||||
|
elementLength = elementWidth;
|
||||||
|
} else {
|
||||||
|
relativeOffset = relativeY;
|
||||||
|
elementLength = elementHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canAcceptSpecialInsertion && !canAcceptNormalInsertion) {
|
||||||
|
// If normal insertion is not available, dedicate whole element area
|
||||||
|
// to special insertion
|
||||||
|
SPECIAL_AREA_INSERTION_WIDTH = 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (relativeOffset <= elementLength * SPECIAL_AREA_INSERTION_WIDTH && (unsafe || canAcceptSpecialInsertion)) {
|
||||||
|
insertionType = 'special';
|
||||||
|
position = 'before';
|
||||||
|
index = this._computeSpecialIndex(eventX, eventY);
|
||||||
|
} else if (relativeOffset > elementLength * (1 - SPECIAL_AREA_INSERTION_WIDTH) && (unsafe || canAcceptSpecialInsertion)) {
|
||||||
|
insertionType = 'special';
|
||||||
|
position = 'after';
|
||||||
|
index = this._computeSpecialIndex(eventX, eventY);
|
||||||
|
} else {
|
||||||
|
indexAndPosition = this._computeNormalIndex(eventX, eventY);
|
||||||
|
insertionType = 'normal';
|
||||||
|
position = indexAndPosition.position;
|
||||||
|
index = indexAndPosition.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!unsafe && orientation === 'vertical' && insertionType === 'special' && this.view.collection.at(index).get('orientation') === 'horizontal') {
|
||||||
|
// Prevent placing horizontal container in another horizontal container,
|
||||||
|
// which would allow breaking the column limit.
|
||||||
|
// Switch that to normal insertion
|
||||||
|
indexAndPosition = this._computeNormalIndex(eventX, eventY);
|
||||||
|
insertionType = 'normal';
|
||||||
|
position = indexAndPosition.position;
|
||||||
|
index = indexAndPosition.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orientation === 'horizontal' && insertionType === 'special') {
|
||||||
|
// Disable special insertion for horizontal containers
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
insertionType: insertionType, // 'normal'|'special'
|
||||||
|
index: index,
|
||||||
|
position: position, // 'inside'|'before'|'after'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
_computeNormalIndex: function(eventX, eventY) {
|
||||||
|
// Normal insertion inserts dropModel before target element if
|
||||||
|
// event happens on the first half of the element and after the
|
||||||
|
// target element if event happens on the second half of the element.
|
||||||
|
// Halves depend on orientation.
|
||||||
|
|
||||||
|
var index = this._computeCellIndex(eventX, eventY),
|
||||||
|
// TODO: Handle case when there are no children, container is empty
|
||||||
|
targetView = this.view.children.findByModel(this.view.collection.at(index)),
|
||||||
|
orientation = this.view.model.get('orientation'),
|
||||||
|
element = targetView.$el,
|
||||||
|
eventOffset, closeOffset, elementDimension;
|
||||||
|
|
||||||
|
if (orientation === 'vertical') {
|
||||||
|
eventOffset = eventY;
|
||||||
|
closeOffset = element.offset().top;
|
||||||
|
elementDimension = element.outerHeight(true);
|
||||||
|
} else {
|
||||||
|
eventOffset = eventX;
|
||||||
|
closeOffset = element.offset().left;
|
||||||
|
elementDimension = element.outerWidth(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eventOffset <= closeOffset + elementDimension / 2) {
|
||||||
|
// First half of the element
|
||||||
|
return {
|
||||||
|
index: index,
|
||||||
|
position: 'before',
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// Second half of the element
|
||||||
|
return {
|
||||||
|
index: index,
|
||||||
|
position: 'after',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_computeSpecialIndex: function(eventX, eventY) {
|
||||||
|
return this._computeCellIndex(eventX, eventY);
|
||||||
|
},
|
||||||
|
_computeCellIndex: function(eventX, eventY) {
|
||||||
|
var orientation = this.view.model.get('orientation'),
|
||||||
|
eventOffset = (orientation === 'vertical') ? eventY : eventX,
|
||||||
|
resultView = this.view.children.find(function(view) {
|
||||||
|
var element = view.$el,
|
||||||
|
closeOffset, farOffset;
|
||||||
|
|
||||||
|
if (orientation === 'vertical') {
|
||||||
|
closeOffset = element.offset().top;
|
||||||
|
farOffset = element.outerHeight(true);
|
||||||
|
} else {
|
||||||
|
closeOffset = element.offset().left;
|
||||||
|
farOffset = element.outerWidth(true);
|
||||||
|
}
|
||||||
|
farOffset += closeOffset;
|
||||||
|
|
||||||
|
return closeOffset <= eventOffset && eventOffset <= farOffset;
|
||||||
|
});
|
||||||
|
|
||||||
|
var index = (typeof resultView === 'object') ? resultView._index : 0;
|
||||||
|
|
||||||
|
return index;
|
||||||
},
|
},
|
||||||
_canAcceptNormalInsertion: function() {
|
_canAcceptNormalInsertion: function() {
|
||||||
var orientation = this.view.model.get('orientation'),
|
var orientation = this.view.model.get('orientation'),
|
||||||
depth = this.view.renderOptions.depth,
|
depth = this.view.renderOptions.depth,
|
||||||
childCount = this.view.children.length;
|
childCount = this.view.children.length;
|
||||||
// Note that depth is zero indexed. Root container has depth=0
|
// Note that depth is zero indexed. Root container has depth=0
|
||||||
return orientation === 'vertical' || (orientation === 'horizontal' && depth === 1 && childCount < this.options.columnLimit);
|
return orientation === 'vertical' || (orientation === 'horizontal' && depth === 1 && childCount < this.options.columnLimit);
|
||||||
},
|
},
|
||||||
_canAcceptSpecialInsertion: function() {
|
_canAcceptSpecialInsertion: function() {
|
||||||
var orientation = this.view.model.get('orientation'),
|
var orientation = this.view.model.get('orientation'),
|
||||||
depth = this.view.renderOptions.depth,
|
depth = this.view.renderOptions.depth,
|
||||||
childCount = this.view.children.length;
|
childCount = this.view.children.length;
|
||||||
return depth === 0 || (depth === 1 && orientation === 'horizontal' && childCount <= this.options.columnLimit);
|
return depth === 0 || (depth === 1 && orientation === 'horizontal' && childCount <= this.options.columnLimit);
|
||||||
},
|
},
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -4,121 +4,129 @@
|
|||||||
* Allows View instances to be draggable.
|
* Allows View instances to be draggable.
|
||||||
* Part of the drag&drop behavior.
|
* Part of the drag&drop behavior.
|
||||||
*/
|
*/
|
||||||
BehaviorsLookup.DraggableBehavior = Backbone.Marionette.Behavior.extend({
|
define('newsletter_editor/behaviors/DraggableBehavior', [
|
||||||
defaults: {
|
'backbone.marionette',
|
||||||
cloneOriginal: false,
|
'newsletter_editor/behaviors/BehaviorsLookup',
|
||||||
hideOriginal: false,
|
'interact.js',
|
||||||
ignoreSelector: '.mailpoet_ignore_drag, .mailpoet_ignore_drag *',
|
], function(Marionette, BehaviorsLookup, interact) {
|
||||||
onDragSubstituteBy: undefined,
|
|
||||||
/**
|
|
||||||
* Constructs a model that will be passed to the receiver on drop
|
|
||||||
*
|
|
||||||
* @return Backbone.Model A model that will be passed to the receiver
|
|
||||||
*/
|
|
||||||
getDropModel: function() {
|
|
||||||
throw "Missing 'drop' function for DraggableBehavior";
|
|
||||||
},
|
|
||||||
|
|
||||||
onDrop: function(model, view) {},
|
BehaviorsLookup.DraggableBehavior = Marionette.Behavior.extend({
|
||||||
testAttachToInstance: function(model, view) { return true; },
|
defaults: {
|
||||||
},
|
cloneOriginal: false,
|
||||||
onRender: function() {
|
hideOriginal: false,
|
||||||
var that = this,
|
ignoreSelector: '.mailpoet_ignore_drag, .mailpoet_ignore_drag *',
|
||||||
interactable;
|
onDragSubstituteBy: undefined,
|
||||||
|
/**
|
||||||
|
* Constructs a model that will be passed to the receiver on drop
|
||||||
|
*
|
||||||
|
* @return Backbone.Model A model that will be passed to the receiver
|
||||||
|
*/
|
||||||
|
getDropModel: function() {
|
||||||
|
throw "Missing 'drop' function for DraggableBehavior";
|
||||||
|
},
|
||||||
|
|
||||||
// Give instances more control over whether Draggable should be applied
|
onDrop: function(model, view) {},
|
||||||
if (!this.options.testAttachToInstance(this.view.model, this.view)) return;
|
testAttachToInstance: function(model, view) { return true; },
|
||||||
|
},
|
||||||
|
onRender: function() {
|
||||||
|
var that = this,
|
||||||
|
interactable;
|
||||||
|
|
||||||
interactable = interact(this.$el.get(0), {
|
// Give instances more control over whether Draggable should be applied
|
||||||
ignoreFrom: this.options.ignoreSelector,
|
if (!this.options.testAttachToInstance(this.view.model, this.view)) return;
|
||||||
}).draggable({
|
|
||||||
// allow dragging of multple elements at the same time
|
|
||||||
max: Infinity,
|
|
||||||
|
|
||||||
// Scroll when dragging near edges of a window
|
interactable = interact(this.$el.get(0), {
|
||||||
autoScroll: true,
|
ignoreFrom: this.options.ignoreSelector,
|
||||||
|
}).draggable({
|
||||||
|
// allow dragging of multple elements at the same time
|
||||||
|
max: Infinity,
|
||||||
|
|
||||||
onstart: function(event) {
|
// Scroll when dragging near edges of a window
|
||||||
console.log('Drag start', event, this);
|
autoScroll: true,
|
||||||
|
|
||||||
if (that.options.cloneOriginal === true) {
|
onstart: function(event) {
|
||||||
// Use substitution instead of a clone
|
console.log('Drag start', event, this);
|
||||||
var tempClone = (_.isFunction(that.options.onDragSubstituteBy)) ? that.options.onDragSubstituteBy(that) : undefined,
|
|
||||||
// Or use a clone
|
|
||||||
clone = tempClone ? tempClone : event.target.cloneNode(true),
|
|
||||||
|
|
||||||
$original = jQuery(event.target),
|
if (that.options.cloneOriginal === true) {
|
||||||
$clone = jQuery(clone),
|
// Use substitution instead of a clone
|
||||||
centerXOffset, centerYOffset, parentOffset;
|
var tempClone = (_.isFunction(that.options.onDragSubstituteBy)) ? that.options.onDragSubstituteBy(that) : undefined,
|
||||||
|
// Or use a clone
|
||||||
|
clone = tempClone ? tempClone : event.target.cloneNode(true),
|
||||||
|
|
||||||
$clone.addClass('mailpoet_droppable_active');
|
$original = jQuery(event.target),
|
||||||
$clone.css('position', 'absolute');
|
$clone = jQuery(clone),
|
||||||
$clone.css('top', 0);
|
centerXOffset, centerYOffset, parentOffset;
|
||||||
$clone.css('left', 0);
|
|
||||||
document.body.appendChild(clone);
|
|
||||||
|
|
||||||
// Position the clone over the target element with a slight
|
$clone.addClass('mailpoet_droppable_active');
|
||||||
// offset to center the clone under the mouse cursor.
|
$clone.css('position', 'absolute');
|
||||||
// Accurate dimensions can only be taken after insertion to document
|
$clone.css('top', 0);
|
||||||
centerXOffset = $clone.width() / 2;
|
$clone.css('left', 0);
|
||||||
centerYOffset = $clone.height() / 2;
|
document.body.appendChild(clone);
|
||||||
$clone.css('top', event.pageY - centerYOffset);
|
|
||||||
$clone.css('left', event.pageX - centerXOffset);
|
|
||||||
|
|
||||||
event.interaction.element = clone;
|
// Position the clone over the target element with a slight
|
||||||
|
// offset to center the clone under the mouse cursor.
|
||||||
|
// Accurate dimensions can only be taken after insertion to document
|
||||||
|
centerXOffset = $clone.width() / 2;
|
||||||
|
centerYOffset = $clone.height() / 2;
|
||||||
|
$clone.css('top', event.pageY - centerYOffset);
|
||||||
|
$clone.css('left', event.pageX - centerXOffset);
|
||||||
|
|
||||||
|
event.interaction.element = clone;
|
||||||
|
|
||||||
|
|
||||||
if (that.options.hideOriginal === true) {
|
if (that.options.hideOriginal === true) {
|
||||||
that.view.$el.addClass('mailpoet_hidden');
|
that.view.$el.addClass('mailpoet_hidden');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
// call this function on every dragmove event
|
// call this function on every dragmove event
|
||||||
onmove: function (event) {
|
onmove: function (event) {
|
||||||
var target = event.target,
|
var target = event.target,
|
||||||
// keep the dragged position in the data-x/data-y attributes
|
// keep the dragged position in the data-x/data-y attributes
|
||||||
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
|
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
|
||||||
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
|
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
|
||||||
|
|
||||||
// translate the element
|
// translate the element
|
||||||
target.style.webkitTransform =
|
target.style.webkitTransform =
|
||||||
target.style.transform =
|
target.style.transform =
|
||||||
'translate(' + x + 'px, ' + y + 'px)';
|
'translate(' + x + 'px, ' + y + 'px)';
|
||||||
|
|
||||||
// update the posiion attributes
|
// update the posiion attributes
|
||||||
target.setAttribute('data-x', x);
|
target.setAttribute('data-x', x);
|
||||||
target.setAttribute('data-y', y);
|
target.setAttribute('data-y', y);
|
||||||
},
|
},
|
||||||
onend: function (event) {
|
onend: function (event) {
|
||||||
var target = event.target;
|
var target = event.target;
|
||||||
target.style.webkitTransform = target.style.transform = '';
|
target.style.webkitTransform = target.style.transform = '';
|
||||||
target.removeAttribute('data-x');
|
target.removeAttribute('data-x');
|
||||||
target.removeAttribute('data-y');
|
target.removeAttribute('data-y');
|
||||||
jQuery(event.interaction.element).addClass('mailpoet_droppable_active');
|
jQuery(event.interaction.element).addClass('mailpoet_droppable_active');
|
||||||
|
|
||||||
if (that.options.cloneOriginal === true) {
|
if (that.options.cloneOriginal === true) {
|
||||||
jQuery(target).remove();
|
jQuery(target).remove();
|
||||||
|
|
||||||
if (that.options.hideOriginal === true) {
|
if (that.options.hideOriginal === true) {
|
||||||
that.view.$el.removeClass('mailpoet_hidden');
|
that.view.$el.removeClass('mailpoet_hidden');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}).preventDefault('auto');
|
}).preventDefault('auto');
|
||||||
|
|
||||||
|
if (this.options.drop !== undefined) {
|
||||||
|
interactable.getDropModel = this.options.drop;
|
||||||
|
} else {
|
||||||
|
interactable.getDropModel = this.view.getDropFunc();
|
||||||
|
}
|
||||||
|
interactable.onDrop = function(options) {
|
||||||
|
if (_.isObject(options)) {
|
||||||
|
// Inject Draggable behavior if possible
|
||||||
|
options.dragBehavior = that;
|
||||||
|
}
|
||||||
|
// Delegate to view's event handler
|
||||||
|
that.options.onDrop.apply(that, [options]);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (this.options.drop !== undefined) {
|
|
||||||
interactable.getDropModel = this.options.drop;
|
|
||||||
} else {
|
|
||||||
interactable.getDropModel = this.view.getDropFunc();
|
|
||||||
}
|
|
||||||
interactable.onDrop = function(options) {
|
|
||||||
if (_.isObject(options)) {
|
|
||||||
// Inject Draggable behavior if possible
|
|
||||||
options.dragBehavior = that;
|
|
||||||
}
|
|
||||||
// Delegate to view's event handler
|
|
||||||
that.options.onDrop.apply(that, [options]);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
@ -3,59 +3,67 @@
|
|||||||
*
|
*
|
||||||
* Allows resizing elements within a block
|
* Allows resizing elements within a block
|
||||||
*/
|
*/
|
||||||
BehaviorsLookup.ResizableBehavior = Backbone.Marionette.Behavior.extend({
|
define('newsletter_editor/behaviors/ResizableBehavior', [
|
||||||
defaults: {
|
'backbone.marionette',
|
||||||
elementSelector: null,
|
'newsletter_editor/behaviors/BehaviorsLookup',
|
||||||
resizeHandleSelector: true, // true will use edges of the element itself
|
'interact.js',
|
||||||
transformationFunction: function(y) { return y; },
|
], function(Marionette, BehaviorsLookup, interact) {
|
||||||
minLength: 0,
|
|
||||||
modelField: 'styles.block.height',
|
|
||||||
},
|
|
||||||
events: {
|
|
||||||
"mouseenter": 'showResizeHandle',
|
|
||||||
"mouseleave": 'hideResizeHandle',
|
|
||||||
},
|
|
||||||
onRender: function() {
|
|
||||||
this.attachResize();
|
|
||||||
|
|
||||||
if (this.isBeingResized !== true) {
|
BehaviorsLookup.ResizableBehavior = Marionette.Behavior.extend({
|
||||||
this.hideResizeHandle();
|
defaults: {
|
||||||
}
|
elementSelector: null,
|
||||||
},
|
resizeHandleSelector: true, // true will use edges of the element itself
|
||||||
attachResize: function() {
|
transformationFunction: function(y) { return y; },
|
||||||
var domElement = (this.options.elementSelector === null) ? this.view.$el.get(0) : this.view.$(this.options.elementSelector).get(0),
|
minLength: 0,
|
||||||
that = this;
|
modelField: 'styles.block.height',
|
||||||
interact(domElement).resizable({
|
},
|
||||||
//axis: 'y',
|
events: {
|
||||||
edges: {
|
"mouseenter": 'showResizeHandle',
|
||||||
top: false,
|
"mouseleave": 'hideResizeHandle',
|
||||||
left: false,
|
},
|
||||||
right: false,
|
onRender: function() {
|
||||||
bottom: (typeof this.options.resizeHandleSelector === 'string') ? this.view.$(this.options.resizeHandleSelector).get(0) : this.options.resizeHandleSelector,
|
this.attachResize();
|
||||||
},
|
|
||||||
}).on('resizestart', function(event) {
|
|
||||||
that.isBeingResized = true;
|
|
||||||
that.$el.addClass('mailpoet_resize_active');
|
|
||||||
}).on('resizemove', function(event) {
|
|
||||||
var currentLength = parseFloat(that.view.model.get(that.options.modelField)),
|
|
||||||
newLength = currentLength + that.options.transformationFunction(event.dy);
|
|
||||||
|
|
||||||
if (newLength < that.options.minLength) newLength = that.options.minLength;
|
if (this.isBeingResized !== true) {
|
||||||
|
this.hideResizeHandle();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
attachResize: function() {
|
||||||
|
var domElement = (this.options.elementSelector === null) ? this.view.$el.get(0) : this.view.$(this.options.elementSelector).get(0),
|
||||||
|
that = this;
|
||||||
|
interact(domElement).resizable({
|
||||||
|
//axis: 'y',
|
||||||
|
edges: {
|
||||||
|
top: false,
|
||||||
|
left: false,
|
||||||
|
right: false,
|
||||||
|
bottom: (typeof this.options.resizeHandleSelector === 'string') ? this.view.$(this.options.resizeHandleSelector).get(0) : this.options.resizeHandleSelector,
|
||||||
|
},
|
||||||
|
}).on('resizestart', function(event) {
|
||||||
|
that.isBeingResized = true;
|
||||||
|
that.$el.addClass('mailpoet_resize_active');
|
||||||
|
}).on('resizemove', function(event) {
|
||||||
|
var currentLength = parseFloat(that.view.model.get(that.options.modelField)),
|
||||||
|
newLength = currentLength + that.options.transformationFunction(event.dy);
|
||||||
|
|
||||||
|
if (newLength < that.options.minLength) newLength = that.options.minLength;
|
||||||
|
|
||||||
|
that.view.model.set(that.options.modelField, newLength + 'px');
|
||||||
|
}).on('resizeend', function(event) {
|
||||||
|
that.isBeingResized = null;
|
||||||
|
that.$el.removeClass('mailpoet_resize_active');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
showResizeHandle: function() {
|
||||||
|
if (typeof this.options.resizeHandleSelector === 'string') {
|
||||||
|
this.view.$(this.options.resizeHandleSelector).removeClass('mailpoet_hidden');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hideResizeHandle: function() {
|
||||||
|
if (typeof this.options.resizeHandleSelector === 'string') {
|
||||||
|
this.view.$(this.options.resizeHandleSelector).addClass('mailpoet_hidden');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
that.view.model.set(that.options.modelField, newLength + 'px');
|
|
||||||
}).on('resizeend', function(event) {
|
|
||||||
that.isBeingResized = null;
|
|
||||||
that.$el.removeClass('mailpoet_resize_active');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showResizeHandle: function() {
|
|
||||||
if (typeof this.options.resizeHandleSelector === 'string') {
|
|
||||||
this.view.$(this.options.resizeHandleSelector).removeClass('mailpoet_hidden');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hideResizeHandle: function() {
|
|
||||||
if (typeof this.options.resizeHandleSelector === 'string') {
|
|
||||||
this.view.$(this.options.resizeHandleSelector).addClass('mailpoet_hidden');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
@ -3,32 +3,38 @@
|
|||||||
*
|
*
|
||||||
* Allows sorting elements within a collection
|
* Allows sorting elements within a collection
|
||||||
*/
|
*/
|
||||||
BehaviorsLookup.SortableBehavior = Backbone.Marionette.Behavior.extend({
|
define('newsletter_editor/behaviors/SortableBehavior', [
|
||||||
onRender: function() {
|
'backbone.marionette',
|
||||||
var collection = this.view.collection;
|
'newsletter_editor/behaviors/BehaviorsLookup',
|
||||||
|
], function(Marionette, BehaviorsLookup) {
|
||||||
|
|
||||||
if (_.isFunction(this.$el.sortable)) {
|
BehaviorsLookup.SortableBehavior = Marionette.Behavior.extend({
|
||||||
this.$el.sortable({
|
onRender: function() {
|
||||||
cursor: "move",
|
var collection = this.view.collection;
|
||||||
start: function(event, ui) {
|
|
||||||
ui.item.data('previousIndex', ui.item.index());
|
if (_.isFunction(this.$el.sortable)) {
|
||||||
},
|
this.$el.sortable({
|
||||||
end: function(event, ui) {
|
cursor: "move",
|
||||||
ui.item.removeData('previousIndex');
|
start: function(event, ui) {
|
||||||
},
|
ui.item.data('previousIndex', ui.item.index());
|
||||||
update: function(event, ui) {
|
},
|
||||||
var previousIndex = ui.item.data('previousIndex'),
|
end: function(event, ui) {
|
||||||
newIndex = ui.item.index(),
|
ui.item.removeData('previousIndex');
|
||||||
model = collection.at(previousIndex);
|
},
|
||||||
|
update: function(event, ui) {
|
||||||
|
var previousIndex = ui.item.data('previousIndex'),
|
||||||
|
newIndex = ui.item.index(),
|
||||||
|
model = collection.at(previousIndex);
|
||||||
|
|
||||||
|
// Replicate DOM changes. Move target model to a new position
|
||||||
|
// within the collection
|
||||||
|
collection.remove(model);
|
||||||
|
collection.add(model, { at: newIndex });
|
||||||
|
},
|
||||||
|
items: this.options.items,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Replicate DOM changes. Move target model to a new position
|
|
||||||
// within the collection
|
|
||||||
collection.remove(model);
|
|
||||||
collection.add(model, { at: newIndex });
|
|
||||||
},
|
|
||||||
items: this.options.items,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -6,325 +6,335 @@
|
|||||||
* This block depends on blocks.button and blocks.divider for block model and
|
* This block depends on blocks.button and blocks.divider for block model and
|
||||||
* block settings view.
|
* block settings view.
|
||||||
*/
|
*/
|
||||||
EditorApplication.module("blocks.automatedLatestContent", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/blocks/automatedLatestContent', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
'mailpoet',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette, MailPoet) {
|
||||||
|
|
||||||
var base = App.module('blocks.base');
|
EditorApplication.module("blocks.automatedLatestContent", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
Module.AutomatedLatestContentBlockModel = base.BlockModel.extend({
|
var base = App.module('blocks.base');
|
||||||
stale: ['_container'],
|
|
||||||
defaults: function() {
|
|
||||||
return this._getDefaults({
|
|
||||||
type: 'automatedLatestContent',
|
|
||||||
amount: '5',
|
|
||||||
contentType: 'post', // 'post'|'page'|'mailpoet_page'
|
|
||||||
terms: [], // List of category and tag objects
|
|
||||||
inclusionType: 'include', // 'include'|'exclude'
|
|
||||||
displayType: 'excerpt', // 'excerpt'|'full'|'titleOnly'
|
|
||||||
titleFormat: 'h1', // 'h1'|'h2'|'h3'|'ul'
|
|
||||||
titlePosition: 'inTextBlock', // 'inTextBlock'|'aboveBlock',
|
|
||||||
titleAlignment: 'left', // 'left'|'center'|'right'
|
|
||||||
titleIsLink: false, // false|true
|
|
||||||
imagePadded: true, // true|false
|
|
||||||
//imageAlignment: 'centerPadded', // 'centerFull'|'centerPadded'|'left'|'right'|'alternate'|'none'
|
|
||||||
showAuthor: 'no', // 'no'|'aboveText'|'belowText'
|
|
||||||
authorPrecededBy: 'Author:',
|
|
||||||
showCategories: 'no', // 'no'|'aboveText'|'belowText'
|
|
||||||
categoriesPrecededBy: 'Categories:',
|
|
||||||
readMoreType: 'button', // 'link'|'button'
|
|
||||||
readMoreText: 'Read more', // 'link'|'button'
|
|
||||||
readMoreButton: {
|
|
||||||
text: 'Read more',
|
|
||||||
url: '[postLink]'
|
|
||||||
},
|
|
||||||
sortBy: 'newest', // 'newest'|'oldest',
|
|
||||||
showDivider: true, // true|false
|
|
||||||
divider: {},
|
|
||||||
_container: new (App.getBlockTypeModel('container'))(),
|
|
||||||
}, EditorApplication.getConfig().get('blockDefaults.automatedLatestContent'));
|
|
||||||
},
|
|
||||||
relations: function() {
|
|
||||||
return {
|
|
||||||
readMoreButton: App.getBlockTypeModel('button'),
|
|
||||||
divider: App.getBlockTypeModel('divider'),
|
|
||||||
_container: App.getBlockTypeModel('container'),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
initialize: function() {
|
|
||||||
base.BlockModel.prototype.initialize.apply(this);
|
|
||||||
this.fetchPosts();
|
|
||||||
this.on('change:amount change:contentType change:terms change:inclusionType change:displayType change:titleFormat change:titlePosition change:titleAlignment change:titleIsLink change:imagePadded change:showAuthor change:authorPrecededBy change:showCategories change:categoriesPrecededBy change:readMoreType change:readMoreText change:sortBy change:showDivider', this._scheduleFetchPosts, this);
|
|
||||||
this.listenTo(this.get('readMoreButton'), 'change', this._scheduleFetchPosts);
|
|
||||||
this.listenTo(this.get('divider'), 'change', this._scheduleFetchPosts);
|
|
||||||
},
|
|
||||||
fetchPosts: function() {
|
|
||||||
var that = this;
|
|
||||||
mailpoet_post_wpi('automated_latest_content.php', this.toJSON(), function(response) {
|
|
||||||
console.log('ALC fetched', arguments);
|
|
||||||
that.get('_container').get('blocks').reset(response, {parse: true});
|
|
||||||
}, function() {
|
|
||||||
console.log('ALC fetchPosts error', arguments);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Batch more changes during a specific time, instead of fetching
|
|
||||||
* ALC posts on each model change
|
|
||||||
*/
|
|
||||||
_scheduleFetchPosts: function() {
|
|
||||||
var timeout = 2000,
|
|
||||||
that = this;
|
|
||||||
if (this._fetchPostsTimer !== undefined) {
|
|
||||||
clearTimeout(this._fetchPostsTimer);
|
|
||||||
}
|
|
||||||
this._fetchPostsTimer = setTimeout(function() {
|
|
||||||
that.fetchPosts();
|
|
||||||
that._fetchPostsTimer = undefined;
|
|
||||||
}, timeout);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.AutomatedLatestContentBlockView = base.BlockView.extend({
|
Module.AutomatedLatestContentBlockModel = base.BlockModel.extend({
|
||||||
className: "mailpoet_block mailpoet_automated_latest_content_block mailpoet_droppable_block",
|
stale: ['_container'],
|
||||||
getTemplate: function() { return templates.automatedLatestContentBlock; },
|
defaults: function() {
|
||||||
regions: {
|
return this._getDefaults({
|
||||||
toolsRegion: '.mailpoet_tools',
|
type: 'automatedLatestContent',
|
||||||
postsRegion: '.mailpoet_automated_latest_content_block_posts',
|
amount: '5',
|
||||||
},
|
contentType: 'post', // 'post'|'page'|'mailpoet_page'
|
||||||
onDragSubstituteBy: function() { return Module.AutomatedLatestContentWidgetView; },
|
terms: [], // List of category and tag objects
|
||||||
onRender: function() {
|
inclusionType: 'include', // 'include'|'exclude'
|
||||||
var ContainerView = App.getBlockTypeView('container'),
|
displayType: 'excerpt', // 'excerpt'|'full'|'titleOnly'
|
||||||
renderOptions = {
|
titleFormat: 'h1', // 'h1'|'h2'|'h3'|'ul'
|
||||||
disableTextEditor: true,
|
titlePosition: 'inTextBlock', // 'inTextBlock'|'aboveBlock',
|
||||||
disableDragAndDrop: true,
|
titleAlignment: 'left', // 'left'|'center'|'right'
|
||||||
};
|
titleIsLink: false, // false|true
|
||||||
this.toolsView = new Module.AutomatedLatestContentBlockToolsView({ model: this.model });
|
imagePadded: true, // true|false
|
||||||
this.toolsRegion.show(this.toolsView);
|
//imageAlignment: 'centerPadded', // 'centerFull'|'centerPadded'|'left'|'right'|'alternate'|'none'
|
||||||
this.postsRegion.show(new ContainerView({ model: this.model.get('_container'), renderOptions: renderOptions }));
|
showAuthor: 'no', // 'no'|'aboveText'|'belowText'
|
||||||
},
|
authorPrecededBy: 'Author:',
|
||||||
});
|
showCategories: 'no', // 'no'|'aboveText'|'belowText'
|
||||||
|
categoriesPrecededBy: 'Categories:',
|
||||||
|
readMoreType: 'button', // 'link'|'button'
|
||||||
|
readMoreText: 'Read more', // 'link'|'button'
|
||||||
|
readMoreButton: {
|
||||||
|
text: 'Read more',
|
||||||
|
url: '[postLink]'
|
||||||
|
},
|
||||||
|
sortBy: 'newest', // 'newest'|'oldest',
|
||||||
|
showDivider: true, // true|false
|
||||||
|
divider: {},
|
||||||
|
_container: new (App.getBlockTypeModel('container'))(),
|
||||||
|
}, EditorApplication.getConfig().get('blockDefaults.automatedLatestContent'));
|
||||||
|
},
|
||||||
|
relations: function() {
|
||||||
|
return {
|
||||||
|
readMoreButton: App.getBlockTypeModel('button'),
|
||||||
|
divider: App.getBlockTypeModel('divider'),
|
||||||
|
_container: App.getBlockTypeModel('container'),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
initialize: function() {
|
||||||
|
base.BlockModel.prototype.initialize.apply(this);
|
||||||
|
this.fetchPosts();
|
||||||
|
this.on('change:amount change:contentType change:terms change:inclusionType change:displayType change:titleFormat change:titlePosition change:titleAlignment change:titleIsLink change:imagePadded change:showAuthor change:authorPrecededBy change:showCategories change:categoriesPrecededBy change:readMoreType change:readMoreText change:sortBy change:showDivider', this._scheduleFetchPosts, this);
|
||||||
|
this.listenTo(this.get('readMoreButton'), 'change', this._scheduleFetchPosts);
|
||||||
|
this.listenTo(this.get('divider'), 'change', this._scheduleFetchPosts);
|
||||||
|
},
|
||||||
|
fetchPosts: function() {
|
||||||
|
var that = this;
|
||||||
|
mailpoet_post_wpi('automated_latest_content.php', this.toJSON(), function(response) {
|
||||||
|
console.log('ALC fetched', arguments);
|
||||||
|
that.get('_container').get('blocks').reset(response, {parse: true});
|
||||||
|
}, function() {
|
||||||
|
console.log('ALC fetchPosts error', arguments);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Batch more changes during a specific time, instead of fetching
|
||||||
|
* ALC posts on each model change
|
||||||
|
*/
|
||||||
|
_scheduleFetchPosts: function() {
|
||||||
|
var timeout = 2000,
|
||||||
|
that = this;
|
||||||
|
if (this._fetchPostsTimer !== undefined) {
|
||||||
|
clearTimeout(this._fetchPostsTimer);
|
||||||
|
}
|
||||||
|
this._fetchPostsTimer = setTimeout(function() {
|
||||||
|
that.fetchPosts();
|
||||||
|
that._fetchPostsTimer = undefined;
|
||||||
|
}, timeout);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Module.AutomatedLatestContentBlockToolsView = base.BlockToolsView.extend({
|
Module.AutomatedLatestContentBlockView = base.BlockView.extend({
|
||||||
getSettingsView: function() { return Module.AutomatedLatestContentBlockSettingsView; },
|
className: "mailpoet_block mailpoet_automated_latest_content_block mailpoet_droppable_block",
|
||||||
});
|
getTemplate: function() { return templates.automatedLatestContentBlock; },
|
||||||
|
regions: {
|
||||||
|
toolsRegion: '.mailpoet_tools',
|
||||||
|
postsRegion: '.mailpoet_automated_latest_content_block_posts',
|
||||||
|
},
|
||||||
|
onDragSubstituteBy: function() { return Module.AutomatedLatestContentWidgetView; },
|
||||||
|
onRender: function() {
|
||||||
|
var ContainerView = App.getBlockTypeView('container'),
|
||||||
|
renderOptions = {
|
||||||
|
disableTextEditor: true,
|
||||||
|
disableDragAndDrop: true,
|
||||||
|
};
|
||||||
|
this.toolsView = new Module.AutomatedLatestContentBlockToolsView({ model: this.model });
|
||||||
|
this.toolsRegion.show(this.toolsView);
|
||||||
|
this.postsRegion.show(new ContainerView({ model: this.model.get('_container'), renderOptions: renderOptions }));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// Sidebar view container
|
Module.AutomatedLatestContentBlockToolsView = base.BlockToolsView.extend({
|
||||||
Module.AutomatedLatestContentBlockSettingsView = base.BlockSettingsView.extend({
|
getSettingsView: function() { return Module.AutomatedLatestContentBlockSettingsView; },
|
||||||
getTemplate: function() { return templates.automatedLatestContentBlockSettings; },
|
});
|
||||||
events: function() {
|
|
||||||
return {
|
|
||||||
"click .mailpoet_automated_latest_content_hide_display_options": 'toggleDisplayOptions',
|
|
||||||
"click .mailpoet_automated_latest_content_show_display_options": 'toggleDisplayOptions',
|
|
||||||
"click .mailpoet_automated_latest_content_select_button": 'showButtonSettings',
|
|
||||||
"click .mailpoet_automated_latest_content_select_divider": 'showDividerSettings',
|
|
||||||
"change .mailpoet_automated_latest_content_read_more_type": 'changeReadMoreType',
|
|
||||||
"change .mailpoet_automated_latest_content_display_type": 'changeDisplayType',
|
|
||||||
"change .mailpoet_automated_latest_content_title_format": 'changeTitleFormat',
|
|
||||||
"change .mailpoet_automated_latest_content_title_as_links": _.partial(this.changeBoolField, 'titleIsLink'),
|
|
||||||
"change .mailpoet_automated_latest_content_show_divider": _.partial(this.changeBoolField, 'showDivider'),
|
|
||||||
"keyup .mailpoet_automated_latest_content_show_amount": _.partial(this.changeField, "amount"),
|
|
||||||
"change .mailpoet_automated_latest_content_content_type": _.partial(this.changeField, "contentType"),
|
|
||||||
"change .mailpoet_automated_latest_content_include_or_exclude": _.partial(this.changeField, "inclusionType"),
|
|
||||||
"change .mailpoet_automated_latest_content_title_position": _.partial(this.changeField, "titlePosition"),
|
|
||||||
"change .mailpoet_automated_latest_content_title_alignment": _.partial(this.changeField, "titleAlignment"),
|
|
||||||
"change .mailpoet_automated_latest_content_image_padded": _.partial(this.changeBoolField, "imagePadded"),
|
|
||||||
"change .mailpoet_automated_latest_content_show_author": _.partial(this.changeField, "showAuthor"),
|
|
||||||
"keyup .mailpoet_automated_latest_content_author_preceded_by": _.partial(this.changeField, "authorPrecededBy"),
|
|
||||||
"change .mailpoet_automated_latest_content_show_categories": _.partial(this.changeField, "showCategories"),
|
|
||||||
"keyup .mailpoet_automated_latest_content_categories": _.partial(this.changeField, "categoriesPrecededBy"),
|
|
||||||
"keyup .mailpoet_automated_latest_content_read_more_text": _.partial(this.changeField, "readMoreText"),
|
|
||||||
"change .mailpoet_automated_latest_content_sort_by": _.partial(this.changeField, "sortBy"),
|
|
||||||
"click .mailpoet_done_editing": "close",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
behaviors: {
|
|
||||||
ColorPickerBehavior: {},
|
|
||||||
},
|
|
||||||
templateHelpers: function() {
|
|
||||||
return {
|
|
||||||
model: this.model.toJSON(),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
onRender: function() {
|
|
||||||
var that = this;
|
|
||||||
|
|
||||||
this.$('.mailpoet_automated_latest_content_categories_and_tags').select2({
|
// Sidebar view container
|
||||||
multiple: true,
|
Module.AutomatedLatestContentBlockSettingsView = base.BlockSettingsView.extend({
|
||||||
allowClear: true,
|
getTemplate: function() { return templates.automatedLatestContentBlockSettings; },
|
||||||
ajax: {
|
events: function() {
|
||||||
url: App.getConfig().get('urls.termSearch'),
|
return {
|
||||||
type: 'POST',
|
"click .mailpoet_automated_latest_content_hide_display_options": 'toggleDisplayOptions',
|
||||||
dataType: 'json',
|
"click .mailpoet_automated_latest_content_show_display_options": 'toggleDisplayOptions',
|
||||||
delay: 250,
|
"click .mailpoet_automated_latest_content_select_button": 'showButtonSettings',
|
||||||
data: function(searchParameter, page) {
|
"click .mailpoet_automated_latest_content_select_divider": 'showDividerSettings',
|
||||||
return JSON.stringify({
|
"change .mailpoet_automated_latest_content_read_more_type": 'changeReadMoreType',
|
||||||
postType: that.model.get('contentType'),
|
"change .mailpoet_automated_latest_content_display_type": 'changeDisplayType',
|
||||||
search: searchParameter,
|
"change .mailpoet_automated_latest_content_title_format": 'changeTitleFormat',
|
||||||
limit: 10, // TODO: Move this hardcoded limit to Config
|
"change .mailpoet_automated_latest_content_title_as_links": _.partial(this.changeBoolField, 'titleIsLink'),
|
||||||
page: page,
|
"change .mailpoet_automated_latest_content_show_divider": _.partial(this.changeBoolField, 'showDivider'),
|
||||||
});
|
"keyup .mailpoet_automated_latest_content_show_amount": _.partial(this.changeField, "amount"),
|
||||||
},
|
"change .mailpoet_automated_latest_content_content_type": _.partial(this.changeField, "contentType"),
|
||||||
/**
|
"change .mailpoet_automated_latest_content_include_or_exclude": _.partial(this.changeField, "inclusionType"),
|
||||||
* Parse results for select2.
|
"change .mailpoet_automated_latest_content_title_position": _.partial(this.changeField, "titlePosition"),
|
||||||
* Returns object, where `results` key holds a list of
|
"change .mailpoet_automated_latest_content_title_alignment": _.partial(this.changeField, "titleAlignment"),
|
||||||
* select item objects
|
"change .mailpoet_automated_latest_content_image_padded": _.partial(this.changeBoolField, "imagePadded"),
|
||||||
*/
|
"change .mailpoet_automated_latest_content_show_author": _.partial(this.changeField, "showAuthor"),
|
||||||
results: function (data, page) {
|
"keyup .mailpoet_automated_latest_content_author_preceded_by": _.partial(this.changeField, "authorPrecededBy"),
|
||||||
return {
|
"change .mailpoet_automated_latest_content_show_categories": _.partial(this.changeField, "showCategories"),
|
||||||
results: _.map(
|
"keyup .mailpoet_automated_latest_content_categories": _.partial(this.changeField, "categoriesPrecededBy"),
|
||||||
data.results,
|
"keyup .mailpoet_automated_latest_content_read_more_text": _.partial(this.changeField, "readMoreText"),
|
||||||
function(item) {
|
"change .mailpoet_automated_latest_content_sort_by": _.partial(this.changeField, "sortBy"),
|
||||||
return _.defaults({
|
"click .mailpoet_done_editing": "close",
|
||||||
text: data.taxonomies[item.taxonomy].labels.singular_name + ': ' + item.name,
|
};
|
||||||
id: item.term_id
|
},
|
||||||
}, item);
|
behaviors: {
|
||||||
}
|
ColorPickerBehavior: {},
|
||||||
)
|
},
|
||||||
};
|
templateHelpers: function() {
|
||||||
}
|
return {
|
||||||
},
|
model: this.model.toJSON(),
|
||||||
initSelection: function(element, callback) {
|
};
|
||||||
// On external data load tell select2 which terms to preselect
|
},
|
||||||
|
onRender: function() {
|
||||||
|
var that = this;
|
||||||
|
|
||||||
callback(_.map(
|
this.$('.mailpoet_automated_latest_content_categories_and_tags').select2({
|
||||||
that.model.get('terms').toJSON(),
|
multiple: true,
|
||||||
function(item) {
|
allowClear: true,
|
||||||
return {
|
ajax: {
|
||||||
id: item.id,
|
url: App.getConfig().get('urls.termSearch'),
|
||||||
text: item.text,
|
type: 'POST',
|
||||||
};
|
dataType: 'json',
|
||||||
}
|
delay: 250,
|
||||||
));
|
data: function(searchParameter, page) {
|
||||||
},
|
return JSON.stringify({
|
||||||
}).trigger( 'change' ).on({
|
postType: that.model.get('contentType'),
|
||||||
'change': function(e){
|
search: searchParameter,
|
||||||
var data = $(this).data('selected');
|
limit: 10, // TODO: Move this hardcoded limit to Config
|
||||||
|
page: page,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Parse results for select2.
|
||||||
|
* Returns object, where `results` key holds a list of
|
||||||
|
* select item objects
|
||||||
|
*/
|
||||||
|
results: function (data, page) {
|
||||||
|
return {
|
||||||
|
results: _.map(
|
||||||
|
data.results,
|
||||||
|
function(item) {
|
||||||
|
return _.defaults({
|
||||||
|
text: data.taxonomies[item.taxonomy].labels.singular_name + ': ' + item.name,
|
||||||
|
id: item.term_id
|
||||||
|
}, item);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initSelection: function(element, callback) {
|
||||||
|
// On external data load tell select2 which terms to preselect
|
||||||
|
|
||||||
if (typeof data === 'string') {
|
callback(_.map(
|
||||||
if (data === '') {
|
that.model.get('terms').toJSON(),
|
||||||
data = [];
|
function(item) {
|
||||||
} else {
|
return {
|
||||||
data = JSON.parse(data);
|
id: item.id,
|
||||||
}
|
text: item.text,
|
||||||
}
|
};
|
||||||
|
}
|
||||||
|
));
|
||||||
|
},
|
||||||
|
}).trigger( 'change' ).on({
|
||||||
|
'change': function(e){
|
||||||
|
var data = $(this).data('selected');
|
||||||
|
|
||||||
if ( e.added ){
|
if (typeof data === 'string') {
|
||||||
data.push(e.added);
|
if (data === '') {
|
||||||
} else {
|
data = [];
|
||||||
data = _.filter(data, function(item) {
|
} else {
|
||||||
return item.id !== e.removed.id;
|
data = JSON.parse(data);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update ALC model
|
if ( e.added ){
|
||||||
that.model.set('terms', data);
|
data.push(e.added);
|
||||||
|
} else {
|
||||||
|
data = _.filter(data, function(item) {
|
||||||
|
return item.id !== e.removed.id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
$(this).data('selected', JSON.stringify(data));
|
// Update ALC model
|
||||||
}
|
that.model.set('terms', data);
|
||||||
});
|
|
||||||
},
|
|
||||||
onBeforeDestroy: function() {
|
|
||||||
// Force close select2 if it hasn't closed yet
|
|
||||||
this.$('.mailpoet_automated_latest_content_categories_and_tags').select2('close');
|
|
||||||
},
|
|
||||||
toggleDisplayOptions: function(event) {
|
|
||||||
var el = this.$('.mailpoet_automated_latest_content_display_options'),
|
|
||||||
showControl = this.$('.mailpoet_automated_latest_content_show_display_options');
|
|
||||||
if (el.hasClass('mailpoet_hidden')) {
|
|
||||||
el.removeClass('mailpoet_hidden');
|
|
||||||
showControl.addClass('mailpoet_hidden');
|
|
||||||
} else {
|
|
||||||
el.addClass('mailpoet_hidden');
|
|
||||||
showControl.removeClass('mailpoet_hidden');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showButtonSettings: function(event) {
|
|
||||||
var buttonModule = App.module('blocks.button');
|
|
||||||
(new buttonModule.ButtonBlockSettingsView({
|
|
||||||
model: this.model.get('readMoreButton'),
|
|
||||||
renderOptions: {
|
|
||||||
displayFormat: 'subpanel',
|
|
||||||
hideLink: true,
|
|
||||||
hideApplyToAll: true,
|
|
||||||
},
|
|
||||||
})).render();
|
|
||||||
},
|
|
||||||
showDividerSettings: function(event) {
|
|
||||||
var dividerModule = App.module('blocks.divider');
|
|
||||||
(new dividerModule.DividerBlockSettingsView({
|
|
||||||
model: this.model.get('divider'),
|
|
||||||
renderOptions: {
|
|
||||||
displayFormat: 'subpanel',
|
|
||||||
hideApplyToAll: true,
|
|
||||||
},
|
|
||||||
})).render();
|
|
||||||
},
|
|
||||||
changeReadMoreType: function(event) {
|
|
||||||
var value = jQuery(event.target).val();
|
|
||||||
if (value == 'link') {
|
|
||||||
this.$('.mailpoet_automated_latest_content_read_more_text').removeClass('mailpoet_hidden');
|
|
||||||
this.$('.mailpoet_automated_latest_content_select_button').addClass('mailpoet_hidden');
|
|
||||||
} else if (value == 'button') {
|
|
||||||
this.$('.mailpoet_automated_latest_content_read_more_text').addClass('mailpoet_hidden');
|
|
||||||
this.$('.mailpoet_automated_latest_content_select_button').removeClass('mailpoet_hidden');
|
|
||||||
}
|
|
||||||
this.changeField('readMoreType', event);
|
|
||||||
},
|
|
||||||
changeDisplayType: function(event) {
|
|
||||||
var value = jQuery(event.target).val();
|
|
||||||
if (value == 'titleOnly') {
|
|
||||||
this.$('.mailpoet_automated_latest_content_title_position_container').addClass('mailpoet_hidden');
|
|
||||||
this.$('.mailpoet_automated_latest_content_title_as_list').removeClass('mailpoet_hidden');
|
|
||||||
} else {
|
|
||||||
this.$('.mailpoet_automated_latest_content_title_position_container').removeClass('mailpoet_hidden');
|
|
||||||
this.$('.mailpoet_automated_latest_content_title_as_list').addClass('mailpoet_hidden');
|
|
||||||
|
|
||||||
// Reset titleFormat if it was set to List when switching away from displayType=titleOnly
|
$(this).data('selected', JSON.stringify(data));
|
||||||
if (this.model.get('titleFormat') === 'ul') {
|
}
|
||||||
this.model.set('titleFormat', 'h1');
|
});
|
||||||
this.$('.mailpoet_automated_latest_content_title_format').val(['h1']);
|
},
|
||||||
this.$('.mailpoet_automated_latest_content_title_as_link').removeClass('mailpoet_hidden');
|
onBeforeDestroy: function() {
|
||||||
}
|
// Force close select2 if it hasn't closed yet
|
||||||
}
|
this.$('.mailpoet_automated_latest_content_categories_and_tags').select2('close');
|
||||||
this.changeField('displayType', event);
|
},
|
||||||
},
|
toggleDisplayOptions: function(event) {
|
||||||
changeTitleFormat: function(event) {
|
var el = this.$('.mailpoet_automated_latest_content_display_options'),
|
||||||
var value = jQuery(event.target).val();
|
showControl = this.$('.mailpoet_automated_latest_content_show_display_options');
|
||||||
if (value == 'ul') {
|
if (el.hasClass('mailpoet_hidden')) {
|
||||||
this.$('.mailpoet_automated_latest_content_non_title_list_options').addClass('mailpoet_hidden');
|
el.removeClass('mailpoet_hidden');
|
||||||
|
showControl.addClass('mailpoet_hidden');
|
||||||
|
} else {
|
||||||
|
el.addClass('mailpoet_hidden');
|
||||||
|
showControl.removeClass('mailpoet_hidden');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showButtonSettings: function(event) {
|
||||||
|
var buttonModule = App.module('blocks.button');
|
||||||
|
(new buttonModule.ButtonBlockSettingsView({
|
||||||
|
model: this.model.get('readMoreButton'),
|
||||||
|
renderOptions: {
|
||||||
|
displayFormat: 'subpanel',
|
||||||
|
hideLink: true,
|
||||||
|
hideApplyToAll: true,
|
||||||
|
},
|
||||||
|
})).render();
|
||||||
|
},
|
||||||
|
showDividerSettings: function(event) {
|
||||||
|
var dividerModule = App.module('blocks.divider');
|
||||||
|
(new dividerModule.DividerBlockSettingsView({
|
||||||
|
model: this.model.get('divider'),
|
||||||
|
renderOptions: {
|
||||||
|
displayFormat: 'subpanel',
|
||||||
|
hideApplyToAll: true,
|
||||||
|
},
|
||||||
|
})).render();
|
||||||
|
},
|
||||||
|
changeReadMoreType: function(event) {
|
||||||
|
var value = jQuery(event.target).val();
|
||||||
|
if (value == 'link') {
|
||||||
|
this.$('.mailpoet_automated_latest_content_read_more_text').removeClass('mailpoet_hidden');
|
||||||
|
this.$('.mailpoet_automated_latest_content_select_button').addClass('mailpoet_hidden');
|
||||||
|
} else if (value == 'button') {
|
||||||
|
this.$('.mailpoet_automated_latest_content_read_more_text').addClass('mailpoet_hidden');
|
||||||
|
this.$('.mailpoet_automated_latest_content_select_button').removeClass('mailpoet_hidden');
|
||||||
|
}
|
||||||
|
this.changeField('readMoreType', event);
|
||||||
|
},
|
||||||
|
changeDisplayType: function(event) {
|
||||||
|
var value = jQuery(event.target).val();
|
||||||
|
if (value == 'titleOnly') {
|
||||||
|
this.$('.mailpoet_automated_latest_content_title_position_container').addClass('mailpoet_hidden');
|
||||||
|
this.$('.mailpoet_automated_latest_content_title_as_list').removeClass('mailpoet_hidden');
|
||||||
|
} else {
|
||||||
|
this.$('.mailpoet_automated_latest_content_title_position_container').removeClass('mailpoet_hidden');
|
||||||
|
this.$('.mailpoet_automated_latest_content_title_as_list').addClass('mailpoet_hidden');
|
||||||
|
|
||||||
this.model.set('titleIsLink', true);
|
// Reset titleFormat if it was set to List when switching away from displayType=titleOnly
|
||||||
this.$('.mailpoet_automated_latest_content_title_as_link').addClass('mailpoet_hidden');
|
if (this.model.get('titleFormat') === 'ul') {
|
||||||
this.$('.mailpoet_automated_latest_content_title_as_links').val(['true']);
|
this.model.set('titleFormat', 'h1');
|
||||||
} else {
|
this.$('.mailpoet_automated_latest_content_title_format').val(['h1']);
|
||||||
this.$('.mailpoet_automated_latest_content_non_title_list_options').removeClass('mailpoet_hidden');
|
this.$('.mailpoet_automated_latest_content_title_as_link').removeClass('mailpoet_hidden');
|
||||||
this.$('.mailpoet_automated_latest_content_title_as_link').removeClass('mailpoet_hidden');
|
}
|
||||||
}
|
}
|
||||||
this.changeField('titleFormat', event);
|
this.changeField('displayType', event);
|
||||||
},
|
},
|
||||||
});
|
changeTitleFormat: function(event) {
|
||||||
|
var value = jQuery(event.target).val();
|
||||||
|
if (value == 'ul') {
|
||||||
|
this.$('.mailpoet_automated_latest_content_non_title_list_options').addClass('mailpoet_hidden');
|
||||||
|
|
||||||
Module.AutomatedLatestContentWidgetView = base.WidgetView.extend({
|
this.model.set('titleIsLink', true);
|
||||||
getTemplate: function() { return templates.automatedLatestContentInsertion; },
|
this.$('.mailpoet_automated_latest_content_title_as_link').addClass('mailpoet_hidden');
|
||||||
behaviors: {
|
this.$('.mailpoet_automated_latest_content_title_as_links').val(['true']);
|
||||||
DraggableBehavior: {
|
} else {
|
||||||
cloneOriginal: true,
|
this.$('.mailpoet_automated_latest_content_non_title_list_options').removeClass('mailpoet_hidden');
|
||||||
drop: function() {
|
this.$('.mailpoet_automated_latest_content_title_as_link').removeClass('mailpoet_hidden');
|
||||||
return new Module.AutomatedLatestContentBlockModel({}, { parse: true });
|
}
|
||||||
}
|
this.changeField('titleFormat', event);
|
||||||
}
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
App.on('before:start', function() {
|
Module.AutomatedLatestContentWidgetView = base.WidgetView.extend({
|
||||||
App.registerBlockType('automatedLatestContent', {
|
getTemplate: function() { return templates.automatedLatestContentInsertion; },
|
||||||
blockModel: Module.AutomatedLatestContentBlockModel,
|
behaviors: {
|
||||||
blockView: Module.AutomatedLatestContentBlockView,
|
DraggableBehavior: {
|
||||||
});
|
cloneOriginal: true,
|
||||||
|
drop: function() {
|
||||||
|
return new Module.AutomatedLatestContentBlockModel({}, { parse: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
App.on('before:start', function() {
|
||||||
|
App.registerBlockType('automatedLatestContent', {
|
||||||
|
blockModel: Module.AutomatedLatestContentBlockModel,
|
||||||
|
blockView: Module.AutomatedLatestContentBlockView,
|
||||||
|
});
|
||||||
|
|
||||||
|
App.registerWidget({
|
||||||
|
name: 'automatedLatestContent',
|
||||||
|
widgetView: Module.AutomatedLatestContentWidgetView,
|
||||||
|
priority: 97,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.registerWidget({
|
|
||||||
name: 'automatedLatestContent',
|
|
||||||
widgetView: Module.AutomatedLatestContentWidgetView,
|
|
||||||
priority: 97,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -4,206 +4,217 @@
|
|||||||
* a BlockModel and a BlockView.
|
* a BlockModel and a BlockView.
|
||||||
* BlockToolsView, BlockSettingsView and BlockWidgetView are optional.
|
* BlockToolsView, BlockSettingsView and BlockWidgetView are optional.
|
||||||
*/
|
*/
|
||||||
EditorApplication.module("blocks.base", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/blocks/base', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
'mailpoet',
|
||||||
|
'modal',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette, MailPoet) {
|
||||||
|
|
||||||
var AugmentedView = Marionette.LayoutView.extend({});
|
EditorApplication.module("blocks.base", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
Module.BlockModel = Backbone.SuperModel.extend({
|
var AugmentedView = Marionette.LayoutView.extend({});
|
||||||
stale: [], // Attributes to be removed upon saving
|
|
||||||
initialize: function() {
|
|
||||||
var that = this;
|
|
||||||
this.on('change', function() {
|
|
||||||
App.getChannel().trigger('autoSave');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
_getDefaults: function(blockDefaults, configDefaults) {
|
|
||||||
var defaults = (_.isObject(configDefaults) && _.isFunction(configDefaults.toJSON)) ? configDefaults.toJSON() : configDefaults;
|
|
||||||
|
|
||||||
// Patch the resulting JSON object and fix it's constructors to be Object.
|
Module.BlockModel = SuperModel.extend({
|
||||||
// Otherwise Backbone.SuperModel interprets it not as a simpleObject
|
stale: [], // Attributes to be removed upon saving
|
||||||
// and misbehaves
|
initialize: function() {
|
||||||
// TODO: Investigate for a better solution
|
var that = this;
|
||||||
return JSON.parse(JSON.stringify(jQuery.extend(blockDefaults, defaults || {})));
|
this.on('change', function() {
|
||||||
},
|
App.getChannel().trigger('autoSave');
|
||||||
toJSON: function() {
|
});
|
||||||
// Remove stale attributes from resulting JSON object
|
},
|
||||||
return _.omit(Backbone.SuperModel.prototype.toJSON.call(this), this.stale);
|
_getDefaults: function(blockDefaults, configDefaults) {
|
||||||
},
|
var defaults = (_.isObject(configDefaults) && _.isFunction(configDefaults.toJSON)) ? configDefaults.toJSON() : configDefaults;
|
||||||
});
|
|
||||||
|
|
||||||
Module.BlockView = AugmentedView.extend({
|
// Patch the resulting JSON object and fix it's constructors to be Object.
|
||||||
regions: {
|
// Otherwise SuperModel interprets it not as a simpleObject
|
||||||
toolsRegion: '> .mailpoet_tools',
|
// and misbehaves
|
||||||
},
|
// TODO: Investigate for a better solution
|
||||||
modelEvents: {
|
return JSON.parse(JSON.stringify(jQuery.extend(blockDefaults, defaults || {})));
|
||||||
'change': 'render',
|
},
|
||||||
},
|
toJSON: function() {
|
||||||
events: {
|
// Remove stale attributes from resulting JSON object
|
||||||
"mouseenter": "showTools",
|
return _.omit(SuperModel.prototype.toJSON.call(this), this.stale);
|
||||||
"mouseleave": "hideTools",
|
},
|
||||||
},
|
});
|
||||||
behaviors: {
|
|
||||||
DraggableBehavior: {
|
|
||||||
cloneOriginal: true,
|
|
||||||
hideOriginal: true,
|
|
||||||
onDrop: function(options) {
|
|
||||||
// After a clone of model has been dropped, cleanup
|
|
||||||
// and destroy self
|
|
||||||
options.dragBehavior.view.model.destroy();
|
|
||||||
},
|
|
||||||
onDragSubstituteBy: function(behavior) {
|
|
||||||
var WidgetView, node;
|
|
||||||
// When block is being dragged, display the widget icon instead.
|
|
||||||
// This will create an instance of block's widget view and
|
|
||||||
// use it's rendered DOM element instead of the content block
|
|
||||||
if (_.isFunction(behavior.view.onDragSubstituteBy)) {
|
|
||||||
WidgetView = new (behavior.view.onDragSubstituteBy())();
|
|
||||||
WidgetView.render();
|
|
||||||
node = WidgetView.$el.get(0).cloneNode(true);
|
|
||||||
WidgetView.destroy();
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
templateHelpers: function() {
|
|
||||||
return {
|
|
||||||
model: this.model.toJSON(),
|
|
||||||
viewCid: this.cid,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
constructor: function() {
|
|
||||||
AugmentedView.apply(this, arguments);
|
|
||||||
this.$el.addClass('mailpoet_editor_view_' + this.cid);
|
|
||||||
},
|
|
||||||
showTools: function(_event) {
|
|
||||||
if (!this.showingToolsDisabled) {
|
|
||||||
this.$('> .mailpoet_tools').show();
|
|
||||||
this.toolsView.triggerMethod('showTools');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hideTools: function(e) {
|
|
||||||
this.$('> .mailpoet_tools').hide();
|
|
||||||
this.toolsView.triggerMethod('hideTools');
|
|
||||||
},
|
|
||||||
enableShowingTools: function() {
|
|
||||||
this.showingToolsDisabled = false;
|
|
||||||
},
|
|
||||||
disableShowingTools: function() {
|
|
||||||
this.showingToolsDisabled = true;
|
|
||||||
this.hideTools();
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Defines drop behavior of BlockView instance
|
|
||||||
*/
|
|
||||||
getDropFunc: function() {
|
|
||||||
var that = this;
|
|
||||||
return function() {
|
|
||||||
var newModel = that.model.clone();
|
|
||||||
//that.model.destroy();
|
|
||||||
return newModel;
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.BlockToolsView = AugmentedView.extend({
|
Module.BlockView = AugmentedView.extend({
|
||||||
getTemplate: function() { return templates.genericBlockTools; },
|
regions: {
|
||||||
events: {
|
toolsRegion: '> .mailpoet_tools',
|
||||||
"click .mailpoet_edit_block": "changeSettings",
|
},
|
||||||
"click .mailpoet_delete_block_activate": "showDeletionConfirmation",
|
modelEvents: {
|
||||||
"click .mailpoet_delete_block_cancel": "hideDeletionConfirmation",
|
'change': 'render',
|
||||||
"click .mailpoet_delete_block_confirm": "deleteBlock",
|
},
|
||||||
},
|
events: {
|
||||||
// Markers of whether these particular tools will be used for this instance
|
"mouseenter": "showTools",
|
||||||
tools: {
|
"mouseleave": "hideTools",
|
||||||
settings: true,
|
},
|
||||||
delete: true,
|
behaviors: {
|
||||||
move: true,
|
DraggableBehavior: {
|
||||||
},
|
cloneOriginal: true,
|
||||||
getSettingsView: function() { return Module.BlockSettingsView; },
|
hideOriginal: true,
|
||||||
initialize: function(options) {
|
onDrop: function(options) {
|
||||||
options = options || {};
|
// After a clone of model has been dropped, cleanup
|
||||||
if (!_.isUndefined(options.tools)) {
|
// and destroy self
|
||||||
// Make a new block specific tool config object
|
options.dragBehavior.view.model.destroy();
|
||||||
this.tools = jQuery.extend({}, this.tools, options.tools || {});
|
},
|
||||||
}
|
onDragSubstituteBy: function(behavior) {
|
||||||
|
var WidgetView, node;
|
||||||
|
// When block is being dragged, display the widget icon instead.
|
||||||
|
// This will create an instance of block's widget view and
|
||||||
|
// use it's rendered DOM element instead of the content block
|
||||||
|
if (_.isFunction(behavior.view.onDragSubstituteBy)) {
|
||||||
|
WidgetView = new (behavior.view.onDragSubstituteBy())();
|
||||||
|
WidgetView.render();
|
||||||
|
node = WidgetView.$el.get(0).cloneNode(true);
|
||||||
|
WidgetView.destroy();
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
templateHelpers: function() {
|
||||||
|
return {
|
||||||
|
model: this.model.toJSON(),
|
||||||
|
viewCid: this.cid,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
constructor: function() {
|
||||||
|
AugmentedView.apply(this, arguments);
|
||||||
|
this.$el.addClass('mailpoet_editor_view_' + this.cid);
|
||||||
|
},
|
||||||
|
showTools: function(_event) {
|
||||||
|
if (!this.showingToolsDisabled) {
|
||||||
|
this.$('> .mailpoet_tools').show();
|
||||||
|
this.toolsView.triggerMethod('showTools');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hideTools: function(e) {
|
||||||
|
this.$('> .mailpoet_tools').hide();
|
||||||
|
this.toolsView.triggerMethod('hideTools');
|
||||||
|
},
|
||||||
|
enableShowingTools: function() {
|
||||||
|
this.showingToolsDisabled = false;
|
||||||
|
},
|
||||||
|
disableShowingTools: function() {
|
||||||
|
this.showingToolsDisabled = true;
|
||||||
|
this.hideTools();
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Defines drop behavior of BlockView instance
|
||||||
|
*/
|
||||||
|
getDropFunc: function() {
|
||||||
|
var that = this;
|
||||||
|
return function() {
|
||||||
|
var newModel = that.model.clone();
|
||||||
|
//that.model.destroy();
|
||||||
|
return newModel;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// Automatically cancel deletion
|
Module.BlockToolsView = AugmentedView.extend({
|
||||||
this.on('hideTools', this.hideDeletionConfirmation, this);
|
getTemplate: function() { return templates.genericBlockTools; },
|
||||||
},
|
events: {
|
||||||
templateHelpers: function() {
|
"click .mailpoet_edit_block": "changeSettings",
|
||||||
return {
|
"click .mailpoet_delete_block_activate": "showDeletionConfirmation",
|
||||||
model: this.model.toJSON(),
|
"click .mailpoet_delete_block_cancel": "hideDeletionConfirmation",
|
||||||
viewCid: this.cid,
|
"click .mailpoet_delete_block_confirm": "deleteBlock",
|
||||||
tools: this.tools,
|
},
|
||||||
};
|
// Markers of whether these particular tools will be used for this instance
|
||||||
},
|
tools: {
|
||||||
changeSettings: function() {
|
settings: true,
|
||||||
var ViewType = this.getSettingsView();
|
delete: true,
|
||||||
(new ViewType({ model: this.model })).render();
|
move: true,
|
||||||
},
|
},
|
||||||
showDeletionConfirmation: function() {
|
getSettingsView: function() { return Module.BlockSettingsView; },
|
||||||
this.$('.mailpoet_delete_block').addClass('mailpoet_delete_block_activated');
|
initialize: function(options) {
|
||||||
},
|
options = options || {};
|
||||||
hideDeletionConfirmation: function() {
|
if (!_.isUndefined(options.tools)) {
|
||||||
this.$('.mailpoet_delete_block').removeClass('mailpoet_delete_block_activated');
|
// Make a new block specific tool config object
|
||||||
},
|
this.tools = jQuery.extend({}, this.tools, options.tools || {});
|
||||||
deleteBlock: function(event) {
|
}
|
||||||
event.preventDefault();
|
|
||||||
this.model.destroy();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.BlockSettingsView = Marionette.LayoutView.extend({
|
// Automatically cancel deletion
|
||||||
className: 'mailpoet_editor_settings',
|
this.on('hideTools', this.hideDeletionConfirmation, this);
|
||||||
initialize: function() {
|
},
|
||||||
var that = this;
|
templateHelpers: function() {
|
||||||
|
return {
|
||||||
|
model: this.model.toJSON(),
|
||||||
|
viewCid: this.cid,
|
||||||
|
tools: this.tools,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
changeSettings: function() {
|
||||||
|
var ViewType = this.getSettingsView();
|
||||||
|
(new ViewType({ model: this.model })).render();
|
||||||
|
},
|
||||||
|
showDeletionConfirmation: function() {
|
||||||
|
this.$('.mailpoet_delete_block').addClass('mailpoet_delete_block_activated');
|
||||||
|
},
|
||||||
|
hideDeletionConfirmation: function() {
|
||||||
|
this.$('.mailpoet_delete_block').removeClass('mailpoet_delete_block_activated');
|
||||||
|
},
|
||||||
|
deleteBlock: function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.model.destroy();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
MailPoet.Modal.panel({
|
Module.BlockSettingsView = Marionette.LayoutView.extend({
|
||||||
element: this.$el,
|
className: 'mailpoet_editor_settings',
|
||||||
template: '',
|
initialize: function() {
|
||||||
position: 'right',
|
var that = this;
|
||||||
width: App.getConfig().get('sidepanelWidth'),
|
|
||||||
onCancel: function() {
|
MailPoet.Modal.panel({
|
||||||
that.destroy();
|
element: this.$el,
|
||||||
},
|
template: '',
|
||||||
});
|
position: 'right',
|
||||||
},
|
width: App.getConfig().get('sidepanelWidth'),
|
||||||
close: function(event) {
|
onCancel: function() {
|
||||||
MailPoet.Modal.cancel();
|
that.destroy();
|
||||||
this.destroy();
|
},
|
||||||
},
|
});
|
||||||
changeField: function(field, event) {
|
},
|
||||||
this.model.set(field, jQuery(event.target).val());
|
close: function(event) {
|
||||||
},
|
MailPoet.Modal.cancel();
|
||||||
changePixelField: function(field, event) {
|
this.destroy();
|
||||||
this.changeFieldWithSuffix(field, event, 'px');
|
},
|
||||||
},
|
changeField: function(field, event) {
|
||||||
changeFieldWithSuffix: function(field, event, suffix) {
|
this.model.set(field, jQuery(event.target).val());
|
||||||
this.model.set(field, jQuery(event.target).val() + suffix);
|
},
|
||||||
},
|
changePixelField: function(field, event) {
|
||||||
changeBoolField: function(field, event) {
|
this.changeFieldWithSuffix(field, event, 'px');
|
||||||
this.model.set(field, (jQuery(event.target).val() === 'true') ? true : false);
|
},
|
||||||
},
|
changeFieldWithSuffix: function(field, event, suffix) {
|
||||||
changeColorField: function(field, event) {
|
this.model.set(field, jQuery(event.target).val() + suffix);
|
||||||
var value = jQuery(event.target).val();
|
},
|
||||||
if (value === '') {
|
changeBoolField: function(field, event) {
|
||||||
value = 'transparent';
|
this.model.set(field, (jQuery(event.target).val() === 'true') ? true : false);
|
||||||
}
|
},
|
||||||
this.model.set(field, value);
|
changeColorField: function(field, event) {
|
||||||
},
|
var value = jQuery(event.target).val();
|
||||||
});
|
if (value === '') {
|
||||||
|
value = 'transparent';
|
||||||
|
}
|
||||||
|
this.model.set(field, value);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Module.WidgetView = Marionette.ItemView.extend({
|
||||||
|
className: 'mailpoet_widget mailpoet_droppable_block mailpoet_droppable_widget',
|
||||||
|
behaviors: {
|
||||||
|
DraggableBehavior: {
|
||||||
|
drop: function() {
|
||||||
|
throw "Unsupported operation";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
Module.WidgetView = Marionette.ItemView.extend({
|
|
||||||
className: 'mailpoet_widget mailpoet_droppable_block mailpoet_droppable_widget',
|
|
||||||
behaviors: {
|
|
||||||
DraggableBehavior: {
|
|
||||||
drop: function() {
|
|
||||||
throw "Unsupported operation";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,153 +1,163 @@
|
|||||||
/**
|
/**
|
||||||
* Button content block
|
* Button content block
|
||||||
*/
|
*/
|
||||||
EditorApplication.module("blocks.button", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/blocks/button', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
'mailpoet',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette, MailPoet) {
|
||||||
|
|
||||||
var base = App.module('blocks.base');
|
EditorApplication.module("blocks.button", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
Module.ButtonBlockModel = base.BlockModel.extend({
|
var base = App.module('blocks.base');
|
||||||
defaults: function() {
|
|
||||||
return this._getDefaults({
|
|
||||||
type: 'button',
|
|
||||||
text: 'Button',
|
|
||||||
url: 'http://google.com',
|
|
||||||
styles: {
|
|
||||||
block: {
|
|
||||||
backgroundColor: '#ff0000',
|
|
||||||
borderColor: '#cccccc',
|
|
||||||
borderWidth: '1px',
|
|
||||||
borderRadius: '4px',
|
|
||||||
borderStyle: 'solid',
|
|
||||||
width: '200px',
|
|
||||||
lineHeight: '40px',
|
|
||||||
fontColor: '#000000',
|
|
||||||
fontFamily: 'Arial',
|
|
||||||
fontSize: '16px',
|
|
||||||
textAlign: 'center',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, EditorApplication.getConfig().get('blockDefaults.button'));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.ButtonBlockView = base.BlockView.extend({
|
Module.ButtonBlockModel = base.BlockModel.extend({
|
||||||
className: "mailpoet_block mailpoet_button_block mailpoet_droppable_block",
|
defaults: function() {
|
||||||
getTemplate: function() { return templates.buttonBlock; },
|
return this._getDefaults({
|
||||||
modelEvents: {
|
type: 'button',
|
||||||
'change': 'render',
|
text: 'Button',
|
||||||
},
|
url: 'http://google.com',
|
||||||
onDragSubstituteBy: function() { return Module.ButtonWidgetView; },
|
styles: {
|
||||||
initialize: function() {
|
block: {
|
||||||
base.BlockView.prototype.initialize.apply(this, arguments);
|
backgroundColor: '#ff0000',
|
||||||
var that = this;
|
borderColor: '#cccccc',
|
||||||
|
borderWidth: '1px',
|
||||||
|
borderRadius: '4px',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
width: '200px',
|
||||||
|
lineHeight: '40px',
|
||||||
|
fontColor: '#000000',
|
||||||
|
fontFamily: 'Arial',
|
||||||
|
fontSize: '16px',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, EditorApplication.getConfig().get('blockDefaults.button'));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// Listen for attempts to change all dividers in one go
|
Module.ButtonBlockView = base.BlockView.extend({
|
||||||
this._replaceButtonStylesHandler = function(data) { that.model.set(data); };
|
className: "mailpoet_block mailpoet_button_block mailpoet_droppable_block",
|
||||||
App.getChannel().on('replaceAllButtonStyles', this._replaceButtonStylesHandler);
|
getTemplate: function() { return templates.buttonBlock; },
|
||||||
},
|
modelEvents: {
|
||||||
onRender: function() {
|
'change': 'render',
|
||||||
this.toolsView = new Module.ButtonBlockToolsView({ model: this.model });
|
},
|
||||||
this.toolsRegion.show(this.toolsView);
|
onDragSubstituteBy: function() { return Module.ButtonWidgetView; },
|
||||||
},
|
initialize: function() {
|
||||||
});
|
base.BlockView.prototype.initialize.apply(this, arguments);
|
||||||
|
var that = this;
|
||||||
|
|
||||||
Module.ButtonBlockToolsView = base.BlockToolsView.extend({
|
// Listen for attempts to change all dividers in one go
|
||||||
getSettingsView: function() { return Module.ButtonBlockSettingsView; },
|
this._replaceButtonStylesHandler = function(data) { that.model.set(data); };
|
||||||
});
|
App.getChannel().on('replaceAllButtonStyles', this._replaceButtonStylesHandler);
|
||||||
|
},
|
||||||
|
onRender: function() {
|
||||||
|
this.toolsView = new Module.ButtonBlockToolsView({ model: this.model });
|
||||||
|
this.toolsRegion.show(this.toolsView);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Module.ButtonBlockSettingsView = base.BlockSettingsView.extend({
|
Module.ButtonBlockToolsView = base.BlockToolsView.extend({
|
||||||
getTemplate: function() { return templates.buttonBlockSettings; },
|
getSettingsView: function() { return Module.ButtonBlockSettingsView; },
|
||||||
events: function() {
|
});
|
||||||
return {
|
|
||||||
"keyup .mailpoet_field_button_text": _.partial(this.changeField, "text"),
|
|
||||||
"keyup .mailpoet_field_button_url": _.partial(this.changeField, "url"),
|
|
||||||
"change .mailpoet_field_button_alignment": _.partial(this.changeField, "styles.block.textAlign"),
|
|
||||||
"change .mailpoet_field_button_font_color": _.partial(this.changeColorField, "styles.block.fontColor"),
|
|
||||||
"change .mailpoet_field_button_font_family": _.partial(this.changeField, "styles.block.fontFamily"),
|
|
||||||
"change .mailpoet_field_button_font_size": _.partial(this.changeField, "styles.block.fontSize"),
|
|
||||||
"change .mailpoet_field_button_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
|
|
||||||
"change .mailpoet_field_button_border_color": _.partial(this.changeColorField, "styles.block.borderColor"),
|
|
||||||
|
|
||||||
"input .mailpoet_field_button_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
Module.ButtonBlockSettingsView = base.BlockSettingsView.extend({
|
||||||
"change .mailpoet_field_button_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
getTemplate: function() { return templates.buttonBlockSettings; },
|
||||||
"change .mailpoet_field_button_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
events: function() {
|
||||||
"keyup .mailpoet_field_button_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
return {
|
||||||
|
"keyup .mailpoet_field_button_text": _.partial(this.changeField, "text"),
|
||||||
|
"keyup .mailpoet_field_button_url": _.partial(this.changeField, "url"),
|
||||||
|
"change .mailpoet_field_button_alignment": _.partial(this.changeField, "styles.block.textAlign"),
|
||||||
|
"change .mailpoet_field_button_font_color": _.partial(this.changeColorField, "styles.block.fontColor"),
|
||||||
|
"change .mailpoet_field_button_font_family": _.partial(this.changeField, "styles.block.fontFamily"),
|
||||||
|
"change .mailpoet_field_button_font_size": _.partial(this.changeField, "styles.block.fontSize"),
|
||||||
|
"change .mailpoet_field_button_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
|
||||||
|
"change .mailpoet_field_button_border_color": _.partial(this.changeColorField, "styles.block.borderColor"),
|
||||||
|
|
||||||
"input .mailpoet_field_button_border_radius": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius_input', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
"input .mailpoet_field_button_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
||||||
"change .mailpoet_field_button_border_radius": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius_input', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
"change .mailpoet_field_button_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
||||||
"change .mailpoet_field_button_border_radius_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
"change .mailpoet_field_button_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
||||||
"keyup .mailpoet_field_button_border_radius_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
"keyup .mailpoet_field_button_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
||||||
|
|
||||||
"input .mailpoet_field_button_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width_input', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
"input .mailpoet_field_button_border_radius": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius_input', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
||||||
"change .mailpoet_field_button_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width_input', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
"change .mailpoet_field_button_border_radius": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius_input', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
||||||
"change .mailpoet_field_button_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
"change .mailpoet_field_button_border_radius_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
||||||
"keyup .mailpoet_field_button_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
"keyup .mailpoet_field_button_border_radius_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
||||||
|
|
||||||
"input .mailpoet_field_button_line_height": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height_input', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
"input .mailpoet_field_button_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width_input', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
||||||
"change .mailpoet_field_button_line_height": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height_input', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
"change .mailpoet_field_button_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width_input', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
||||||
"change .mailpoet_field_button_line_height_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
"change .mailpoet_field_button_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
||||||
"keyup .mailpoet_field_button_line_height_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
"keyup .mailpoet_field_button_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
||||||
|
|
||||||
"click .mailpoet_field_button_replace_all_styles": "applyToAll",
|
"input .mailpoet_field_button_line_height": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height_input', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
||||||
"click .mailpoet_done_editing": "close",
|
"change .mailpoet_field_button_line_height": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height_input', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
||||||
};
|
"change .mailpoet_field_button_line_height_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
||||||
},
|
"keyup .mailpoet_field_button_line_height_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
||||||
behaviors: {
|
|
||||||
ColorPickerBehavior: {},
|
|
||||||
},
|
|
||||||
initialize: function(params) {
|
|
||||||
var panelParams = {
|
|
||||||
element: this.$el,
|
|
||||||
template: '',
|
|
||||||
position: 'right',
|
|
||||||
width: App.getConfig().get('sidepanelWidth'),
|
|
||||||
};
|
|
||||||
this.renderOptions = params.renderOptions || {};
|
|
||||||
if (this.renderOptions.displayFormat === 'subpanel') {
|
|
||||||
MailPoet.Modal.subpanel(panelParams);
|
|
||||||
} else {
|
|
||||||
MailPoet.Modal.panel(panelParams);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
templateHelpers: function() {
|
|
||||||
return {
|
|
||||||
model: this.model.toJSON(),
|
|
||||||
availableStyles: App.getAvailableStyles().toJSON(),
|
|
||||||
renderOptions: this.renderOptions,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
applyToAll: function() {
|
|
||||||
App.getChannel().trigger('replaceAllButtonStyles', _.pick(this.model.toJSON(), 'styles', 'type'));
|
|
||||||
},
|
|
||||||
updateValueAndCall: function(fieldToUpdate, callable, event) {
|
|
||||||
this.$(fieldToUpdate).val(jQuery(event.target).val());
|
|
||||||
callable(event);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.ButtonWidgetView = base.WidgetView.extend({
|
"click .mailpoet_field_button_replace_all_styles": "applyToAll",
|
||||||
getTemplate: function() { return templates.buttonInsertion; },
|
"click .mailpoet_done_editing": "close",
|
||||||
behaviors: {
|
};
|
||||||
DraggableBehavior: {
|
},
|
||||||
cloneOriginal: true,
|
behaviors: {
|
||||||
drop: function() {
|
ColorPickerBehavior: {},
|
||||||
return new Module.ButtonBlockModel();
|
},
|
||||||
},
|
initialize: function(params) {
|
||||||
}
|
var panelParams = {
|
||||||
},
|
element: this.$el,
|
||||||
});
|
template: '',
|
||||||
|
position: 'right',
|
||||||
|
width: App.getConfig().get('sidepanelWidth'),
|
||||||
|
};
|
||||||
|
this.renderOptions = params.renderOptions || {};
|
||||||
|
if (this.renderOptions.displayFormat === 'subpanel') {
|
||||||
|
MailPoet.Modal.subpanel(panelParams);
|
||||||
|
} else {
|
||||||
|
MailPoet.Modal.panel(panelParams);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
templateHelpers: function() {
|
||||||
|
return {
|
||||||
|
model: this.model.toJSON(),
|
||||||
|
availableStyles: App.getAvailableStyles().toJSON(),
|
||||||
|
renderOptions: this.renderOptions,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
applyToAll: function() {
|
||||||
|
App.getChannel().trigger('replaceAllButtonStyles', _.pick(this.model.toJSON(), 'styles', 'type'));
|
||||||
|
},
|
||||||
|
updateValueAndCall: function(fieldToUpdate, callable, event) {
|
||||||
|
this.$(fieldToUpdate).val(jQuery(event.target).val());
|
||||||
|
callable(event);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
App.on('before:start', function() {
|
Module.ButtonWidgetView = base.WidgetView.extend({
|
||||||
App.registerBlockType('button', {
|
getTemplate: function() { return templates.buttonInsertion; },
|
||||||
blockModel: Module.ButtonBlockModel,
|
behaviors: {
|
||||||
blockView: Module.ButtonBlockView,
|
DraggableBehavior: {
|
||||||
});
|
cloneOriginal: true,
|
||||||
|
drop: function() {
|
||||||
|
return new Module.ButtonBlockModel();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
App.on('before:start', function() {
|
||||||
|
App.registerBlockType('button', {
|
||||||
|
blockModel: Module.ButtonBlockModel,
|
||||||
|
blockView: Module.ButtonBlockView,
|
||||||
|
});
|
||||||
|
|
||||||
|
App.registerWidget({
|
||||||
|
name: 'button',
|
||||||
|
widgetView: Module.ButtonWidgetView,
|
||||||
|
priority: 92,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.registerWidget({
|
|
||||||
name: 'button',
|
|
||||||
widgetView: Module.ButtonWidgetView,
|
|
||||||
priority: 92,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -3,337 +3,347 @@
|
|||||||
* This is a special kind of block, as it can contain content blocks, as well
|
* This is a special kind of block, as it can contain content blocks, as well
|
||||||
* as other containers.
|
* as other containers.
|
||||||
*/
|
*/
|
||||||
EditorApplication.module("blocks.container", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/blocks/container', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
'mailpoet',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette, MailPoet) {
|
||||||
|
|
||||||
var base = App.module('blocks.base'),
|
EditorApplication.module("blocks.container", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
BlockCollection;
|
"use strict";
|
||||||
|
|
||||||
Module.ContainerBlockModel = base.BlockModel.extend({
|
var base = App.module('blocks.base'),
|
||||||
defaults: function() {
|
BlockCollection;
|
||||||
return this._getDefaults({
|
|
||||||
type: 'container',
|
|
||||||
orientation: 'vertical',
|
|
||||||
styles: {
|
|
||||||
block: {
|
|
||||||
backgroundColor: 'transparent',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
blocks: new BlockCollection(),
|
|
||||||
}, EditorApplication.getConfig().get('blockDefaults.container'));
|
|
||||||
},
|
|
||||||
parse: function(response) {
|
|
||||||
// If container has any blocks - add them to a collection
|
|
||||||
if (response.type === 'container' && _.has(response, 'blocks')) {
|
|
||||||
response.blocks = new BlockCollection(response.blocks, {
|
|
||||||
parse: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
},
|
|
||||||
validate: function() {
|
|
||||||
// Recursively propagate validation checks to blocks in the tree
|
|
||||||
var invalidBlock = this.get('blocks').find(function(block) { return !block.isValid(); });
|
|
||||||
if (invalidBlock) {
|
|
||||||
return invalidBlock.validationError;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
BlockCollection = Backbone.Collection.extend({
|
Module.ContainerBlockModel = base.BlockModel.extend({
|
||||||
model: base.BlockModel,
|
defaults: function() {
|
||||||
initialize: function() {
|
return this._getDefaults({
|
||||||
this.on('add change remove', function() { App.getChannel().trigger('autoSave'); });
|
type: 'container',
|
||||||
},
|
orientation: 'vertical',
|
||||||
parse: function(response) {
|
styles: {
|
||||||
var self = this;
|
block: {
|
||||||
return _.map(response, function(block) {
|
backgroundColor: 'transparent',
|
||||||
var Type = App.getBlockTypeModel(block.type);
|
},
|
||||||
// TODO: If type has no registered model, use a backup one
|
},
|
||||||
return new Type(block, {parse: true});
|
blocks: new BlockCollection(),
|
||||||
});
|
}, EditorApplication.getConfig().get('blockDefaults.container'));
|
||||||
},
|
},
|
||||||
});
|
parse: function(response) {
|
||||||
|
// If container has any blocks - add them to a collection
|
||||||
|
if (response.type === 'container' && _.has(response, 'blocks')) {
|
||||||
|
response.blocks = new BlockCollection(response.blocks, {
|
||||||
|
parse: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
},
|
||||||
|
validate: function() {
|
||||||
|
// Recursively propagate validation checks to blocks in the tree
|
||||||
|
var invalidBlock = this.get('blocks').find(function(block) { return !block.isValid(); });
|
||||||
|
if (invalidBlock) {
|
||||||
|
return invalidBlock.validationError;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Module.ContainerBlockView = Marionette.CompositeView.extend({
|
BlockCollection = Backbone.Collection.extend({
|
||||||
regionClass: Marionette.Region,
|
model: base.BlockModel,
|
||||||
className: 'mailpoet_block mailpoet_container_block mailpoet_droppable_block mailpoet_droppable_layout_block',
|
initialize: function() {
|
||||||
getTemplate: function() { return templates.containerBlock; },
|
this.on('add change remove', function() { App.getChannel().trigger('autoSave'); });
|
||||||
childViewContainer: '> .mailpoet_container',
|
},
|
||||||
getEmptyView: function() { return Module.ContainerBlockEmptyView; },
|
parse: function(response) {
|
||||||
emptyViewOptions: function() { return { renderOptions: this.renderOptions }; },
|
var self = this;
|
||||||
modelEvents: {
|
return _.map(response, function(block) {
|
||||||
'change': 'render'
|
var Type = App.getBlockTypeModel(block.type);
|
||||||
},
|
// TODO: If type has no registered model, use a backup one
|
||||||
events: {
|
return new Type(block, {parse: true});
|
||||||
"mouseenter": "showTools",
|
});
|
||||||
"mouseleave": "hideTools",
|
},
|
||||||
"click .mailpoet_newsletter_layer_selector": "toggleEditingLayer",
|
});
|
||||||
},
|
|
||||||
regions: {
|
|
||||||
toolsRegion: '> .mailpoet_tools',
|
|
||||||
},
|
|
||||||
ui: {
|
|
||||||
tools: '> .mailpoet_tools'
|
|
||||||
},
|
|
||||||
behaviors: {
|
|
||||||
ContainerDropZoneBehavior: {},
|
|
||||||
DraggableBehavior: {
|
|
||||||
cloneOriginal: true,
|
|
||||||
hideOriginal: true,
|
|
||||||
onDrop: function(options) {
|
|
||||||
// After a clone of model has been dropped, cleanup
|
|
||||||
// and destroy self
|
|
||||||
options.dragBehavior.view.model.destroy();
|
|
||||||
},
|
|
||||||
onDragSubstituteBy: function(behavior) {
|
|
||||||
var WidgetView, node;
|
|
||||||
// When block is being dragged, display the widget icon instead.
|
|
||||||
// This will create an instance of block's widget view and
|
|
||||||
// use it's rendered DOM element instead of the content block
|
|
||||||
if (_.isFunction(behavior.view.onDragSubstituteBy)) {
|
|
||||||
WidgetView = new (behavior.view.onDragSubstituteBy())();
|
|
||||||
WidgetView.render();
|
|
||||||
node = WidgetView.$el.get(0).cloneNode(true);
|
|
||||||
WidgetView.destroy();
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
testAttachToInstance: function(model, view) {
|
|
||||||
// Attach Draggable only to layout containers and disable it
|
|
||||||
// for root and column containers.
|
|
||||||
return view.renderOptions.depth === 1;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
onDragSubstituteBy: function() {
|
|
||||||
// For two and three column layouts display their respective widgets,
|
|
||||||
// otherwise always default to one column layout widget
|
|
||||||
if (this.renderOptions.depth === 1) {
|
|
||||||
if (this.model.get('blocks').length === 3) return Module.ThreeColumnContainerWidgetView;
|
|
||||||
if (this.model.get('blocks').length === 2) return Module.TwoColumnContainerWidgetView;
|
|
||||||
}
|
|
||||||
return Module.OneColumnContainerWidgetView;
|
|
||||||
|
|
||||||
},
|
Module.ContainerBlockView = Marionette.CompositeView.extend({
|
||||||
constructor: function() {
|
regionClass: Marionette.Region,
|
||||||
// Set the block collection to be handled by this view as well
|
className: 'mailpoet_block mailpoet_container_block mailpoet_droppable_block mailpoet_droppable_layout_block',
|
||||||
arguments[0].collection = arguments[0].model.get('blocks');
|
getTemplate: function() { return templates.containerBlock; },
|
||||||
Marionette.CompositeView.apply(this, arguments);
|
childViewContainer: '> .mailpoet_container',
|
||||||
this.$el.addClass('mailpoet_editor_view_' + this.cid);
|
getEmptyView: function() { return Module.ContainerBlockEmptyView; },
|
||||||
},
|
emptyViewOptions: function() { return { renderOptions: this.renderOptions }; },
|
||||||
initialize: function(options) {
|
modelEvents: {
|
||||||
this.renderOptions = _.defaults(options.renderOptions || {}, {});
|
'change': 'render'
|
||||||
},
|
},
|
||||||
// Determines which view type should be used for a child
|
events: {
|
||||||
getChildView: function(model) {
|
"mouseenter": "showTools",
|
||||||
// TODO: If type does not have a type registered, use a generic one
|
"mouseleave": "hideTools",
|
||||||
return App.getBlockTypeView(model.get('type'));
|
"click .mailpoet_newsletter_layer_selector": "toggleEditingLayer",
|
||||||
},
|
},
|
||||||
childViewOptions: function() {
|
regions: {
|
||||||
var newRenderOptions = _.clone(this.renderOptions);
|
toolsRegion: '> .mailpoet_tools',
|
||||||
if (newRenderOptions.depth !== undefined) {
|
},
|
||||||
newRenderOptions.depth += 1;
|
ui: {
|
||||||
}
|
tools: '> .mailpoet_tools'
|
||||||
return {
|
},
|
||||||
renderOptions: newRenderOptions
|
behaviors: {
|
||||||
};
|
ContainerDropZoneBehavior: {},
|
||||||
},
|
DraggableBehavior: {
|
||||||
templateHelpers: function() {
|
cloneOriginal: true,
|
||||||
return {
|
hideOriginal: true,
|
||||||
model: this.model.toJSON(),
|
onDrop: function(options) {
|
||||||
viewCid: this.cid,
|
// After a clone of model has been dropped, cleanup
|
||||||
};
|
// and destroy self
|
||||||
},
|
options.dragBehavior.view.model.destroy();
|
||||||
onRender: function() {
|
},
|
||||||
this._rebuildRegions();
|
onDragSubstituteBy: function(behavior) {
|
||||||
this.toolsView = new Module.ContainerBlockToolsView({
|
var WidgetView, node;
|
||||||
model: this.model,
|
// When block is being dragged, display the widget icon instead.
|
||||||
tools: {
|
// This will create an instance of block's widget view and
|
||||||
settings: this.renderOptions.depth > 1,
|
// use it's rendered DOM element instead of the content block
|
||||||
delete: this.renderOptions.depth === 1,
|
if (_.isFunction(behavior.view.onDragSubstituteBy)) {
|
||||||
move: this.renderOptions.depth === 1,
|
WidgetView = new (behavior.view.onDragSubstituteBy())();
|
||||||
layerSelector: this.renderOptions.depth === 1,
|
WidgetView.render();
|
||||||
},
|
node = WidgetView.$el.get(0).cloneNode(true);
|
||||||
});
|
WidgetView.destroy();
|
||||||
this.toolsRegion.show(this.toolsView);
|
return node;
|
||||||
},
|
}
|
||||||
onBeforeDestroy: function() {
|
},
|
||||||
this.regionManager.destroy();
|
testAttachToInstance: function(model, view) {
|
||||||
},
|
// Attach Draggable only to layout containers and disable it
|
||||||
showTools: function() {
|
// for root and column containers.
|
||||||
if (this.renderOptions.depth === 1 && !this.$el.hasClass('mailpoet_container_layer_active')) {
|
return view.renderOptions.depth === 1;
|
||||||
this.$(this.ui.tools).show();
|
},
|
||||||
this.toolsView.triggerMethod('showTools');
|
},
|
||||||
}
|
},
|
||||||
},
|
onDragSubstituteBy: function() {
|
||||||
hideTools: function() {
|
// For two and three column layouts display their respective widgets,
|
||||||
if (this.renderOptions.depth === 1 && !this.$el.hasClass('mailpoet_container_layer_active')) {
|
// otherwise always default to one column layout widget
|
||||||
this.$(this.ui.tools).hide();
|
if (this.renderOptions.depth === 1) {
|
||||||
this.toolsView.triggerMethod('hideTools');
|
if (this.model.get('blocks').length === 3) return Module.ThreeColumnContainerWidgetView;
|
||||||
}
|
if (this.model.get('blocks').length === 2) return Module.TwoColumnContainerWidgetView;
|
||||||
},
|
}
|
||||||
toggleEditingLayer: function(event) {
|
return Module.OneColumnContainerWidgetView;
|
||||||
var that = this,
|
|
||||||
$toggleButton = this.$('> .mailpoet_tools .mailpoet_newsletter_layer_selector'),
|
|
||||||
$overlay = jQuery('.mailpoet_layer_overlay'),
|
|
||||||
$container = this.$('> .mailpoet_container'),
|
|
||||||
enableContainerLayer = function() {
|
|
||||||
that.$el.addClass('mailpoet_container_layer_active');
|
|
||||||
$toggleButton.addClass('mailpoet_container_layer_active');
|
|
||||||
$container.addClass('mailpoet_layer_highlight');
|
|
||||||
$overlay.click(disableContainerLayer);
|
|
||||||
$overlay.show();
|
|
||||||
},
|
|
||||||
disableContainerLayer = function() {
|
|
||||||
that.$el.removeClass('mailpoet_container_layer_active');
|
|
||||||
$toggleButton.removeClass('mailpoet_container_layer_active');
|
|
||||||
$container.removeClass('mailpoet_layer_highlight');
|
|
||||||
$overlay.hide();
|
|
||||||
$overlay.off('click');
|
|
||||||
};
|
|
||||||
if ($toggleButton.hasClass('mailpoet_container_layer_active')) {
|
|
||||||
disableContainerLayer();
|
|
||||||
} else {
|
|
||||||
enableContainerLayer();
|
|
||||||
}
|
|
||||||
event.stopPropagation();
|
|
||||||
},
|
|
||||||
_buildRegions: function(regions) {
|
|
||||||
var that = this;
|
|
||||||
|
|
||||||
var defaults = {
|
},
|
||||||
regionClass: this.getOption('regionClass'),
|
constructor: function() {
|
||||||
parentEl: function() { return that.$el; }
|
// Set the block collection to be handled by this view as well
|
||||||
};
|
arguments[0].collection = arguments[0].model.get('blocks');
|
||||||
|
Marionette.CompositeView.apply(this, arguments);
|
||||||
|
this.$el.addClass('mailpoet_editor_view_' + this.cid);
|
||||||
|
},
|
||||||
|
initialize: function(options) {
|
||||||
|
this.renderOptions = _.defaults(options.renderOptions || {}, {});
|
||||||
|
},
|
||||||
|
// Determines which view type should be used for a child
|
||||||
|
getChildView: function(model) {
|
||||||
|
// TODO: If type does not have a type registered, use a generic one
|
||||||
|
return App.getBlockTypeView(model.get('type'));
|
||||||
|
},
|
||||||
|
childViewOptions: function() {
|
||||||
|
var newRenderOptions = _.clone(this.renderOptions);
|
||||||
|
if (newRenderOptions.depth !== undefined) {
|
||||||
|
newRenderOptions.depth += 1;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
renderOptions: newRenderOptions
|
||||||
|
};
|
||||||
|
},
|
||||||
|
templateHelpers: function() {
|
||||||
|
return {
|
||||||
|
model: this.model.toJSON(),
|
||||||
|
viewCid: this.cid,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onRender: function() {
|
||||||
|
this._rebuildRegions();
|
||||||
|
this.toolsView = new Module.ContainerBlockToolsView({
|
||||||
|
model: this.model,
|
||||||
|
tools: {
|
||||||
|
settings: this.renderOptions.depth > 1,
|
||||||
|
delete: this.renderOptions.depth === 1,
|
||||||
|
move: this.renderOptions.depth === 1,
|
||||||
|
layerSelector: this.renderOptions.depth === 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.toolsRegion.show(this.toolsView);
|
||||||
|
},
|
||||||
|
onBeforeDestroy: function() {
|
||||||
|
this.regionManager.destroy();
|
||||||
|
},
|
||||||
|
showTools: function() {
|
||||||
|
if (this.renderOptions.depth === 1 && !this.$el.hasClass('mailpoet_container_layer_active')) {
|
||||||
|
this.$(this.ui.tools).show();
|
||||||
|
this.toolsView.triggerMethod('showTools');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hideTools: function() {
|
||||||
|
if (this.renderOptions.depth === 1 && !this.$el.hasClass('mailpoet_container_layer_active')) {
|
||||||
|
this.$(this.ui.tools).hide();
|
||||||
|
this.toolsView.triggerMethod('hideTools');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggleEditingLayer: function(event) {
|
||||||
|
var that = this,
|
||||||
|
$toggleButton = this.$('> .mailpoet_tools .mailpoet_newsletter_layer_selector'),
|
||||||
|
$overlay = jQuery('.mailpoet_layer_overlay'),
|
||||||
|
$container = this.$('> .mailpoet_container'),
|
||||||
|
enableContainerLayer = function() {
|
||||||
|
that.$el.addClass('mailpoet_container_layer_active');
|
||||||
|
$toggleButton.addClass('mailpoet_container_layer_active');
|
||||||
|
$container.addClass('mailpoet_layer_highlight');
|
||||||
|
$overlay.click(disableContainerLayer);
|
||||||
|
$overlay.show();
|
||||||
|
},
|
||||||
|
disableContainerLayer = function() {
|
||||||
|
that.$el.removeClass('mailpoet_container_layer_active');
|
||||||
|
$toggleButton.removeClass('mailpoet_container_layer_active');
|
||||||
|
$container.removeClass('mailpoet_layer_highlight');
|
||||||
|
$overlay.hide();
|
||||||
|
$overlay.off('click');
|
||||||
|
};
|
||||||
|
if ($toggleButton.hasClass('mailpoet_container_layer_active')) {
|
||||||
|
disableContainerLayer();
|
||||||
|
} else {
|
||||||
|
enableContainerLayer();
|
||||||
|
}
|
||||||
|
event.stopPropagation();
|
||||||
|
},
|
||||||
|
_buildRegions: function(regions) {
|
||||||
|
var that = this;
|
||||||
|
|
||||||
return this.regionManager.addRegions(regions, defaults);
|
var defaults = {
|
||||||
},
|
regionClass: this.getOption('regionClass'),
|
||||||
_rebuildRegions: function() {
|
parentEl: function() { return that.$el; }
|
||||||
if (this.regionManager === undefined) {
|
};
|
||||||
this.regionManager = new Backbone.Marionette.RegionManager();
|
|
||||||
}
|
|
||||||
this.regionManager.destroy();
|
|
||||||
_.extend(this, this._buildRegions(this.regions));
|
|
||||||
},
|
|
||||||
getDropFunc: function() {
|
|
||||||
var that = this;
|
|
||||||
return function() {
|
|
||||||
var newModel = that.model.clone();
|
|
||||||
that.model.destroy();
|
|
||||||
return newModel;
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.ContainerBlockEmptyView = Marionette.ItemView.extend({
|
return this.regionManager.addRegions(regions, defaults);
|
||||||
getTemplate: function() { return templates.containerEmpty; },
|
},
|
||||||
initialize: function(options) {
|
_rebuildRegions: function() {
|
||||||
this.renderOptions = _.defaults(options.renderOptions || {}, {});
|
if (this.regionManager === undefined) {
|
||||||
},
|
this.regionManager = new Backbone.Marionette.RegionManager();
|
||||||
templateHelpers: function() {
|
}
|
||||||
return {
|
this.regionManager.destroy();
|
||||||
isRoot: this.renderOptions.depth === 0,
|
_.extend(this, this._buildRegions(this.regions));
|
||||||
};
|
},
|
||||||
},
|
getDropFunc: function() {
|
||||||
});
|
var that = this;
|
||||||
|
return function() {
|
||||||
|
var newModel = that.model.clone();
|
||||||
|
that.model.destroy();
|
||||||
|
return newModel;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Module.ContainerBlockToolsView = base.BlockToolsView.extend({
|
Module.ContainerBlockEmptyView = Marionette.ItemView.extend({
|
||||||
getSettingsView: function() { return Module.ContainerBlockSettingsView; },
|
getTemplate: function() { return templates.containerEmpty; },
|
||||||
});
|
initialize: function(options) {
|
||||||
|
this.renderOptions = _.defaults(options.renderOptions || {}, {});
|
||||||
|
},
|
||||||
|
templateHelpers: function() {
|
||||||
|
return {
|
||||||
|
isRoot: this.renderOptions.depth === 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Module.ContainerBlockSettingsView = base.BlockSettingsView.extend({
|
Module.ContainerBlockToolsView = base.BlockToolsView.extend({
|
||||||
getTemplate: function() { return templates.containerBlockSettings; },
|
getSettingsView: function() { return Module.ContainerBlockSettingsView; },
|
||||||
events: function() {
|
});
|
||||||
return {
|
|
||||||
"change .mailpoet_field_container_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
|
|
||||||
"click .mailpoet_done_editing": "close",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
behaviors: {
|
|
||||||
ColorPickerBehavior: {},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.OneColumnContainerWidgetView = base.WidgetView.extend({
|
Module.ContainerBlockSettingsView = base.BlockSettingsView.extend({
|
||||||
className: base.WidgetView.prototype.className + ' mailpoet_droppable_layout_block',
|
getTemplate: function() { return templates.containerBlockSettings; },
|
||||||
getTemplate: function() { return templates.oneColumnLayoutInsertion; },
|
events: function() {
|
||||||
behaviors: {
|
return {
|
||||||
DraggableBehavior: {
|
"change .mailpoet_field_container_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
|
||||||
cloneOriginal: true,
|
"click .mailpoet_done_editing": "close",
|
||||||
drop: function() {
|
};
|
||||||
return new Module.ContainerBlockModel({
|
},
|
||||||
orientation: 'horizontal',
|
behaviors: {
|
||||||
blocks: [
|
ColorPickerBehavior: {},
|
||||||
new Module.ContainerBlockModel(),
|
},
|
||||||
]
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.TwoColumnContainerWidgetView = base.WidgetView.extend({
|
Module.OneColumnContainerWidgetView = base.WidgetView.extend({
|
||||||
className: base.WidgetView.prototype.className + ' mailpoet_droppable_layout_block',
|
className: base.WidgetView.prototype.className + ' mailpoet_droppable_layout_block',
|
||||||
getTemplate: function() { return templates.twoColumnLayoutInsertion; },
|
getTemplate: function() { return templates.oneColumnLayoutInsertion; },
|
||||||
behaviors: {
|
behaviors: {
|
||||||
DraggableBehavior: {
|
DraggableBehavior: {
|
||||||
cloneOriginal: true,
|
cloneOriginal: true,
|
||||||
drop: function() {
|
drop: function() {
|
||||||
return new Module.ContainerBlockModel({
|
return new Module.ContainerBlockModel({
|
||||||
orientation: 'horizontal',
|
orientation: 'horizontal',
|
||||||
blocks: [
|
blocks: [
|
||||||
new Module.ContainerBlockModel(),
|
new Module.ContainerBlockModel(),
|
||||||
new Module.ContainerBlockModel(),
|
]
|
||||||
]
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
Module.ThreeColumnContainerWidgetView = base.WidgetView.extend({
|
Module.TwoColumnContainerWidgetView = base.WidgetView.extend({
|
||||||
className: base.WidgetView.prototype.className + ' mailpoet_droppable_layout_block',
|
className: base.WidgetView.prototype.className + ' mailpoet_droppable_layout_block',
|
||||||
getTemplate: function() { return templates.threeColumnLayoutInsertion; },
|
getTemplate: function() { return templates.twoColumnLayoutInsertion; },
|
||||||
behaviors: {
|
behaviors: {
|
||||||
DraggableBehavior: {
|
DraggableBehavior: {
|
||||||
cloneOriginal: true,
|
cloneOriginal: true,
|
||||||
drop: function() {
|
drop: function() {
|
||||||
return new Module.ContainerBlockModel({
|
return new Module.ContainerBlockModel({
|
||||||
orientation: 'horizontal',
|
orientation: 'horizontal',
|
||||||
blocks: [
|
blocks: [
|
||||||
new Module.ContainerBlockModel(),
|
new Module.ContainerBlockModel(),
|
||||||
new Module.ContainerBlockModel(),
|
new Module.ContainerBlockModel(),
|
||||||
new Module.ContainerBlockModel(),
|
]
|
||||||
]
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
App.on('before:start', function() {
|
Module.ThreeColumnContainerWidgetView = base.WidgetView.extend({
|
||||||
App.registerBlockType('container', {
|
className: base.WidgetView.prototype.className + ' mailpoet_droppable_layout_block',
|
||||||
blockModel: Module.ContainerBlockModel,
|
getTemplate: function() { return templates.threeColumnLayoutInsertion; },
|
||||||
blockView: Module.ContainerBlockView,
|
behaviors: {
|
||||||
});
|
DraggableBehavior: {
|
||||||
|
cloneOriginal: true,
|
||||||
|
drop: function() {
|
||||||
|
return new Module.ContainerBlockModel({
|
||||||
|
orientation: 'horizontal',
|
||||||
|
blocks: [
|
||||||
|
new Module.ContainerBlockModel(),
|
||||||
|
new Module.ContainerBlockModel(),
|
||||||
|
new Module.ContainerBlockModel(),
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
App.registerLayoutWidget({
|
App.on('before:start', function() {
|
||||||
name: 'oneColumnLayout',
|
App.registerBlockType('container', {
|
||||||
priority: 100,
|
blockModel: Module.ContainerBlockModel,
|
||||||
widgetView: Module.OneColumnContainerWidgetView,
|
blockView: Module.ContainerBlockView,
|
||||||
});
|
});
|
||||||
|
|
||||||
App.registerLayoutWidget({
|
App.registerLayoutWidget({
|
||||||
name: 'twoColumnLayout',
|
name: 'oneColumnLayout',
|
||||||
priority: 100,
|
priority: 100,
|
||||||
widgetView: Module.TwoColumnContainerWidgetView,
|
widgetView: Module.OneColumnContainerWidgetView,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
App.registerLayoutWidget({
|
||||||
|
name: 'twoColumnLayout',
|
||||||
|
priority: 100,
|
||||||
|
widgetView: Module.TwoColumnContainerWidgetView,
|
||||||
|
});
|
||||||
|
|
||||||
|
App.registerLayoutWidget({
|
||||||
|
name: 'threeColumnLayout',
|
||||||
|
priority: 100,
|
||||||
|
widgetView: Module.ThreeColumnContainerWidgetView,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.registerLayoutWidget({
|
|
||||||
name: 'threeColumnLayout',
|
|
||||||
priority: 100,
|
|
||||||
widgetView: Module.ThreeColumnContainerWidgetView,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,164 +1,174 @@
|
|||||||
/**
|
/**
|
||||||
* Divider content block
|
* Divider content block
|
||||||
*/
|
*/
|
||||||
EditorApplication.module("blocks.divider", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/blocks/divider', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
'mailpoet',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette, MailPoet) {
|
||||||
|
|
||||||
var base = App.module('blocks.base');
|
EditorApplication.module("blocks.divider", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
Module.DividerBlockModel = base.BlockModel.extend({
|
var base = App.module('blocks.base');
|
||||||
defaults: function() {
|
|
||||||
return this._getDefaults({
|
|
||||||
type: 'divider',
|
|
||||||
styles: {
|
|
||||||
block: {
|
|
||||||
backgroundColor: 'transparent',
|
|
||||||
padding: '12px',
|
|
||||||
borderStyle: 'solid',
|
|
||||||
borderWidth: '1px',
|
|
||||||
borderColor: '#000000',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, EditorApplication.getConfig().get('blockDefaults.divider'));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.DividerBlockView = base.BlockView.extend({
|
Module.DividerBlockModel = base.BlockModel.extend({
|
||||||
className: "mailpoet_block mailpoet_divider_block mailpoet_droppable_block",
|
defaults: function() {
|
||||||
getTemplate: function() { return templates.dividerBlock; },
|
return this._getDefaults({
|
||||||
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'),
|
type: 'divider',
|
||||||
behaviors: _.defaults({
|
styles: {
|
||||||
ResizableBehavior: {
|
block: {
|
||||||
elementSelector: '.mailpoet_content',
|
backgroundColor: 'transparent',
|
||||||
resizeHandleSelector: '.mailpoet_resize_handle',
|
padding: '12px',
|
||||||
transformationFunction: function(y) { return y / 2; },
|
borderStyle: 'solid',
|
||||||
minLength: 0, // TODO: Move this number to editor configuration
|
borderWidth: '1px',
|
||||||
modelField: 'styles.block.padding',
|
borderColor: '#000000',
|
||||||
},
|
},
|
||||||
}, base.BlockView.prototype.behaviors),
|
},
|
||||||
onDragSubstituteBy: function() { return Module.DividerWidgetView; },
|
}, EditorApplication.getConfig().get('blockDefaults.divider'));
|
||||||
initialize: function() {
|
},
|
||||||
base.BlockView.prototype.initialize.apply(this, arguments);
|
});
|
||||||
var that = this;
|
|
||||||
|
|
||||||
// Listen for attempts to change all dividers in one go
|
Module.DividerBlockView = base.BlockView.extend({
|
||||||
this._replaceDividerHandler = function(data) { that.model.set(data); that.model.trigger('applyToAll'); };
|
className: "mailpoet_block mailpoet_divider_block mailpoet_droppable_block",
|
||||||
App.getChannel().on('replaceAllDividers', this._replaceDividerHandler);
|
getTemplate: function() { return templates.dividerBlock; },
|
||||||
|
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'),
|
||||||
|
behaviors: _.defaults({
|
||||||
|
ResizableBehavior: {
|
||||||
|
elementSelector: '.mailpoet_content',
|
||||||
|
resizeHandleSelector: '.mailpoet_resize_handle',
|
||||||
|
transformationFunction: function(y) { return y / 2; },
|
||||||
|
minLength: 0, // TODO: Move this number to editor configuration
|
||||||
|
modelField: 'styles.block.padding',
|
||||||
|
},
|
||||||
|
}, base.BlockView.prototype.behaviors),
|
||||||
|
onDragSubstituteBy: function() { return Module.DividerWidgetView; },
|
||||||
|
initialize: function() {
|
||||||
|
base.BlockView.prototype.initialize.apply(this, arguments);
|
||||||
|
var that = this;
|
||||||
|
|
||||||
this.listenTo(this.model, 'change:src change:styles.block.backgroundColor change:styles.block.borderStyle change:styles.block.borderWidth change:styles.block.borderColor applyToAll', this.render);
|
// Listen for attempts to change all dividers in one go
|
||||||
this.listenTo(this.model, 'change:styles.block.padding', this.changePadding);
|
this._replaceDividerHandler = function(data) { that.model.set(data); that.model.trigger('applyToAll'); };
|
||||||
},
|
App.getChannel().on('replaceAllDividers', this._replaceDividerHandler);
|
||||||
templateHelpers: function() {
|
|
||||||
return {
|
|
||||||
model: this.model.toJSON(),
|
|
||||||
viewCid: this.cid,
|
|
||||||
totalHeight: parseInt(this.model.get('styles.block.padding'), 10)*2 + parseInt(this.model.get('styles.block.borderWidth')) + 'px',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
onRender: function() {
|
|
||||||
this.toolsView = new Module.DividerBlockToolsView({ model: this.model });
|
|
||||||
this.toolsRegion.show(this.toolsView);
|
|
||||||
},
|
|
||||||
onBeforeDestroy: function() {
|
|
||||||
App.getChannel().off('replaceAllDividers', this._replaceDividerHandler);
|
|
||||||
this.stopListening(this.model);
|
|
||||||
},
|
|
||||||
changePadding: function() {
|
|
||||||
this.$('.mailpoet_content').css('padding-top', this.model.get('styles.block.padding'));
|
|
||||||
this.$('.mailpoet_content').css('padding-bottom', this.model.get('styles.block.padding'));
|
|
||||||
this.$('.mailpoet_resize_handle_text').text(parseInt(this.model.get('styles.block.padding'), 10)*2 + parseInt(this.model.get('styles.block.borderWidth')) + 'px');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.DividerBlockToolsView = base.BlockToolsView.extend({
|
this.listenTo(this.model, 'change:src change:styles.block.backgroundColor change:styles.block.borderStyle change:styles.block.borderWidth change:styles.block.borderColor applyToAll', this.render);
|
||||||
getSettingsView: function() { return Module.DividerBlockSettingsView; },
|
this.listenTo(this.model, 'change:styles.block.padding', this.changePadding);
|
||||||
});
|
},
|
||||||
|
templateHelpers: function() {
|
||||||
|
return {
|
||||||
|
model: this.model.toJSON(),
|
||||||
|
viewCid: this.cid,
|
||||||
|
totalHeight: parseInt(this.model.get('styles.block.padding'), 10)*2 + parseInt(this.model.get('styles.block.borderWidth')) + 'px',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onRender: function() {
|
||||||
|
this.toolsView = new Module.DividerBlockToolsView({ model: this.model });
|
||||||
|
this.toolsRegion.show(this.toolsView);
|
||||||
|
},
|
||||||
|
onBeforeDestroy: function() {
|
||||||
|
App.getChannel().off('replaceAllDividers', this._replaceDividerHandler);
|
||||||
|
this.stopListening(this.model);
|
||||||
|
},
|
||||||
|
changePadding: function() {
|
||||||
|
this.$('.mailpoet_content').css('padding-top', this.model.get('styles.block.padding'));
|
||||||
|
this.$('.mailpoet_content').css('padding-bottom', this.model.get('styles.block.padding'));
|
||||||
|
this.$('.mailpoet_resize_handle_text').text(parseInt(this.model.get('styles.block.padding'), 10)*2 + parseInt(this.model.get('styles.block.borderWidth')) + 'px');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Module.DividerBlockSettingsView = base.BlockSettingsView.extend({
|
Module.DividerBlockToolsView = base.BlockToolsView.extend({
|
||||||
getTemplate: function() { return templates.dividerBlockSettings; },
|
getSettingsView: function() { return Module.DividerBlockSettingsView; },
|
||||||
events: function() {
|
});
|
||||||
return {
|
|
||||||
"click .mailpoet_field_divider_style": 'changeStyle',
|
|
||||||
|
|
||||||
"input .mailpoet_field_divider_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
Module.DividerBlockSettingsView = base.BlockSettingsView.extend({
|
||||||
"change .mailpoet_field_divider_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
getTemplate: function() { return templates.dividerBlockSettings; },
|
||||||
"change .mailpoet_field_divider_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
events: function() {
|
||||||
"keyup .mailpoet_field_divider_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
return {
|
||||||
|
"click .mailpoet_field_divider_style": 'changeStyle',
|
||||||
|
|
||||||
"change .mailpoet_field_divider_border_color": _.partial(this.changeColorField, "styles.block.borderColor"),
|
"input .mailpoet_field_divider_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
||||||
"change .mailpoet_field_divider_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
|
"change .mailpoet_field_divider_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
||||||
"click .mailpoet_button_divider_apply_to_all": "applyToAll",
|
"change .mailpoet_field_divider_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
||||||
"click .mailpoet_done_editing": "close",
|
"keyup .mailpoet_field_divider_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
||||||
};
|
|
||||||
},
|
|
||||||
modelEvents: function() {
|
|
||||||
return {
|
|
||||||
'change:styles.block.borderColor': 'repaintDividerStyleOptions',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
behaviors: {
|
|
||||||
ColorPickerBehavior: {},
|
|
||||||
},
|
|
||||||
initialize: function(params) {
|
|
||||||
var panelParams = {
|
|
||||||
element: this.$el,
|
|
||||||
template: '',
|
|
||||||
position: 'right',
|
|
||||||
width: App.getConfig().get('sidepanelWidth'),
|
|
||||||
};
|
|
||||||
this.renderOptions = params.renderOptions || {};
|
|
||||||
if (this.renderOptions.displayFormat === 'subpanel') {
|
|
||||||
MailPoet.Modal.subpanel(panelParams);
|
|
||||||
} else {
|
|
||||||
MailPoet.Modal.panel(panelParams);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
templateHelpers: function() {
|
|
||||||
return {
|
|
||||||
model: this.model.toJSON(),
|
|
||||||
availableStyles: App.getAvailableStyles().toJSON(),
|
|
||||||
renderOptions: this.renderOptions,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
changeStyle: function(event) {
|
|
||||||
var style = jQuery(event.currentTarget).data('style');
|
|
||||||
this.model.set('styles.block.borderStyle', style);
|
|
||||||
this.$('.mailpoet_field_divider_style').removeClass('mailpoet_active_divider_style');
|
|
||||||
this.$('.mailpoet_field_divider_style[data-style="' + style + '"]').addClass('mailpoet_active_divider_style');
|
|
||||||
},
|
|
||||||
repaintDividerStyleOptions: function() {
|
|
||||||
this.$('.mailpoet_field_divider_style > div').css('border-top-color', this.model.get('styles.block.borderColor'));
|
|
||||||
},
|
|
||||||
applyToAll: function(event) {
|
|
||||||
App.getChannel().trigger('replaceAllDividers', this.model.toJSON());
|
|
||||||
},
|
|
||||||
updateValueAndCall: function(fieldToUpdate, callable, event) {
|
|
||||||
this.$(fieldToUpdate).val(jQuery(event.target).val());
|
|
||||||
callable(event);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.DividerWidgetView = base.WidgetView.extend({
|
"change .mailpoet_field_divider_border_color": _.partial(this.changeColorField, "styles.block.borderColor"),
|
||||||
getTemplate: function() { return templates.dividerInsertion; },
|
"change .mailpoet_field_divider_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
|
||||||
behaviors: {
|
"click .mailpoet_button_divider_apply_to_all": "applyToAll",
|
||||||
DraggableBehavior: {
|
"click .mailpoet_done_editing": "close",
|
||||||
cloneOriginal: true,
|
};
|
||||||
drop: function() {
|
},
|
||||||
return new Module.DividerBlockModel();
|
modelEvents: function() {
|
||||||
},
|
return {
|
||||||
}
|
'change:styles.block.borderColor': 'repaintDividerStyleOptions',
|
||||||
},
|
};
|
||||||
});
|
},
|
||||||
App.on('before:start', function() {
|
behaviors: {
|
||||||
App.registerBlockType('divider', {
|
ColorPickerBehavior: {},
|
||||||
blockModel: Module.DividerBlockModel,
|
},
|
||||||
blockView: Module.DividerBlockView,
|
initialize: function(params) {
|
||||||
});
|
var panelParams = {
|
||||||
|
element: this.$el,
|
||||||
|
template: '',
|
||||||
|
position: 'right',
|
||||||
|
width: App.getConfig().get('sidepanelWidth'),
|
||||||
|
};
|
||||||
|
this.renderOptions = params.renderOptions || {};
|
||||||
|
if (this.renderOptions.displayFormat === 'subpanel') {
|
||||||
|
MailPoet.Modal.subpanel(panelParams);
|
||||||
|
} else {
|
||||||
|
MailPoet.Modal.panel(panelParams);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
templateHelpers: function() {
|
||||||
|
return {
|
||||||
|
model: this.model.toJSON(),
|
||||||
|
availableStyles: App.getAvailableStyles().toJSON(),
|
||||||
|
renderOptions: this.renderOptions,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
changeStyle: function(event) {
|
||||||
|
var style = jQuery(event.currentTarget).data('style');
|
||||||
|
this.model.set('styles.block.borderStyle', style);
|
||||||
|
this.$('.mailpoet_field_divider_style').removeClass('mailpoet_active_divider_style');
|
||||||
|
this.$('.mailpoet_field_divider_style[data-style="' + style + '"]').addClass('mailpoet_active_divider_style');
|
||||||
|
},
|
||||||
|
repaintDividerStyleOptions: function() {
|
||||||
|
this.$('.mailpoet_field_divider_style > div').css('border-top-color', this.model.get('styles.block.borderColor'));
|
||||||
|
},
|
||||||
|
applyToAll: function(event) {
|
||||||
|
App.getChannel().trigger('replaceAllDividers', this.model.toJSON());
|
||||||
|
},
|
||||||
|
updateValueAndCall: function(fieldToUpdate, callable, event) {
|
||||||
|
this.$(fieldToUpdate).val(jQuery(event.target).val());
|
||||||
|
callable(event);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Module.DividerWidgetView = base.WidgetView.extend({
|
||||||
|
getTemplate: function() { return templates.dividerInsertion; },
|
||||||
|
behaviors: {
|
||||||
|
DraggableBehavior: {
|
||||||
|
cloneOriginal: true,
|
||||||
|
drop: function() {
|
||||||
|
return new Module.DividerBlockModel();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
App.on('before:start', function() {
|
||||||
|
App.registerBlockType('divider', {
|
||||||
|
blockModel: Module.DividerBlockModel,
|
||||||
|
blockView: Module.DividerBlockView,
|
||||||
|
});
|
||||||
|
|
||||||
|
App.registerWidget({
|
||||||
|
name: 'divider',
|
||||||
|
widgetView: Module.DividerWidgetView,
|
||||||
|
priority: 93,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.registerWidget({
|
|
||||||
name: 'divider',
|
|
||||||
widgetView: Module.DividerWidgetView,
|
|
||||||
priority: 93,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,138 +1,148 @@
|
|||||||
/**
|
/**
|
||||||
* Footer content block
|
* Footer content block
|
||||||
*/
|
*/
|
||||||
EditorApplication.module("blocks.footer", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/blocks/footer', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
'mailpoet',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette, MailPoet) {
|
||||||
|
|
||||||
var base = App.module('blocks.base');
|
EditorApplication.module("blocks.footer", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
Module.FooterBlockModel = base.BlockModel.extend({
|
var base = App.module('blocks.base');
|
||||||
defaults: function() {
|
|
||||||
return this._getDefaults({
|
|
||||||
type: 'footer',
|
|
||||||
text: '<a href="[unsubscribeUrl]">Unsubscribe</a> | <a href="[manageSubscriptionUrl]">Manage subscription</a><br /><b>Add your postal address here!</b>',
|
|
||||||
styles: {
|
|
||||||
block: {
|
|
||||||
backgroundColor: 'transparent',
|
|
||||||
},
|
|
||||||
text: {
|
|
||||||
fontColor: '#000000',
|
|
||||||
fontFamily: 'Arial',
|
|
||||||
fontSize: '12px',
|
|
||||||
textAlign: 'center',
|
|
||||||
},
|
|
||||||
link: {
|
|
||||||
fontColor: '#0000ff',
|
|
||||||
textDecoration: 'none',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, EditorApplication.getConfig().get('blockDefaults.footer'));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.FooterBlockView = base.BlockView.extend({
|
Module.FooterBlockModel = base.BlockModel.extend({
|
||||||
className: "mailpoet_block mailpoet_footer_block mailpoet_droppable_block",
|
defaults: function() {
|
||||||
getTemplate: function() { return templates.footerBlock; },
|
return this._getDefaults({
|
||||||
modelEvents: {
|
type: 'footer',
|
||||||
'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',
|
text: '<a href="[unsubscribeUrl]">Unsubscribe</a> | <a href="[manageSubscriptionUrl]">Manage subscription</a><br /><b>Add your postal address here!</b>',
|
||||||
},
|
styles: {
|
||||||
onDragSubstituteBy: function() { return Module.FooterWidgetView; },
|
block: {
|
||||||
onRender: function() {
|
backgroundColor: 'transparent',
|
||||||
this.toolsView = new Module.FooterBlockToolsView({ model: this.model });
|
},
|
||||||
this.toolsRegion.show(this.toolsView);
|
text: {
|
||||||
},
|
fontColor: '#000000',
|
||||||
onDomRefresh: function() {
|
fontFamily: 'Arial',
|
||||||
this.attachTextEditor();
|
fontSize: '12px',
|
||||||
},
|
textAlign: 'center',
|
||||||
attachTextEditor: function() {
|
},
|
||||||
var that = this;
|
link: {
|
||||||
this.$('.mailpoet_content').tinymce({
|
fontColor: '#0000ff',
|
||||||
inline: true,
|
textDecoration: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, EditorApplication.getConfig().get('blockDefaults.footer'));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
menubar: false,
|
Module.FooterBlockView = base.BlockView.extend({
|
||||||
toolbar: "bold italic link unlink forecolor mailpoet_custom_fields",
|
className: "mailpoet_block mailpoet_footer_block mailpoet_droppable_block",
|
||||||
|
getTemplate: function() { return templates.footerBlock; },
|
||||||
|
modelEvents: {
|
||||||
|
'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',
|
||||||
|
},
|
||||||
|
onDragSubstituteBy: function() { return Module.FooterWidgetView; },
|
||||||
|
onRender: function() {
|
||||||
|
this.toolsView = new Module.FooterBlockToolsView({ model: this.model });
|
||||||
|
this.toolsRegion.show(this.toolsView);
|
||||||
|
},
|
||||||
|
onDomRefresh: function() {
|
||||||
|
this.attachTextEditor();
|
||||||
|
},
|
||||||
|
attachTextEditor: function() {
|
||||||
|
var that = this;
|
||||||
|
this.$('.mailpoet_content').tinymce({
|
||||||
|
inline: true,
|
||||||
|
|
||||||
valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],strong[class|style],em[class|style],strike,br",
|
menubar: false,
|
||||||
invalid_elements: "script",
|
toolbar: "bold italic link unlink forecolor mailpoet_custom_fields",
|
||||||
style_formats: [
|
|
||||||
{title: 'Paragraph', block: 'p'},
|
|
||||||
],
|
|
||||||
|
|
||||||
plugins: "wplink textcolor mailpoet_custom_fields",
|
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",
|
||||||
|
style_formats: [
|
||||||
|
{title: 'Paragraph', block: 'p'},
|
||||||
|
],
|
||||||
|
|
||||||
setup: function(editor) {
|
plugins: "wplink textcolor mailpoet_custom_fields",
|
||||||
editor.on('change', function(e) {
|
|
||||||
that.model.set('text', editor.getContent());
|
|
||||||
});
|
|
||||||
|
|
||||||
editor.on('focus', function(e) {
|
setup: function(editor) {
|
||||||
that.disableShowingTools();
|
editor.on('change', function(e) {
|
||||||
});
|
that.model.set('text', editor.getContent());
|
||||||
|
});
|
||||||
|
|
||||||
editor.on('blur', function(e) {
|
editor.on('focus', function(e) {
|
||||||
that.enableShowingTools();
|
that.disableShowingTools();
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
mailpoet_custom_fields: App.getConfig().get('customFields').toJSON(),
|
editor.on('blur', function(e) {
|
||||||
mailpoet_custom_fields_window_title: App.getConfig().get('translations.customFieldsWindowTitle'),
|
that.enableShowingTools();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
|
||||||
|
|
||||||
Module.FooterBlockToolsView = base.BlockToolsView.extend({
|
mailpoet_custom_fields: App.getConfig().get('customFields').toJSON(),
|
||||||
getSettingsView: function() { return Module.FooterBlockSettingsView; },
|
mailpoet_custom_fields_window_title: App.getConfig().get('translations.customFieldsWindowTitle'),
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Module.FooterBlockSettingsView = base.BlockSettingsView.extend({
|
Module.FooterBlockToolsView = base.BlockToolsView.extend({
|
||||||
getTemplate: function() { return templates.footerBlockSettings; },
|
getSettingsView: function() { return Module.FooterBlockSettingsView; },
|
||||||
events: function() {
|
});
|
||||||
return {
|
|
||||||
"change .mailpoet_field_footer_text_color": _.partial(this.changeColorField, "styles.text.fontColor"),
|
|
||||||
"change .mailpoet_field_footer_text_font_family": _.partial(this.changeField, "styles.text.fontFamily"),
|
|
||||||
"change .mailpoet_field_footer_text_size": _.partial(this.changeField, "styles.text.fontSize"),
|
|
||||||
"change #mailpoet_field_footer_link_color": _.partial(this.changeColorField, "styles.link.fontColor"),
|
|
||||||
"change #mailpoet_field_footer_link_underline": function(event) {
|
|
||||||
this.model.set('styles.link.textDecoration', (event.target.checked) ? event.target.value : 'none');
|
|
||||||
},
|
|
||||||
"change .mailpoet_field_footer_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
|
|
||||||
"change .mailpoet_field_footer_alignment": _.partial(this.changeField, "styles.text.textAlign"),
|
|
||||||
"click .mailpoet_done_editing": "close",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
behaviors: {
|
|
||||||
ColorPickerBehavior: {},
|
|
||||||
},
|
|
||||||
templateHelpers: function() {
|
|
||||||
return {
|
|
||||||
model: this.model.toJSON(),
|
|
||||||
availableStyles: App.getAvailableStyles().toJSON(),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.FooterWidgetView = base.WidgetView.extend({
|
Module.FooterBlockSettingsView = base.BlockSettingsView.extend({
|
||||||
getTemplate: function() { return templates.footerInsertion; },
|
getTemplate: function() { return templates.footerBlockSettings; },
|
||||||
behaviors: {
|
events: function() {
|
||||||
DraggableBehavior: {
|
return {
|
||||||
cloneOriginal: true,
|
"change .mailpoet_field_footer_text_color": _.partial(this.changeColorField, "styles.text.fontColor"),
|
||||||
drop: function() {
|
"change .mailpoet_field_footer_text_font_family": _.partial(this.changeField, "styles.text.fontFamily"),
|
||||||
return new Module.FooterBlockModel();
|
"change .mailpoet_field_footer_text_size": _.partial(this.changeField, "styles.text.fontSize"),
|
||||||
},
|
"change #mailpoet_field_footer_link_color": _.partial(this.changeColorField, "styles.link.fontColor"),
|
||||||
}
|
"change #mailpoet_field_footer_link_underline": function(event) {
|
||||||
},
|
this.model.set('styles.link.textDecoration', (event.target.checked) ? event.target.value : 'none');
|
||||||
});
|
},
|
||||||
|
"change .mailpoet_field_footer_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
|
||||||
|
"change .mailpoet_field_footer_alignment": _.partial(this.changeField, "styles.text.textAlign"),
|
||||||
|
"click .mailpoet_done_editing": "close",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
behaviors: {
|
||||||
|
ColorPickerBehavior: {},
|
||||||
|
},
|
||||||
|
templateHelpers: function() {
|
||||||
|
return {
|
||||||
|
model: this.model.toJSON(),
|
||||||
|
availableStyles: App.getAvailableStyles().toJSON(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
App.on('before:start', function() {
|
Module.FooterWidgetView = base.WidgetView.extend({
|
||||||
App.registerBlockType('footer', {
|
getTemplate: function() { return templates.footerInsertion; },
|
||||||
blockModel: Module.FooterBlockModel,
|
behaviors: {
|
||||||
blockView: Module.FooterBlockView,
|
DraggableBehavior: {
|
||||||
});
|
cloneOriginal: true,
|
||||||
|
drop: function() {
|
||||||
|
return new Module.FooterBlockModel();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
App.on('before:start', function() {
|
||||||
|
App.registerBlockType('footer', {
|
||||||
|
blockModel: Module.FooterBlockModel,
|
||||||
|
blockView: Module.FooterBlockView,
|
||||||
|
});
|
||||||
|
|
||||||
|
App.registerWidget({
|
||||||
|
name: 'footer',
|
||||||
|
widgetView: Module.FooterWidgetView,
|
||||||
|
priority: 99,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.registerWidget({
|
|
||||||
name: 'footer',
|
|
||||||
widgetView: Module.FooterWidgetView,
|
|
||||||
priority: 99,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,138 +1,148 @@
|
|||||||
/**
|
/**
|
||||||
* Header content block
|
* Header content block
|
||||||
*/
|
*/
|
||||||
EditorApplication.module("blocks.header", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/blocks/header', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
'mailpoet',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette, MailPoet) {
|
||||||
|
|
||||||
var base = App.module('blocks.base');
|
EditorApplication.module("blocks.header", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
Module.HeaderBlockModel = base.BlockModel.extend({
|
var base = App.module('blocks.base');
|
||||||
defaults: function() {
|
|
||||||
return this._getDefaults({
|
|
||||||
type: 'header',
|
|
||||||
text: 'Display problems? <a href="[viewInBrowserUrl]">View it in your browser</a>',
|
|
||||||
styles: {
|
|
||||||
block: {
|
|
||||||
backgroundColor: 'transparent',
|
|
||||||
},
|
|
||||||
text: {
|
|
||||||
fontColor: '#000000',
|
|
||||||
fontFamily: 'Arial',
|
|
||||||
fontSize: '12px',
|
|
||||||
textAlign: 'center',
|
|
||||||
},
|
|
||||||
link: {
|
|
||||||
fontColor: '#0000ff',
|
|
||||||
textDecoration: 'underline',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, EditorApplication.getConfig().get('blockDefaults.header'));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.HeaderBlockView = base.BlockView.extend({
|
Module.HeaderBlockModel = base.BlockModel.extend({
|
||||||
className: "mailpoet_block mailpoet_header_block mailpoet_droppable_block",
|
defaults: function() {
|
||||||
getTemplate: function() { return templates.headerBlock; },
|
return this._getDefaults({
|
||||||
modelEvents: {
|
type: 'header',
|
||||||
'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',
|
text: 'Display problems? <a href="[viewInBrowserUrl]">View it in your browser</a>',
|
||||||
},
|
styles: {
|
||||||
onDragSubstituteBy: function() { return Module.HeaderWidgetView; },
|
block: {
|
||||||
onRender: function() {
|
backgroundColor: 'transparent',
|
||||||
this.toolsView = new Module.HeaderBlockToolsView({ model: this.model });
|
},
|
||||||
this.toolsRegion.show(this.toolsView);
|
text: {
|
||||||
},
|
fontColor: '#000000',
|
||||||
onDomRefresh: function() {
|
fontFamily: 'Arial',
|
||||||
this.attachTextEditor();
|
fontSize: '12px',
|
||||||
},
|
textAlign: 'center',
|
||||||
attachTextEditor: function() {
|
},
|
||||||
var that = this;
|
link: {
|
||||||
this.$('.mailpoet_content').tinymce({
|
fontColor: '#0000ff',
|
||||||
inline: true,
|
textDecoration: 'underline',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, EditorApplication.getConfig().get('blockDefaults.header'));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
menubar: false,
|
Module.HeaderBlockView = base.BlockView.extend({
|
||||||
toolbar: "bold italic link unlink forecolor mailpoet_custom_fields",
|
className: "mailpoet_block mailpoet_header_block mailpoet_droppable_block",
|
||||||
|
getTemplate: function() { return templates.headerBlock; },
|
||||||
|
modelEvents: {
|
||||||
|
'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',
|
||||||
|
},
|
||||||
|
onDragSubstituteBy: function() { return Module.HeaderWidgetView; },
|
||||||
|
onRender: function() {
|
||||||
|
this.toolsView = new Module.HeaderBlockToolsView({ model: this.model });
|
||||||
|
this.toolsRegion.show(this.toolsView);
|
||||||
|
},
|
||||||
|
onDomRefresh: function() {
|
||||||
|
this.attachTextEditor();
|
||||||
|
},
|
||||||
|
attachTextEditor: function() {
|
||||||
|
var that = this;
|
||||||
|
this.$('.mailpoet_content').tinymce({
|
||||||
|
inline: true,
|
||||||
|
|
||||||
valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],strong[class|style],em[class|style],strike,br",
|
menubar: false,
|
||||||
invalid_elements: "script",
|
toolbar: "bold italic link unlink forecolor mailpoet_custom_fields",
|
||||||
style_formats: [
|
|
||||||
{title: 'Paragraph', block: 'p'},
|
|
||||||
],
|
|
||||||
|
|
||||||
plugins: "wplink textcolor mailpoet_custom_fields",
|
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",
|
||||||
|
style_formats: [
|
||||||
|
{title: 'Paragraph', block: 'p'},
|
||||||
|
],
|
||||||
|
|
||||||
setup: function(editor) {
|
plugins: "wplink textcolor mailpoet_custom_fields",
|
||||||
editor.on('change', function(e) {
|
|
||||||
that.model.set('text', editor.getContent());
|
|
||||||
});
|
|
||||||
|
|
||||||
editor.on('focus', function(e) {
|
setup: function(editor) {
|
||||||
that.disableShowingTools();
|
editor.on('change', function(e) {
|
||||||
});
|
that.model.set('text', editor.getContent());
|
||||||
|
});
|
||||||
|
|
||||||
editor.on('blur', function(e) {
|
editor.on('focus', function(e) {
|
||||||
that.enableShowingTools();
|
that.disableShowingTools();
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
mailpoet_custom_fields: App.getConfig().get('customFields').toJSON(),
|
editor.on('blur', function(e) {
|
||||||
mailpoet_custom_fields_window_title: App.getConfig().get('translations.customFieldsWindowTitle'),
|
that.enableShowingTools();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
|
||||||
|
|
||||||
Module.HeaderBlockToolsView = base.BlockToolsView.extend({
|
mailpoet_custom_fields: App.getConfig().get('customFields').toJSON(),
|
||||||
getSettingsView: function() { return Module.HeaderBlockSettingsView; },
|
mailpoet_custom_fields_window_title: App.getConfig().get('translations.customFieldsWindowTitle'),
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Module.HeaderBlockSettingsView = base.BlockSettingsView.extend({
|
Module.HeaderBlockToolsView = base.BlockToolsView.extend({
|
||||||
getTemplate: function() { return templates.headerBlockSettings; },
|
getSettingsView: function() { return Module.HeaderBlockSettingsView; },
|
||||||
events: function() {
|
});
|
||||||
return {
|
|
||||||
"change .mailpoet_field_header_text_color": _.partial(this.changeColorField, "styles.text.fontColor"),
|
|
||||||
"change .mailpoet_field_header_text_font_family": _.partial(this.changeField, "styles.text.fontFamily"),
|
|
||||||
"change .mailpoet_field_header_text_size": _.partial(this.changeField, "styles.text.fontSize"),
|
|
||||||
"change #mailpoet_field_header_link_color": _.partial(this.changeColorField, "styles.link.fontColor"),
|
|
||||||
"change #mailpoet_field_header_link_underline": function(event) {
|
|
||||||
this.model.set('styles.link.textDecoration', (event.target.checked) ? event.target.value : 'none');
|
|
||||||
},
|
|
||||||
"change .mailpoet_field_header_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
|
|
||||||
"change .mailpoet_field_header_alignment": _.partial(this.changeField, "styles.text.textAlign"),
|
|
||||||
"click .mailpoet_done_editing": "close",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
behaviors: {
|
|
||||||
ColorPickerBehavior: {},
|
|
||||||
},
|
|
||||||
templateHelpers: function() {
|
|
||||||
return {
|
|
||||||
model: this.model.toJSON(),
|
|
||||||
availableStyles: App.getAvailableStyles().toJSON(),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.HeaderWidgetView = base.WidgetView.extend({
|
Module.HeaderBlockSettingsView = base.BlockSettingsView.extend({
|
||||||
getTemplate: function() { return templates.headerInsertion; },
|
getTemplate: function() { return templates.headerBlockSettings; },
|
||||||
behaviors: {
|
events: function() {
|
||||||
DraggableBehavior: {
|
return {
|
||||||
cloneOriginal: true,
|
"change .mailpoet_field_header_text_color": _.partial(this.changeColorField, "styles.text.fontColor"),
|
||||||
drop: function() {
|
"change .mailpoet_field_header_text_font_family": _.partial(this.changeField, "styles.text.fontFamily"),
|
||||||
return new Module.HeaderBlockModel();
|
"change .mailpoet_field_header_text_size": _.partial(this.changeField, "styles.text.fontSize"),
|
||||||
},
|
"change #mailpoet_field_header_link_color": _.partial(this.changeColorField, "styles.link.fontColor"),
|
||||||
}
|
"change #mailpoet_field_header_link_underline": function(event) {
|
||||||
},
|
this.model.set('styles.link.textDecoration', (event.target.checked) ? event.target.value : 'none');
|
||||||
});
|
},
|
||||||
|
"change .mailpoet_field_header_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
|
||||||
|
"change .mailpoet_field_header_alignment": _.partial(this.changeField, "styles.text.textAlign"),
|
||||||
|
"click .mailpoet_done_editing": "close",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
behaviors: {
|
||||||
|
ColorPickerBehavior: {},
|
||||||
|
},
|
||||||
|
templateHelpers: function() {
|
||||||
|
return {
|
||||||
|
model: this.model.toJSON(),
|
||||||
|
availableStyles: App.getAvailableStyles().toJSON(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
App.on('before:start', function() {
|
Module.HeaderWidgetView = base.WidgetView.extend({
|
||||||
App.registerBlockType('header', {
|
getTemplate: function() { return templates.headerInsertion; },
|
||||||
blockModel: Module.HeaderBlockModel,
|
behaviors: {
|
||||||
blockView: Module.HeaderBlockView,
|
DraggableBehavior: {
|
||||||
});
|
cloneOriginal: true,
|
||||||
|
drop: function() {
|
||||||
|
return new Module.HeaderBlockModel();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
App.on('before:start', function() {
|
||||||
|
App.registerBlockType('header', {
|
||||||
|
blockModel: Module.HeaderBlockModel,
|
||||||
|
blockView: Module.HeaderBlockView,
|
||||||
|
});
|
||||||
|
|
||||||
|
App.registerWidget({
|
||||||
|
name: 'header',
|
||||||
|
widgetView: Module.HeaderWidgetView,
|
||||||
|
priority: 98,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.registerWidget({
|
|
||||||
name: 'header',
|
|
||||||
widgetView: Module.HeaderWidgetView,
|
|
||||||
priority: 98,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,380 +1,390 @@
|
|||||||
/**
|
/**
|
||||||
* Image content block
|
* Image content block
|
||||||
*/
|
*/
|
||||||
EditorApplication.module("blocks.image", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/blocks/image', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
'mailpoet',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette, MailPoet) {
|
||||||
|
|
||||||
var base = App.module('blocks.base'),
|
EditorApplication.module("blocks.image", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
ImageWidgetView;
|
"use strict";
|
||||||
|
|
||||||
Module.ImageBlockModel = base.BlockModel.extend({
|
var base = App.module('blocks.base'),
|
||||||
defaults: function() {
|
ImageWidgetView;
|
||||||
return this._getDefaults({
|
|
||||||
type: 'image',
|
|
||||||
link: 'http://example.org',
|
|
||||||
src: 'no-image.png',
|
|
||||||
alt: 'An image of...',
|
|
||||||
padded: true, // true | false - Padded or full width
|
|
||||||
width: '64px',
|
|
||||||
height: '64px',
|
|
||||||
styles: {
|
|
||||||
block: {
|
|
||||||
textAlign: 'center',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, EditorApplication.getConfig().get('blockDefaults.image'));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.ImageBlockView = base.BlockView.extend({
|
Module.ImageBlockModel = base.BlockModel.extend({
|
||||||
className: "mailpoet_block mailpoet_image_block mailpoet_droppable_block",
|
defaults: function() {
|
||||||
getTemplate: function() { return templates.imageBlock; },
|
return this._getDefaults({
|
||||||
initialize: function() {
|
type: 'image',
|
||||||
this.on('showSettings', this.showSettings);
|
link: 'http://example.org',
|
||||||
},
|
src: 'no-image.png',
|
||||||
onDragSubstituteBy: function() { return Module.ImageWidgetView; },
|
alt: 'An image of...',
|
||||||
templateHelpers: function() {
|
padded: true, // true | false - Padded or full width
|
||||||
return {
|
width: '64px',
|
||||||
model: this.model.toJSON(),
|
height: '64px',
|
||||||
viewCid: this.cid,
|
styles: {
|
||||||
imageMissingSrc: App.getConfig().get('urls.imageMissing'),
|
block: {
|
||||||
};
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
onRender: function() {
|
},
|
||||||
this.toolsView = new Module.ImageBlockToolsView({ model: this.model });
|
}, EditorApplication.getConfig().get('blockDefaults.image'));
|
||||||
this.toolsRegion.show(this.toolsView);
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (this.model.get('padded')) {
|
Module.ImageBlockView = base.BlockView.extend({
|
||||||
this.$el.removeClass('mailpoet_full_image');
|
className: "mailpoet_block mailpoet_image_block mailpoet_droppable_block",
|
||||||
} else {
|
getTemplate: function() { return templates.imageBlock; },
|
||||||
this.$el.addClass('mailpoet_full_image');
|
initialize: function() {
|
||||||
}
|
this.on('showSettings', this.showSettings);
|
||||||
},
|
},
|
||||||
showSettings: function(options) {
|
onDragSubstituteBy: function() { return Module.ImageWidgetView; },
|
||||||
this.toolsView.triggerMethod('showSettings', options);
|
templateHelpers: function() {
|
||||||
},
|
return {
|
||||||
onBeforeDestroy: function() {
|
model: this.model.toJSON(),
|
||||||
this.off('showSettings');
|
viewCid: this.cid,
|
||||||
},
|
imageMissingSrc: App.getConfig().get('urls.imageMissing'),
|
||||||
});
|
};
|
||||||
|
},
|
||||||
|
onRender: function() {
|
||||||
|
this.toolsView = new Module.ImageBlockToolsView({ model: this.model });
|
||||||
|
this.toolsRegion.show(this.toolsView);
|
||||||
|
|
||||||
Module.ImageBlockToolsView = base.BlockToolsView.extend({
|
if (this.model.get('padded')) {
|
||||||
getSettingsView: function() { return Module.ImageBlockSettingsView; },
|
this.$el.removeClass('mailpoet_full_image');
|
||||||
initialize: function() {
|
} else {
|
||||||
base.BlockToolsView.prototype.initialize.apply(this, arguments);
|
this.$el.addClass('mailpoet_full_image');
|
||||||
this.on('showSettings', this.changeSettings);
|
}
|
||||||
},
|
},
|
||||||
changeSettings: function(options) {
|
showSettings: function(options) {
|
||||||
(new Module.ImageBlockSettingsView({
|
this.toolsView.triggerMethod('showSettings', options);
|
||||||
model: this.model,
|
},
|
||||||
showImageManager: (options.showImageManager === true),
|
onBeforeDestroy: function() {
|
||||||
})).render();
|
this.off('showSettings');
|
||||||
},
|
},
|
||||||
onBeforeDestroy: function() {
|
});
|
||||||
this.off('showSettings');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.ImageBlockSettingsView = base.BlockSettingsView.extend({
|
Module.ImageBlockToolsView = base.BlockToolsView.extend({
|
||||||
getTemplate: function() { return templates.imageBlockSettings; },
|
getSettingsView: function() { return Module.ImageBlockSettingsView; },
|
||||||
events: function() {
|
initialize: function() {
|
||||||
return {
|
base.BlockToolsView.prototype.initialize.apply(this, arguments);
|
||||||
"keyup .mailpoet_field_image_link": _.partial(this.changeField, "link"),
|
this.on('showSettings', this.changeSettings);
|
||||||
"keyup .mailpoet_field_image_address": _.partial(this.changeField, "src"),
|
},
|
||||||
"keyup .mailpoet_field_image_alt_text": _.partial(this.changeField, "alt"),
|
changeSettings: function(options) {
|
||||||
"change .mailpoet_field_image_padded": _.partial(this.changeBoolField, "padded"),
|
(new Module.ImageBlockSettingsView({
|
||||||
"change .mailpoet_field_image_alignment": _.partial(this.changeField, "styles.block.textAlign"),
|
model: this.model,
|
||||||
"click .mailpoet_field_image_select_another_image": "showMediaManager",
|
showImageManager: (options.showImageManager === true),
|
||||||
"click .mailpoet_done_editing": "close",
|
})).render();
|
||||||
};
|
},
|
||||||
},
|
onBeforeDestroy: function() {
|
||||||
initialize: function(options) {
|
this.off('showSettings');
|
||||||
base.BlockSettingsView.prototype.initialize.apply(this, arguments);
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (options.showImageManager) {
|
Module.ImageBlockSettingsView = base.BlockSettingsView.extend({
|
||||||
this.showMediaManager();
|
getTemplate: function() { return templates.imageBlockSettings; },
|
||||||
}
|
events: function() {
|
||||||
},
|
return {
|
||||||
showMediaManager: function() {
|
"keyup .mailpoet_field_image_link": _.partial(this.changeField, "link"),
|
||||||
if (this._mediaManager) {
|
"keyup .mailpoet_field_image_address": _.partial(this.changeField, "src"),
|
||||||
this._mediaManager.resetSelections();
|
"keyup .mailpoet_field_image_alt_text": _.partial(this.changeField, "alt"),
|
||||||
this._mediaManager.open();
|
"change .mailpoet_field_image_padded": _.partial(this.changeBoolField, "padded"),
|
||||||
return;
|
"change .mailpoet_field_image_alignment": _.partial(this.changeField, "styles.block.textAlign"),
|
||||||
}
|
"click .mailpoet_field_image_select_another_image": "showMediaManager",
|
||||||
|
"click .mailpoet_done_editing": "close",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
initialize: function(options) {
|
||||||
|
base.BlockSettingsView.prototype.initialize.apply(this, arguments);
|
||||||
|
|
||||||
var MediaManager = wp.media.view.MediaFrame.Select.extend({
|
if (options.showImageManager) {
|
||||||
|
this.showMediaManager();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showMediaManager: function() {
|
||||||
|
if (this._mediaManager) {
|
||||||
|
this._mediaManager.resetSelections();
|
||||||
|
this._mediaManager.open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
initialize: function() {
|
var MediaManager = wp.media.view.MediaFrame.Select.extend({
|
||||||
wp.media.view.MediaFrame.prototype.initialize.apply(this, arguments);
|
|
||||||
|
|
||||||
_.defaults(this.options, {
|
initialize: function() {
|
||||||
multiple: true,
|
wp.media.view.MediaFrame.prototype.initialize.apply(this, arguments);
|
||||||
editing: false,
|
|
||||||
state: 'insert'
|
|
||||||
});
|
|
||||||
|
|
||||||
this.createSelection();
|
_.defaults(this.options, {
|
||||||
this.createStates();
|
multiple: true,
|
||||||
this.bindHandlers();
|
editing: false,
|
||||||
this.createIframeStates();
|
state: 'insert'
|
||||||
|
});
|
||||||
|
|
||||||
// Hide title
|
this.createSelection();
|
||||||
this.$el.addClass('hide-title');
|
this.createStates();
|
||||||
},
|
this.bindHandlers();
|
||||||
|
this.createIframeStates();
|
||||||
|
|
||||||
resetSelections: function() {
|
// Hide title
|
||||||
this.state().get('selection').reset();
|
this.$el.addClass('hide-title');
|
||||||
},
|
},
|
||||||
|
|
||||||
createQuery: function(options) {
|
resetSelections: function() {
|
||||||
var query = wp.media.query(options);
|
this.state().get('selection').reset();
|
||||||
return query;
|
},
|
||||||
},
|
|
||||||
|
|
||||||
createStates: function() {
|
createQuery: function(options) {
|
||||||
var options = this.options;
|
var query = wp.media.query(options);
|
||||||
|
return query;
|
||||||
|
},
|
||||||
|
|
||||||
// Add the default states.
|
createStates: function() {
|
||||||
this.states.add([
|
var options = this.options;
|
||||||
// Main states.
|
|
||||||
new wp.media.controller.Library({
|
|
||||||
id: 'insert',
|
|
||||||
title: 'Add images',
|
|
||||||
priority: 20,
|
|
||||||
toolbar: 'main-insert',
|
|
||||||
filterable: 'image',
|
|
||||||
library: this.createQuery(options.library),
|
|
||||||
multiple: options.multiple ? 'reset' : false,
|
|
||||||
editable: false,
|
|
||||||
|
|
||||||
// If the user isn't allowed to edit fields,
|
// Add the default states.
|
||||||
// can they still edit it locally?
|
this.states.add([
|
||||||
allowLocalEdits: false,
|
// Main states.
|
||||||
|
new wp.media.controller.Library({
|
||||||
|
id: 'insert',
|
||||||
|
title: 'Add images',
|
||||||
|
priority: 20,
|
||||||
|
toolbar: 'main-insert',
|
||||||
|
filterable: 'image',
|
||||||
|
library: this.createQuery(options.library),
|
||||||
|
multiple: options.multiple ? 'reset' : false,
|
||||||
|
editable: false,
|
||||||
|
|
||||||
// Show the attachment display settings.
|
// If the user isn't allowed to edit fields,
|
||||||
displaySettings: false,
|
// can they still edit it locally?
|
||||||
// Update user settings when users adjust the
|
allowLocalEdits: false,
|
||||||
// attachment display settings.
|
|
||||||
displayUserSettings: false
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if(wp.media.view.settings.post.featuredImageId) {
|
// Show the attachment display settings.
|
||||||
this.states.add(new wp.media.controller.FeaturedImage());
|
displaySettings: false,
|
||||||
}
|
// Update user settings when users adjust the
|
||||||
},
|
// attachment display settings.
|
||||||
|
displayUserSettings: false
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
bindHandlers: function() {
|
if(wp.media.view.settings.post.featuredImageId) {
|
||||||
// from Select
|
this.states.add(new wp.media.controller.FeaturedImage());
|
||||||
this.on('router:create:browse', this.createRouter, this);
|
}
|
||||||
this.on('router:render:browse', this.browseRouter, this);
|
},
|
||||||
this.on('content:create:browse', this.browseContent, this);
|
|
||||||
this.on('content:render:upload', this.uploadContent, this);
|
|
||||||
this.on('toolbar:create:select', this.createSelectToolbar, this);
|
|
||||||
|
|
||||||
this.on('menu:create:gallery', this.createMenu, this);
|
bindHandlers: function() {
|
||||||
this.on('toolbar:create:main-insert', this.createToolbar, this);
|
// from Select
|
||||||
this.on('toolbar:create:main-gallery', this.createToolbar, this);
|
this.on('router:create:browse', this.createRouter, this);
|
||||||
this.on('toolbar:create:main-embed', this.mainEmbedToolbar, this);
|
this.on('router:render:browse', this.browseRouter, this);
|
||||||
|
this.on('content:create:browse', this.browseContent, this);
|
||||||
|
this.on('content:render:upload', this.uploadContent, this);
|
||||||
|
this.on('toolbar:create:select', this.createSelectToolbar, this);
|
||||||
|
|
||||||
this.on('updateExcluded', this.browseContent, this);
|
this.on('menu:create:gallery', this.createMenu, this);
|
||||||
|
this.on('toolbar:create:main-insert', this.createToolbar, this);
|
||||||
|
this.on('toolbar:create:main-gallery', this.createToolbar, this);
|
||||||
|
this.on('toolbar:create:main-embed', this.mainEmbedToolbar, this);
|
||||||
|
|
||||||
var handlers = {
|
this.on('updateExcluded', this.browseContent, this);
|
||||||
content: {
|
|
||||||
'embed': 'embedContent',
|
|
||||||
'edit-selection': 'editSelectionContent'
|
|
||||||
},
|
|
||||||
toolbar: {
|
|
||||||
'main-insert': 'mainInsertToolbar'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
_.each(handlers, function(regionHandlers, region) {
|
var handlers = {
|
||||||
_.each(regionHandlers, function(callback, handler) {
|
content: {
|
||||||
this.on(region + ':render:' + handler, this[callback], this);
|
'embed': 'embedContent',
|
||||||
}, this);
|
'edit-selection': 'editSelectionContent'
|
||||||
}, this);
|
},
|
||||||
},
|
toolbar: {
|
||||||
|
'main-insert': 'mainInsertToolbar'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
uploadContent: function() {
|
_.each(handlers, function(regionHandlers, region) {
|
||||||
wp.media.view.MediaFrame.Select.prototype.uploadContent.apply(this, arguments);
|
_.each(regionHandlers, function(callback, handler) {
|
||||||
this.$el.addClass('hide-toolbar');
|
this.on(region + ':render:' + handler, this[callback], this);
|
||||||
},
|
}, this);
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
// Content
|
uploadContent: function() {
|
||||||
embedContent: function() {
|
wp.media.view.MediaFrame.Select.prototype.uploadContent.apply(this, arguments);
|
||||||
var view = new wp.media.view.Embed({
|
this.$el.addClass('hide-toolbar');
|
||||||
controller: this,
|
},
|
||||||
model: this.state()
|
|
||||||
}).render();
|
|
||||||
|
|
||||||
this.content.set(view);
|
// Content
|
||||||
view.url.focus();
|
embedContent: function() {
|
||||||
},
|
var view = new wp.media.view.Embed({
|
||||||
|
controller: this,
|
||||||
|
model: this.state()
|
||||||
|
}).render();
|
||||||
|
|
||||||
editSelectionContent: function() {
|
this.content.set(view);
|
||||||
var state = this.state(),
|
view.url.focus();
|
||||||
selection = state.get('selection'),
|
},
|
||||||
view;
|
|
||||||
|
|
||||||
view = new wp.media.view.AttachmentsBrowser({
|
editSelectionContent: function() {
|
||||||
controller: this,
|
var state = this.state(),
|
||||||
collection: selection,
|
selection = state.get('selection'),
|
||||||
selection: selection,
|
view;
|
||||||
model: state,
|
|
||||||
sortable: true,
|
|
||||||
search: false,
|
|
||||||
dragInfo: true,
|
|
||||||
|
|
||||||
AttachmentView: wp.media.view.Attachment.EditSelection
|
view = new wp.media.view.AttachmentsBrowser({
|
||||||
}).render();
|
controller: this,
|
||||||
|
collection: selection,
|
||||||
|
selection: selection,
|
||||||
|
model: state,
|
||||||
|
sortable: true,
|
||||||
|
search: false,
|
||||||
|
dragInfo: true,
|
||||||
|
|
||||||
view.toolbar.set('backToLibrary', {
|
AttachmentView: wp.media.view.Attachment.EditSelection
|
||||||
text: 'Return to library',
|
}).render();
|
||||||
priority: -100,
|
|
||||||
|
|
||||||
click: function() {
|
view.toolbar.set('backToLibrary', {
|
||||||
this.controller.content.mode('browse');
|
text: 'Return to library',
|
||||||
}
|
priority: -100,
|
||||||
});
|
|
||||||
|
|
||||||
// Browse our library of attachments.
|
click: function() {
|
||||||
this.content.set(view);
|
this.controller.content.mode('browse');
|
||||||
},
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Toolbars
|
// Browse our library of attachments.
|
||||||
selectionStatusToolbar: function(view) {
|
this.content.set(view);
|
||||||
var editable = this.state().get('editable');
|
},
|
||||||
|
|
||||||
view.set('selection', new wp.media.view.Selection({
|
// Toolbars
|
||||||
controller: this,
|
selectionStatusToolbar: function(view) {
|
||||||
collection: this.state().get('selection'),
|
var editable = this.state().get('editable');
|
||||||
priority: -40,
|
|
||||||
|
|
||||||
// If the selection is editable, pass the callback to
|
view.set('selection', new wp.media.view.Selection({
|
||||||
// switch the content mode.
|
controller: this,
|
||||||
editable: editable && function() {
|
collection: this.state().get('selection'),
|
||||||
this.controller.content.mode('edit-selection');
|
priority: -40,
|
||||||
}
|
|
||||||
}).render() );
|
|
||||||
},
|
|
||||||
|
|
||||||
mainInsertToolbar: function(view) {
|
// If the selection is editable, pass the callback to
|
||||||
var controller = this;
|
// switch the content mode.
|
||||||
|
editable: editable && function() {
|
||||||
|
this.controller.content.mode('edit-selection');
|
||||||
|
}
|
||||||
|
}).render() );
|
||||||
|
},
|
||||||
|
|
||||||
this.selectionStatusToolbar(view);
|
mainInsertToolbar: function(view) {
|
||||||
|
var controller = this;
|
||||||
|
|
||||||
view.set('insert', {
|
this.selectionStatusToolbar(view);
|
||||||
style: 'primary',
|
|
||||||
priority: 80,
|
|
||||||
text: 'Select Image',
|
|
||||||
requires: { selection: true },
|
|
||||||
|
|
||||||
click: function() {
|
view.set('insert', {
|
||||||
var state = controller.state(),
|
style: 'primary',
|
||||||
selection = state.get('selection');
|
priority: 80,
|
||||||
|
text: 'Select Image',
|
||||||
|
requires: { selection: true },
|
||||||
|
|
||||||
controller.close();
|
click: function() {
|
||||||
state.trigger('insert', selection).reset();
|
var state = controller.state(),
|
||||||
}
|
selection = state.get('selection');
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
mainEmbedToolbar: function(toolbar) {
|
controller.close();
|
||||||
toolbar.view = new wp.media.view.Toolbar.Embed({
|
state.trigger('insert', selection).reset();
|
||||||
controller: this,
|
}
|
||||||
text: 'Add images'
|
});
|
||||||
});
|
},
|
||||||
}
|
|
||||||
|
|
||||||
});
|
mainEmbedToolbar: function(toolbar) {
|
||||||
|
toolbar.view = new wp.media.view.Toolbar.Embed({
|
||||||
|
controller: this,
|
||||||
|
text: 'Add images'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var theFrame = this._mediaManager = new MediaManager({
|
});
|
||||||
id: 'mailpoet-media-manager',
|
|
||||||
frame: 'select',
|
|
||||||
title: 'Select image',
|
|
||||||
editing: false,
|
|
||||||
multiple: false,
|
|
||||||
library: {
|
|
||||||
type: 'image'
|
|
||||||
},
|
|
||||||
displaySettings: false,
|
|
||||||
button: {
|
|
||||||
text: 'Select',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
that = this;
|
|
||||||
|
|
||||||
this._mediaManager.on('insert', function() {
|
var theFrame = this._mediaManager = new MediaManager({
|
||||||
// Append media manager image selections to Images tab
|
id: 'mailpoet-media-manager',
|
||||||
var selection = theFrame.state().get('selection');
|
frame: 'select',
|
||||||
selection.each(function(attachment) {
|
title: 'Select image',
|
||||||
var sizes = attachment.get('sizes'),
|
editing: false,
|
||||||
// Following advice from Becs, the target width should
|
multiple: false,
|
||||||
// be a double of one column width to render well on
|
library: {
|
||||||
// retina screen devices
|
type: 'image'
|
||||||
targetImageWidth = 1200,
|
},
|
||||||
|
displaySettings: false,
|
||||||
|
button: {
|
||||||
|
text: 'Select',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
that = this;
|
||||||
|
|
||||||
// For main image use the size, that's closest to being 600px in width
|
this._mediaManager.on('insert', function() {
|
||||||
sizeKeys = _.keys(sizes),
|
// Append media manager image selections to Images tab
|
||||||
|
var selection = theFrame.state().get('selection');
|
||||||
|
selection.each(function(attachment) {
|
||||||
|
var sizes = attachment.get('sizes'),
|
||||||
|
// Following advice from Becs, the target width should
|
||||||
|
// be a double of one column width to render well on
|
||||||
|
// retina screen devices
|
||||||
|
targetImageWidth = 1200,
|
||||||
|
|
||||||
// Pick the width that is closest to target width
|
// For main image use the size, that's closest to being 600px in width
|
||||||
increasingByWidthDifference = _.sortBy(
|
sizeKeys = _.keys(sizes),
|
||||||
_.keys(sizes),
|
|
||||||
function(size) { return Math.abs(targetImageWidth - sizes[size].width); }
|
|
||||||
),
|
|
||||||
bestWidth = sizes[_.first(increasingByWidthDifference)].width,
|
|
||||||
imagesOfBestWidth = _.filter(_.values(sizes), function(size) { return size.width === bestWidth; }),
|
|
||||||
|
|
||||||
// Maximize the height if there are multiple images with same width
|
// Pick the width that is closest to target width
|
||||||
mainSize = _.max(imagesOfBestWidth, function(size) { return size.height; });
|
increasingByWidthDifference = _.sortBy(
|
||||||
|
_.keys(sizes),
|
||||||
|
function(size) { return Math.abs(targetImageWidth - sizes[size].width); }
|
||||||
|
),
|
||||||
|
bestWidth = sizes[_.first(increasingByWidthDifference)].width,
|
||||||
|
imagesOfBestWidth = _.filter(_.values(sizes), function(size) { return size.width === bestWidth; }),
|
||||||
|
|
||||||
that.model.set({
|
// Maximize the height if there are multiple images with same width
|
||||||
height: mainSize.height + 'px',
|
mainSize = _.max(imagesOfBestWidth, function(size) { return size.height; });
|
||||||
width: mainSize.width + 'px',
|
|
||||||
src: mainSize.url,
|
|
||||||
alt: (attachment.get('alt') !== "" && attachment.get('alt') !== undefined) ? attachment.get('alt') : attachment.get('title'),
|
|
||||||
});
|
|
||||||
// Rerender settings view due to changes from outside of settings view
|
|
||||||
that.render();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
this._mediaManager.open();
|
that.model.set({
|
||||||
},
|
height: mainSize.height + 'px',
|
||||||
onBeforeDestroy: function() {
|
width: mainSize.width + 'px',
|
||||||
if (typeof this._mediaManager === 'object') {
|
src: mainSize.url,
|
||||||
this._mediaManager.remove();
|
alt: (attachment.get('alt') !== "" && attachment.get('alt') !== undefined) ? attachment.get('alt') : attachment.get('title'),
|
||||||
}
|
});
|
||||||
},
|
// Rerender settings view due to changes from outside of settings view
|
||||||
});
|
that.render();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
ImageWidgetView = base.WidgetView.extend({
|
this._mediaManager.open();
|
||||||
getTemplate: function() { return templates.imageInsertion; },
|
},
|
||||||
behaviors: {
|
onBeforeDestroy: function() {
|
||||||
DraggableBehavior: {
|
if (typeof this._mediaManager === 'object') {
|
||||||
cloneOriginal: true,
|
this._mediaManager.remove();
|
||||||
drop: function() {
|
}
|
||||||
return new Module.ImageBlockModel();
|
},
|
||||||
},
|
});
|
||||||
onDrop: function(options) {
|
|
||||||
options.droppedView.triggerMethod('showSettings', { showImageManager: true });
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
Module.ImageWidgetView = ImageWidgetView;
|
|
||||||
|
|
||||||
App.on('before:start', function() {
|
ImageWidgetView = base.WidgetView.extend({
|
||||||
App.registerBlockType('image', {
|
getTemplate: function() { return templates.imageInsertion; },
|
||||||
blockModel: Module.ImageBlockModel,
|
behaviors: {
|
||||||
blockView: Module.ImageBlockView,
|
DraggableBehavior: {
|
||||||
});
|
cloneOriginal: true,
|
||||||
|
drop: function() {
|
||||||
|
return new Module.ImageBlockModel();
|
||||||
|
},
|
||||||
|
onDrop: function(options) {
|
||||||
|
options.droppedView.triggerMethod('showSettings', { showImageManager: true });
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
Module.ImageWidgetView = ImageWidgetView;
|
||||||
|
|
||||||
|
App.on('before:start', function() {
|
||||||
|
App.registerBlockType('image', {
|
||||||
|
blockModel: Module.ImageBlockModel,
|
||||||
|
blockView: Module.ImageBlockView,
|
||||||
|
});
|
||||||
|
|
||||||
|
App.registerWidget({
|
||||||
|
name: 'image',
|
||||||
|
widgetView: Module.ImageWidgetView,
|
||||||
|
priority: 91,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.registerWidget({
|
|
||||||
name: 'image',
|
|
||||||
widgetView: Module.ImageWidgetView,
|
|
||||||
priority: 91,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -10,460 +10,470 @@
|
|||||||
* This block depends on blocks.button and blocks.divider for block model and
|
* This block depends on blocks.button and blocks.divider for block model and
|
||||||
* block settings view.
|
* block settings view.
|
||||||
*/
|
*/
|
||||||
EditorApplication.module("blocks.posts", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/blocks/posts', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
'mailpoet',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette, MailPoet) {
|
||||||
|
|
||||||
var base = App.module('blocks.base');
|
EditorApplication.module("blocks.posts", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
Module.PostsBlockModel = base.BlockModel.extend({
|
var base = App.module('blocks.base');
|
||||||
stale: ['_selectedPosts', '_availablePosts'],
|
|
||||||
defaults: function() {
|
|
||||||
return this._getDefaults({
|
|
||||||
type: 'posts',
|
|
||||||
amount: '10',
|
|
||||||
contentType: 'post', // 'post'|'page'|'mailpoet_page'
|
|
||||||
postStatus: 'publish', // 'draft'|'pending'|'private'|'publish'|'future'
|
|
||||||
terms: [], // List of category and tag objects
|
|
||||||
search: '', // Search keyword term
|
|
||||||
inclusionType: 'include', // 'include'|'exclude'
|
|
||||||
displayType: 'excerpt', // 'excerpt'|'full'|'titleOnly'
|
|
||||||
titleFormat: 'h1', // 'h1'|'h2'|'h3'|'ul'
|
|
||||||
titlePosition: 'inTextBlock', // 'inTextBlock'|'aboveBlock',
|
|
||||||
titleAlignment: 'left', // 'left'|'center'|'right'
|
|
||||||
titleIsLink: false, // false|true
|
|
||||||
imagePadded: true, // true|false
|
|
||||||
//imageAlignment: 'centerPadded', // 'centerFull'|'centerPadded'|'left'|'right'|'alternate'|'none'
|
|
||||||
showAuthor: 'no', // 'no'|'aboveText'|'belowText'
|
|
||||||
authorPrecededBy: 'Author:',
|
|
||||||
showCategories: 'no', // 'no'|'aboveText'|'belowText'
|
|
||||||
categoriesPrecededBy: 'Categories:',
|
|
||||||
readMoreType: 'link', // 'link'|'button'
|
|
||||||
readMoreText: 'Read more', // 'link'|'button'
|
|
||||||
readMoreButton: {
|
|
||||||
text: 'Read more',
|
|
||||||
url: '[postLink]'
|
|
||||||
},
|
|
||||||
sortBy: 'newest', // 'newest'|'oldest',
|
|
||||||
showDivider: true, // true|false
|
|
||||||
divider: {},
|
|
||||||
_selectedPosts: [],
|
|
||||||
_availablePosts: [],
|
|
||||||
}, EditorApplication.getConfig().get('blockDefaults.posts'));
|
|
||||||
},
|
|
||||||
relations: function() {
|
|
||||||
return {
|
|
||||||
readMoreButton: App.getBlockTypeModel('button'),
|
|
||||||
divider: App.getBlockTypeModel('divider'),
|
|
||||||
_selectedPosts: Backbone.Collection,
|
|
||||||
_availablePosts: Backbone.Collection,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
initialize: function() {
|
|
||||||
var that = this;
|
|
||||||
// Attach Radio.Requests API primarily for highlighting
|
|
||||||
_.extend(this, Backbone.Radio.Requests);
|
|
||||||
|
|
||||||
this.fetchAvailablePosts();
|
Module.PostsBlockModel = base.BlockModel.extend({
|
||||||
this.on('change:amount change:contentType change:terms change:inclusionType change:postStatus change:search change:sortBy', this._scheduleFetchAvailablePosts, this);
|
stale: ['_selectedPosts', '_availablePosts'],
|
||||||
this.on('insertSelectedPosts', this._insertSelectedPosts, this);
|
defaults: function() {
|
||||||
},
|
return this._getDefaults({
|
||||||
fetchAvailablePosts: function() {
|
type: 'posts',
|
||||||
var that = this;
|
amount: '10',
|
||||||
mailpoet_post_wpi('posts.php', this.toJSON(), function(response) {
|
contentType: 'post', // 'post'|'page'|'mailpoet_page'
|
||||||
console.log('Posts fetched', arguments);
|
postStatus: 'publish', // 'draft'|'pending'|'private'|'publish'|'future'
|
||||||
that.get('_availablePosts').reset(response);
|
terms: [], // List of category and tag objects
|
||||||
that.get('_selectedPosts').reset(); // Empty out the collection
|
search: '', // Search keyword term
|
||||||
that.trigger('change:_availablePosts');
|
inclusionType: 'include', // 'include'|'exclude'
|
||||||
}, function() {
|
displayType: 'excerpt', // 'excerpt'|'full'|'titleOnly'
|
||||||
console.log('Posts fetchPosts error', arguments);
|
titleFormat: 'h1', // 'h1'|'h2'|'h3'|'ul'
|
||||||
});
|
titlePosition: 'inTextBlock', // 'inTextBlock'|'aboveBlock',
|
||||||
},
|
titleAlignment: 'left', // 'left'|'center'|'right'
|
||||||
/**
|
titleIsLink: false, // false|true
|
||||||
* Batch more changes during a specific time, instead of fetching
|
imagePadded: true, // true|false
|
||||||
* ALC posts on each model change
|
//imageAlignment: 'centerPadded', // 'centerFull'|'centerPadded'|'left'|'right'|'alternate'|'none'
|
||||||
*/
|
showAuthor: 'no', // 'no'|'aboveText'|'belowText'
|
||||||
_scheduleFetchAvailablePosts: function() {
|
authorPrecededBy: 'Author:',
|
||||||
var timeout = 500,
|
showCategories: 'no', // 'no'|'aboveText'|'belowText'
|
||||||
that = this;
|
categoriesPrecededBy: 'Categories:',
|
||||||
if (this._fetchPostsTimer !== undefined) {
|
readMoreType: 'link', // 'link'|'button'
|
||||||
clearTimeout(this._fetchPostsTimer);
|
readMoreText: 'Read more', // 'link'|'button'
|
||||||
}
|
readMoreButton: {
|
||||||
this._fetchPostsTimer = setTimeout(function() {
|
text: 'Read more',
|
||||||
that.fetchAvailablePosts();
|
url: '[postLink]'
|
||||||
that._fetchPostsTimer = undefined;
|
},
|
||||||
}, timeout);
|
sortBy: 'newest', // 'newest'|'oldest',
|
||||||
},
|
showDivider: true, // true|false
|
||||||
_insertSelectedPosts: function() {
|
divider: {},
|
||||||
var that = this,
|
_selectedPosts: [],
|
||||||
data = this.toJSON(),
|
_availablePosts: [],
|
||||||
index = this.collection.indexOf(this),
|
}, EditorApplication.getConfig().get('blockDefaults.posts'));
|
||||||
collection = this.collection;
|
},
|
||||||
|
relations: function() {
|
||||||
|
return {
|
||||||
|
readMoreButton: App.getBlockTypeModel('button'),
|
||||||
|
divider: App.getBlockTypeModel('divider'),
|
||||||
|
_selectedPosts: Backbone.Collection,
|
||||||
|
_availablePosts: Backbone.Collection,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
initialize: function() {
|
||||||
|
var that = this;
|
||||||
|
// Attach Radio.Requests API primarily for highlighting
|
||||||
|
_.extend(this, Backbone.Radio.Requests);
|
||||||
|
|
||||||
data.posts = this.get('_selectedPosts').pluck('ID');
|
this.fetchAvailablePosts();
|
||||||
|
this.on('change:amount change:contentType change:terms change:inclusionType change:postStatus change:search change:sortBy', this._scheduleFetchAvailablePosts, this);
|
||||||
|
this.on('insertSelectedPosts', this._insertSelectedPosts, this);
|
||||||
|
},
|
||||||
|
fetchAvailablePosts: function() {
|
||||||
|
var that = this;
|
||||||
|
mailpoet_post_wpi('posts.php', this.toJSON(), function(response) {
|
||||||
|
console.log('Posts fetched', arguments);
|
||||||
|
that.get('_availablePosts').reset(response);
|
||||||
|
that.get('_selectedPosts').reset(); // Empty out the collection
|
||||||
|
that.trigger('change:_availablePosts');
|
||||||
|
}, function() {
|
||||||
|
console.log('Posts fetchPosts error', arguments);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Batch more changes during a specific time, instead of fetching
|
||||||
|
* ALC posts on each model change
|
||||||
|
*/
|
||||||
|
_scheduleFetchAvailablePosts: function() {
|
||||||
|
var timeout = 500,
|
||||||
|
that = this;
|
||||||
|
if (this._fetchPostsTimer !== undefined) {
|
||||||
|
clearTimeout(this._fetchPostsTimer);
|
||||||
|
}
|
||||||
|
this._fetchPostsTimer = setTimeout(function() {
|
||||||
|
that.fetchAvailablePosts();
|
||||||
|
that._fetchPostsTimer = undefined;
|
||||||
|
}, timeout);
|
||||||
|
},
|
||||||
|
_insertSelectedPosts: function() {
|
||||||
|
var that = this,
|
||||||
|
data = this.toJSON(),
|
||||||
|
index = this.collection.indexOf(this),
|
||||||
|
collection = this.collection;
|
||||||
|
|
||||||
if (data.posts.length === 0) return;
|
data.posts = this.get('_selectedPosts').pluck('ID');
|
||||||
|
|
||||||
mailpoet_post_wpi('automated_latest_content.php', data, function(response) {
|
if (data.posts.length === 0) return;
|
||||||
console.log('Available posts fetched', arguments);
|
|
||||||
collection.add(response, { at: index });
|
|
||||||
}, function() {
|
|
||||||
console.log('Posts fetchPosts error', arguments);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.PostsBlockView = base.BlockView.extend({
|
mailpoet_post_wpi('automated_latest_content.php', data, function(response) {
|
||||||
className: "mailpoet_block mailpoet_posts_block mailpoet_droppable_block",
|
console.log('Available posts fetched', arguments);
|
||||||
getTemplate: function() { return templates.postsBlock; },
|
collection.add(response, { at: index });
|
||||||
modelEvents: {},
|
}, function() {
|
||||||
onDragSubstituteBy: function() { return Module.PostsWidgetView; },
|
console.log('Posts fetchPosts error', arguments);
|
||||||
initialize: function() {
|
});
|
||||||
this.toolsView = new Module.PostsBlockToolsView({ model: this.model });
|
},
|
||||||
this.on('showSettings', this.showSettings);
|
});
|
||||||
this.model.reply('blockView', this.notifyAboutSelf, this);
|
|
||||||
},
|
|
||||||
onRender: function() {
|
|
||||||
if (!this.toolsRegion.hasView()) {
|
|
||||||
this.toolsRegion.show(this.toolsView);
|
|
||||||
}
|
|
||||||
this.trigger('showSettings');
|
|
||||||
},
|
|
||||||
showSettings: function(options) {
|
|
||||||
this.toolsView.triggerMethod('showSettings', options);
|
|
||||||
},
|
|
||||||
notifyAboutSelf: function() {
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
onBeforeDestroy: function() {
|
|
||||||
this.model.stopReplying('blockView', this.notifyAboutSelf, this);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.PostsBlockToolsView = base.BlockToolsView.extend({
|
Module.PostsBlockView = base.BlockView.extend({
|
||||||
getSettingsView: function() { return Module.PostsBlockSettingsView; },
|
className: "mailpoet_block mailpoet_posts_block mailpoet_droppable_block",
|
||||||
initialize: function() {
|
getTemplate: function() { return templates.postsBlock; },
|
||||||
base.BlockToolsView.prototype.initialize.apply(this, arguments);
|
modelEvents: {},
|
||||||
this.on('showSettings', this.changeSettings);
|
onDragSubstituteBy: function() { return Module.PostsWidgetView; },
|
||||||
this.settingsView = new Module.PostsBlockSettingsView({ model: this.model });
|
initialize: function() {
|
||||||
},
|
this.toolsView = new Module.PostsBlockToolsView({ model: this.model });
|
||||||
changeSettings: function() {
|
this.on('showSettings', this.showSettings);
|
||||||
this.settingsView.render();
|
this.model.reply('blockView', this.notifyAboutSelf, this);
|
||||||
},
|
},
|
||||||
onBeforeDestroy: function() {
|
onRender: function() {
|
||||||
this.settingsView.destroy();
|
if (!this.toolsRegion.hasView()) {
|
||||||
this.off('showSettings');
|
this.toolsRegion.show(this.toolsView);
|
||||||
MailPoet.Modal.close();
|
}
|
||||||
},
|
this.trigger('showSettings');
|
||||||
});
|
},
|
||||||
|
showSettings: function(options) {
|
||||||
|
this.toolsView.triggerMethod('showSettings', options);
|
||||||
|
},
|
||||||
|
notifyAboutSelf: function() {
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
onBeforeDestroy: function() {
|
||||||
|
this.model.stopReplying('blockView', this.notifyAboutSelf, this);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Module.PostsBlockSettingsView = base.BlockSettingsView.extend({
|
Module.PostsBlockToolsView = base.BlockToolsView.extend({
|
||||||
getTemplate: function() { return templates.postsBlockSettings; },
|
getSettingsView: function() { return Module.PostsBlockSettingsView; },
|
||||||
regions: {
|
initialize: function() {
|
||||||
selectionRegion: '.mailpoet_settings_posts_selection',
|
base.BlockToolsView.prototype.initialize.apply(this, arguments);
|
||||||
displayOptionsRegion: '.mailpoet_settings_posts_display_options',
|
this.on('showSettings', this.changeSettings);
|
||||||
},
|
this.settingsView = new Module.PostsBlockSettingsView({ model: this.model });
|
||||||
events: {
|
},
|
||||||
'click .mailpoet_settings_posts_show_display_options': 'switchToDisplayOptions',
|
changeSettings: function() {
|
||||||
'click .mailpoet_settings_posts_show_post_selection': 'switchToPostSelection',
|
this.settingsView.render();
|
||||||
'click .mailpoet_settings_posts_insert_selected': 'insertPosts',
|
},
|
||||||
},
|
onBeforeDestroy: function() {
|
||||||
templateHelpers: function() {
|
this.settingsView.destroy();
|
||||||
return {
|
this.off('showSettings');
|
||||||
model: this.model.toJSON(),
|
MailPoet.Modal.close();
|
||||||
};
|
},
|
||||||
},
|
});
|
||||||
initialize: function() {
|
|
||||||
this.selectionView = new PostSelectionSettingsView({ model: this.model });
|
|
||||||
this.displayOptionsView = new PostsDisplayOptionsSettingsView({ model: this.model });
|
|
||||||
},
|
|
||||||
onRender: function() {
|
|
||||||
var that = this,
|
|
||||||
blockView = this.model.request('blockView');
|
|
||||||
|
|
||||||
this.selectionRegion.show(this.selectionView);
|
Module.PostsBlockSettingsView = base.BlockSettingsView.extend({
|
||||||
this.displayOptionsRegion.show(this.displayOptionsView);
|
getTemplate: function() { return templates.postsBlockSettings; },
|
||||||
|
regions: {
|
||||||
|
selectionRegion: '.mailpoet_settings_posts_selection',
|
||||||
|
displayOptionsRegion: '.mailpoet_settings_posts_display_options',
|
||||||
|
},
|
||||||
|
events: {
|
||||||
|
'click .mailpoet_settings_posts_show_display_options': 'switchToDisplayOptions',
|
||||||
|
'click .mailpoet_settings_posts_show_post_selection': 'switchToPostSelection',
|
||||||
|
'click .mailpoet_settings_posts_insert_selected': 'insertPosts',
|
||||||
|
},
|
||||||
|
templateHelpers: function() {
|
||||||
|
return {
|
||||||
|
model: this.model.toJSON(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
initialize: function() {
|
||||||
|
this.selectionView = new PostSelectionSettingsView({ model: this.model });
|
||||||
|
this.displayOptionsView = new PostsDisplayOptionsSettingsView({ model: this.model });
|
||||||
|
},
|
||||||
|
onRender: function() {
|
||||||
|
var that = this,
|
||||||
|
blockView = this.model.request('blockView');
|
||||||
|
|
||||||
MailPoet.Modal.panel({
|
this.selectionRegion.show(this.selectionView);
|
||||||
element: this.$el,
|
this.displayOptionsRegion.show(this.displayOptionsView);
|
||||||
template: '',
|
|
||||||
position: 'right',
|
|
||||||
overlay: true,
|
|
||||||
highlight: blockView.$el,
|
|
||||||
width: App.getConfig().get('sidepanelWidth'),
|
|
||||||
onCancel: function() {
|
|
||||||
// Self destroy the block if the user closes settings modal
|
|
||||||
that.model.destroy();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
switchToDisplayOptions: function() {
|
|
||||||
// Switch content view
|
|
||||||
this.$('.mailpoet_settings_posts_selection').addClass('mailpoet_hidden');
|
|
||||||
this.$('.mailpoet_settings_posts_display_options').removeClass('mailpoet_hidden');
|
|
||||||
|
|
||||||
// Switch controls
|
MailPoet.Modal.panel({
|
||||||
this.$('.mailpoet_settings_posts_show_display_options').addClass('mailpoet_hidden');
|
element: this.$el,
|
||||||
this.$('.mailpoet_settings_posts_show_post_selection').removeClass('mailpoet_hidden');
|
template: '',
|
||||||
},
|
position: 'right',
|
||||||
switchToPostSelection: function() {
|
overlay: true,
|
||||||
// Switch content view
|
highlight: blockView.$el,
|
||||||
this.$('.mailpoet_settings_posts_display_options').addClass('mailpoet_hidden');
|
width: App.getConfig().get('sidepanelWidth'),
|
||||||
this.$('.mailpoet_settings_posts_selection').removeClass('mailpoet_hidden');
|
onCancel: function() {
|
||||||
|
// Self destroy the block if the user closes settings modal
|
||||||
|
that.model.destroy();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
switchToDisplayOptions: function() {
|
||||||
|
// Switch content view
|
||||||
|
this.$('.mailpoet_settings_posts_selection').addClass('mailpoet_hidden');
|
||||||
|
this.$('.mailpoet_settings_posts_display_options').removeClass('mailpoet_hidden');
|
||||||
|
|
||||||
// Switch controls
|
// Switch controls
|
||||||
this.$('.mailpoet_settings_posts_show_post_selection').addClass('mailpoet_hidden');
|
this.$('.mailpoet_settings_posts_show_display_options').addClass('mailpoet_hidden');
|
||||||
this.$('.mailpoet_settings_posts_show_display_options').removeClass('mailpoet_hidden');
|
this.$('.mailpoet_settings_posts_show_post_selection').removeClass('mailpoet_hidden');
|
||||||
},
|
},
|
||||||
insertPosts: function() {
|
switchToPostSelection: function() {
|
||||||
this.model.trigger('insertSelectedPosts');
|
// Switch content view
|
||||||
this.model.destroy();
|
this.$('.mailpoet_settings_posts_display_options').addClass('mailpoet_hidden');
|
||||||
},
|
this.$('.mailpoet_settings_posts_selection').removeClass('mailpoet_hidden');
|
||||||
});
|
|
||||||
|
|
||||||
var PostSelectionSettingsView = Marionette.CompositeView.extend({
|
// Switch controls
|
||||||
getTemplate: function() { return templates.postSelectionPostsBlockSettings; },
|
this.$('.mailpoet_settings_posts_show_post_selection').addClass('mailpoet_hidden');
|
||||||
getChildView: function() { return SinglePostSelectionSettingsView; },
|
this.$('.mailpoet_settings_posts_show_display_options').removeClass('mailpoet_hidden');
|
||||||
childViewContainer: '.mailpoet_post_selection_container',
|
},
|
||||||
getEmptyView: function() { return EmptyPostSelectionSettingsView; },
|
insertPosts: function() {
|
||||||
childViewOptions: function() {
|
this.model.trigger('insertSelectedPosts');
|
||||||
return {
|
this.model.destroy();
|
||||||
blockModel: this.model,
|
},
|
||||||
};
|
});
|
||||||
},
|
|
||||||
events: function() {
|
|
||||||
return {
|
|
||||||
'change .mailpoet_settings_posts_content_type': _.partial(this.changeField, 'contentType'),
|
|
||||||
'change .mailpoet_posts_post_status': _.partial(this.changeField, 'postStatus'),
|
|
||||||
'keyup .mailpoet_posts_search_term': _.partial(this.changeField, 'search'),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
constructor: function() {
|
|
||||||
// Set the block collection to be handled by this view as well
|
|
||||||
arguments[0].collection = arguments[0].model.get('_availablePosts');
|
|
||||||
Marionette.CompositeView.apply(this, arguments);
|
|
||||||
},
|
|
||||||
onRender: function() {
|
|
||||||
var that = this;
|
|
||||||
|
|
||||||
this.$('.mailpoet_posts_categories_and_tags').select2({
|
var PostSelectionSettingsView = Marionette.CompositeView.extend({
|
||||||
multiple: true,
|
getTemplate: function() { return templates.postSelectionPostsBlockSettings; },
|
||||||
allowClear: true,
|
getChildView: function() { return SinglePostSelectionSettingsView; },
|
||||||
ajax: {
|
childViewContainer: '.mailpoet_post_selection_container',
|
||||||
url: App.getConfig().get('urls.termSearch'),
|
getEmptyView: function() { return EmptyPostSelectionSettingsView; },
|
||||||
type: 'POST',
|
childViewOptions: function() {
|
||||||
dataType: 'json',
|
return {
|
||||||
delay: 250,
|
blockModel: this.model,
|
||||||
data: function(searchParameter, page) {
|
};
|
||||||
return JSON.stringify({
|
},
|
||||||
postType: that.model.get('contentType'),
|
events: function() {
|
||||||
search: searchParameter,
|
return {
|
||||||
limit: 10, // TODO: Move this hardcoded limit to Config
|
'change .mailpoet_settings_posts_content_type': _.partial(this.changeField, 'contentType'),
|
||||||
page: page,
|
'change .mailpoet_posts_post_status': _.partial(this.changeField, 'postStatus'),
|
||||||
});
|
'keyup .mailpoet_posts_search_term': _.partial(this.changeField, 'search'),
|
||||||
},
|
};
|
||||||
/**
|
},
|
||||||
* Parse results for select2.
|
constructor: function() {
|
||||||
* Returns object, where `results` key holds a list of
|
// Set the block collection to be handled by this view as well
|
||||||
* select item objects
|
arguments[0].collection = arguments[0].model.get('_availablePosts');
|
||||||
*/
|
Marionette.CompositeView.apply(this, arguments);
|
||||||
results: function (data, page) {
|
},
|
||||||
return {
|
onRender: function() {
|
||||||
results: _.map(
|
var that = this;
|
||||||
data.results,
|
|
||||||
function(item) {
|
|
||||||
return _.defaults({
|
|
||||||
text: data.taxonomies[item.taxonomy].labels.singular_name + ': ' + item.name,
|
|
||||||
id: item.term_id
|
|
||||||
}, item);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}).trigger( 'change' ).on({
|
|
||||||
'change': function(e){
|
|
||||||
var data = [];
|
|
||||||
|
|
||||||
if (typeof data === 'string') {
|
this.$('.mailpoet_posts_categories_and_tags').select2({
|
||||||
if (data === '') {
|
multiple: true,
|
||||||
data = [];
|
allowClear: true,
|
||||||
} else {
|
ajax: {
|
||||||
data = JSON.parse(data);
|
url: App.getConfig().get('urls.termSearch'),
|
||||||
}
|
type: 'POST',
|
||||||
}
|
dataType: 'json',
|
||||||
|
delay: 250,
|
||||||
|
data: function(searchParameter, page) {
|
||||||
|
return JSON.stringify({
|
||||||
|
postType: that.model.get('contentType'),
|
||||||
|
search: searchParameter,
|
||||||
|
limit: 10, // TODO: Move this hardcoded limit to Config
|
||||||
|
page: page,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Parse results for select2.
|
||||||
|
* Returns object, where `results` key holds a list of
|
||||||
|
* select item objects
|
||||||
|
*/
|
||||||
|
results: function (data, page) {
|
||||||
|
return {
|
||||||
|
results: _.map(
|
||||||
|
data.results,
|
||||||
|
function(item) {
|
||||||
|
return _.defaults({
|
||||||
|
text: data.taxonomies[item.taxonomy].labels.singular_name + ': ' + item.name,
|
||||||
|
id: item.term_id
|
||||||
|
}, item);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}).trigger( 'change' ).on({
|
||||||
|
'change': function(e){
|
||||||
|
var data = [];
|
||||||
|
|
||||||
if ( e.added ){
|
if (typeof data === 'string') {
|
||||||
data.push(e.added);
|
if (data === '') {
|
||||||
}
|
data = [];
|
||||||
|
} else {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update ALC model
|
if ( e.added ){
|
||||||
that.model.set('terms', data);
|
data.push(e.added);
|
||||||
|
}
|
||||||
|
|
||||||
$(this).data('selected', JSON.stringify(data));
|
// Update ALC model
|
||||||
}
|
that.model.set('terms', data);
|
||||||
});
|
|
||||||
},
|
|
||||||
onBeforeDestroy: function() {
|
|
||||||
// Force close select2 if it hasn't closed yet
|
|
||||||
this.$('.mailpoet_posts_categories_and_tags').select2('close');
|
|
||||||
},
|
|
||||||
changeField: function(field, event) {
|
|
||||||
this.model.set(field, jQuery(event.target).val());
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
var EmptyPostSelectionSettingsView = Marionette.ItemView.extend({
|
$(this).data('selected', JSON.stringify(data));
|
||||||
getTemplate: function() { return templates.emptyPostPostsBlockSettings; },
|
}
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
onBeforeDestroy: function() {
|
||||||
|
// Force close select2 if it hasn't closed yet
|
||||||
|
this.$('.mailpoet_posts_categories_and_tags').select2('close');
|
||||||
|
},
|
||||||
|
changeField: function(field, event) {
|
||||||
|
this.model.set(field, jQuery(event.target).val());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
var SinglePostSelectionSettingsView = Marionette.ItemView.extend({
|
var EmptyPostSelectionSettingsView = Marionette.ItemView.extend({
|
||||||
getTemplate: function() { return templates.singlePostPostsBlockSettings; },
|
getTemplate: function() { return templates.emptyPostPostsBlockSettings; },
|
||||||
events: function() {
|
});
|
||||||
return {
|
|
||||||
'change .mailpoet_select_post_checkbox': 'postSelectionChange',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
templateHelpers: function() {
|
|
||||||
return {
|
|
||||||
model: this.model.toJSON(),
|
|
||||||
index: this._index,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
initialize: function(options) {
|
|
||||||
this.blockModel = options.blockModel;
|
|
||||||
},
|
|
||||||
postSelectionChange: function(event) {
|
|
||||||
var checkBox = jQuery(event.target),
|
|
||||||
selectedPostsCollection = this.blockModel.get('_selectedPosts');
|
|
||||||
if (checkBox.prop('checked')) {
|
|
||||||
selectedPostsCollection.add(this.model);
|
|
||||||
} else {
|
|
||||||
selectedPostsCollection.remove(this.model);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
var PostsDisplayOptionsSettingsView = base.BlockSettingsView.extend({
|
var SinglePostSelectionSettingsView = Marionette.ItemView.extend({
|
||||||
getTemplate: function() { return templates.displayOptionsPostsBlockSettings; },
|
getTemplate: function() { return templates.singlePostPostsBlockSettings; },
|
||||||
events: function() {
|
events: function() {
|
||||||
return {
|
return {
|
||||||
"click .mailpoet_posts_select_button": 'showButtonSettings',
|
'change .mailpoet_select_post_checkbox': 'postSelectionChange',
|
||||||
"click .mailpoet_posts_select_divider": 'showDividerSettings',
|
};
|
||||||
"change .mailpoet_posts_read_more_type": 'changeReadMoreType',
|
},
|
||||||
"change .mailpoet_posts_display_type": 'changeDisplayType',
|
templateHelpers: function() {
|
||||||
"change .mailpoet_posts_title_format": 'changeTitleFormat',
|
return {
|
||||||
"change .mailpoet_posts_title_as_links": _.partial(this.changeBoolField, 'titleIsLink'),
|
model: this.model.toJSON(),
|
||||||
"change .mailpoet_posts_show_divider": _.partial(this.changeBoolField, 'showDivider'),
|
index: this._index,
|
||||||
"keyup .mailpoet_posts_show_amount": _.partial(this.changeField, "amount"),
|
};
|
||||||
"change .mailpoet_posts_content_type": _.partial(this.changeField, "contentType"),
|
},
|
||||||
"change .mailpoet_posts_include_or_exclude": _.partial(this.changeField, "inclusionType"),
|
initialize: function(options) {
|
||||||
"change .mailpoet_posts_title_position": _.partial(this.changeField, "titlePosition"),
|
this.blockModel = options.blockModel;
|
||||||
"change .mailpoet_posts_title_alignment": _.partial(this.changeField, "titleAlignment"),
|
},
|
||||||
"change .mailpoet_posts_image_padded": _.partial(this.changeBoolField, "imagePadded"),
|
postSelectionChange: function(event) {
|
||||||
"change .mailpoet_posts_show_author": _.partial(this.changeField, "showAuthor"),
|
var checkBox = jQuery(event.target),
|
||||||
"keyup .mailpoet_posts_author_preceded_by": _.partial(this.changeField, "authorPrecededBy"),
|
selectedPostsCollection = this.blockModel.get('_selectedPosts');
|
||||||
"change .mailpoet_posts_show_categories": _.partial(this.changeField, "showCategories"),
|
if (checkBox.prop('checked')) {
|
||||||
"keyup .mailpoet_posts_categories": _.partial(this.changeField, "categoriesPrecededBy"),
|
selectedPostsCollection.add(this.model);
|
||||||
"keyup .mailpoet_posts_read_more_text": _.partial(this.changeField, "readMoreText"),
|
} else {
|
||||||
"change .mailpoet_posts_sort_by": _.partial(this.changeField, "sortBy"),
|
selectedPostsCollection.remove(this.model);
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
behaviors: {
|
});
|
||||||
ColorPickerBehavior: {},
|
|
||||||
},
|
|
||||||
templateHelpers: function() {
|
|
||||||
return {
|
|
||||||
model: this.model.toJSON(),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
showButtonSettings: function(event) {
|
|
||||||
var buttonModule = App.module('blocks.button');
|
|
||||||
(new buttonModule.ButtonBlockSettingsView({
|
|
||||||
model: this.model.get('readMoreButton'),
|
|
||||||
renderOptions: {
|
|
||||||
displayFormat: 'subpanel',
|
|
||||||
hideLink: true,
|
|
||||||
hideApplyToAll: true,
|
|
||||||
},
|
|
||||||
})).render();
|
|
||||||
},
|
|
||||||
showDividerSettings: function(event) {
|
|
||||||
var dividerModule = App.module('blocks.divider');
|
|
||||||
(new dividerModule.DividerBlockSettingsView({
|
|
||||||
model: this.model.get('divider'),
|
|
||||||
renderOptions: {
|
|
||||||
displayFormat: 'subpanel',
|
|
||||||
hideApplyToAll: true,
|
|
||||||
},
|
|
||||||
})).render();
|
|
||||||
},
|
|
||||||
changeReadMoreType: function(event) {
|
|
||||||
var value = jQuery(event.target).val();
|
|
||||||
if (value == 'link') {
|
|
||||||
this.$('.mailpoet_posts_read_more_text').removeClass('mailpoet_hidden');
|
|
||||||
this.$('.mailpoet_posts_select_button').addClass('mailpoet_hidden');
|
|
||||||
} else if (value == 'button') {
|
|
||||||
this.$('.mailpoet_posts_read_more_text').addClass('mailpoet_hidden');
|
|
||||||
this.$('.mailpoet_posts_select_button').removeClass('mailpoet_hidden');
|
|
||||||
}
|
|
||||||
this.changeField('readMoreType', event);
|
|
||||||
},
|
|
||||||
changeDisplayType: function(event) {
|
|
||||||
var value = jQuery(event.target).val();
|
|
||||||
if (value == 'titleOnly') {
|
|
||||||
this.$('.mailpoet_posts_title_position_container').addClass('mailpoet_hidden');
|
|
||||||
this.$('.mailpoet_posts_title_as_list').removeClass('mailpoet_hidden');
|
|
||||||
} else {
|
|
||||||
this.$('.mailpoet_posts_title_position_container').removeClass('mailpoet_hidden');
|
|
||||||
this.$('.mailpoet_posts_title_as_list').addClass('mailpoet_hidden');
|
|
||||||
|
|
||||||
// Reset titleFormat if it was set to List when switching away from displayType=titleOnly
|
var PostsDisplayOptionsSettingsView = base.BlockSettingsView.extend({
|
||||||
if (this.model.get('titleFormat') === 'ul') {
|
getTemplate: function() { return templates.displayOptionsPostsBlockSettings; },
|
||||||
this.model.set('titleFormat', 'h1');
|
events: function() {
|
||||||
this.$('.mailpoet_posts_title_format').val(['h1']);
|
return {
|
||||||
this.$('.mailpoet_posts_title_as_link').removeClass('mailpoet_hidden');
|
"click .mailpoet_posts_select_button": 'showButtonSettings',
|
||||||
}
|
"click .mailpoet_posts_select_divider": 'showDividerSettings',
|
||||||
}
|
"change .mailpoet_posts_read_more_type": 'changeReadMoreType',
|
||||||
this.changeField('displayType', event);
|
"change .mailpoet_posts_display_type": 'changeDisplayType',
|
||||||
},
|
"change .mailpoet_posts_title_format": 'changeTitleFormat',
|
||||||
changeTitleFormat: function(event) {
|
"change .mailpoet_posts_title_as_links": _.partial(this.changeBoolField, 'titleIsLink'),
|
||||||
var value = jQuery(event.target).val();
|
"change .mailpoet_posts_show_divider": _.partial(this.changeBoolField, 'showDivider'),
|
||||||
if (value == 'ul') {
|
"keyup .mailpoet_posts_show_amount": _.partial(this.changeField, "amount"),
|
||||||
this.$('.mailpoet_posts_non_title_list_options').addClass('mailpoet_hidden');
|
"change .mailpoet_posts_content_type": _.partial(this.changeField, "contentType"),
|
||||||
|
"change .mailpoet_posts_include_or_exclude": _.partial(this.changeField, "inclusionType"),
|
||||||
|
"change .mailpoet_posts_title_position": _.partial(this.changeField, "titlePosition"),
|
||||||
|
"change .mailpoet_posts_title_alignment": _.partial(this.changeField, "titleAlignment"),
|
||||||
|
"change .mailpoet_posts_image_padded": _.partial(this.changeBoolField, "imagePadded"),
|
||||||
|
"change .mailpoet_posts_show_author": _.partial(this.changeField, "showAuthor"),
|
||||||
|
"keyup .mailpoet_posts_author_preceded_by": _.partial(this.changeField, "authorPrecededBy"),
|
||||||
|
"change .mailpoet_posts_show_categories": _.partial(this.changeField, "showCategories"),
|
||||||
|
"keyup .mailpoet_posts_categories": _.partial(this.changeField, "categoriesPrecededBy"),
|
||||||
|
"keyup .mailpoet_posts_read_more_text": _.partial(this.changeField, "readMoreText"),
|
||||||
|
"change .mailpoet_posts_sort_by": _.partial(this.changeField, "sortBy"),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
behaviors: {
|
||||||
|
ColorPickerBehavior: {},
|
||||||
|
},
|
||||||
|
templateHelpers: function() {
|
||||||
|
return {
|
||||||
|
model: this.model.toJSON(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
showButtonSettings: function(event) {
|
||||||
|
var buttonModule = App.module('blocks.button');
|
||||||
|
(new buttonModule.ButtonBlockSettingsView({
|
||||||
|
model: this.model.get('readMoreButton'),
|
||||||
|
renderOptions: {
|
||||||
|
displayFormat: 'subpanel',
|
||||||
|
hideLink: true,
|
||||||
|
hideApplyToAll: true,
|
||||||
|
},
|
||||||
|
})).render();
|
||||||
|
},
|
||||||
|
showDividerSettings: function(event) {
|
||||||
|
var dividerModule = App.module('blocks.divider');
|
||||||
|
(new dividerModule.DividerBlockSettingsView({
|
||||||
|
model: this.model.get('divider'),
|
||||||
|
renderOptions: {
|
||||||
|
displayFormat: 'subpanel',
|
||||||
|
hideApplyToAll: true,
|
||||||
|
},
|
||||||
|
})).render();
|
||||||
|
},
|
||||||
|
changeReadMoreType: function(event) {
|
||||||
|
var value = jQuery(event.target).val();
|
||||||
|
if (value == 'link') {
|
||||||
|
this.$('.mailpoet_posts_read_more_text').removeClass('mailpoet_hidden');
|
||||||
|
this.$('.mailpoet_posts_select_button').addClass('mailpoet_hidden');
|
||||||
|
} else if (value == 'button') {
|
||||||
|
this.$('.mailpoet_posts_read_more_text').addClass('mailpoet_hidden');
|
||||||
|
this.$('.mailpoet_posts_select_button').removeClass('mailpoet_hidden');
|
||||||
|
}
|
||||||
|
this.changeField('readMoreType', event);
|
||||||
|
},
|
||||||
|
changeDisplayType: function(event) {
|
||||||
|
var value = jQuery(event.target).val();
|
||||||
|
if (value == 'titleOnly') {
|
||||||
|
this.$('.mailpoet_posts_title_position_container').addClass('mailpoet_hidden');
|
||||||
|
this.$('.mailpoet_posts_title_as_list').removeClass('mailpoet_hidden');
|
||||||
|
} else {
|
||||||
|
this.$('.mailpoet_posts_title_position_container').removeClass('mailpoet_hidden');
|
||||||
|
this.$('.mailpoet_posts_title_as_list').addClass('mailpoet_hidden');
|
||||||
|
|
||||||
this.model.set('titleIsLink', true);
|
// Reset titleFormat if it was set to List when switching away from displayType=titleOnly
|
||||||
this.$('.mailpoet_posts_title_as_link').addClass('mailpoet_hidden');
|
if (this.model.get('titleFormat') === 'ul') {
|
||||||
this.$('.mailpoet_posts_title_as_links').val(['true']);
|
this.model.set('titleFormat', 'h1');
|
||||||
} else {
|
this.$('.mailpoet_posts_title_format').val(['h1']);
|
||||||
this.$('.mailpoet_posts_non_title_list_options').removeClass('mailpoet_hidden');
|
this.$('.mailpoet_posts_title_as_link').removeClass('mailpoet_hidden');
|
||||||
this.$('.mailpoet_posts_title_as_link').removeClass('mailpoet_hidden');
|
}
|
||||||
}
|
}
|
||||||
this.changeField('titleFormat', event);
|
this.changeField('displayType', event);
|
||||||
},
|
},
|
||||||
});
|
changeTitleFormat: function(event) {
|
||||||
|
var value = jQuery(event.target).val();
|
||||||
|
if (value == 'ul') {
|
||||||
|
this.$('.mailpoet_posts_non_title_list_options').addClass('mailpoet_hidden');
|
||||||
|
|
||||||
Module.PostsWidgetView = base.WidgetView.extend({
|
this.model.set('titleIsLink', true);
|
||||||
getTemplate: function() { return templates.postsInsertion; },
|
this.$('.mailpoet_posts_title_as_link').addClass('mailpoet_hidden');
|
||||||
behaviors: {
|
this.$('.mailpoet_posts_title_as_links').val(['true']);
|
||||||
DraggableBehavior: {
|
} else {
|
||||||
cloneOriginal: true,
|
this.$('.mailpoet_posts_non_title_list_options').removeClass('mailpoet_hidden');
|
||||||
drop: function() {
|
this.$('.mailpoet_posts_title_as_link').removeClass('mailpoet_hidden');
|
||||||
return new Module.PostsBlockModel({}, { parse: true });
|
}
|
||||||
}
|
this.changeField('titleFormat', event);
|
||||||
}
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
App.on('before:start', function() {
|
Module.PostsWidgetView = base.WidgetView.extend({
|
||||||
App.registerBlockType('posts', {
|
getTemplate: function() { return templates.postsInsertion; },
|
||||||
blockModel: Module.PostsBlockModel,
|
behaviors: {
|
||||||
blockView: Module.PostsBlockView,
|
DraggableBehavior: {
|
||||||
});
|
cloneOriginal: true,
|
||||||
|
drop: function() {
|
||||||
|
return new Module.PostsBlockModel({}, { parse: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
App.on('before:start', function() {
|
||||||
|
App.registerBlockType('posts', {
|
||||||
|
blockModel: Module.PostsBlockModel,
|
||||||
|
blockView: Module.PostsBlockView,
|
||||||
|
});
|
||||||
|
|
||||||
|
App.registerWidget({
|
||||||
|
name: 'posts',
|
||||||
|
widgetView: Module.PostsWidgetView,
|
||||||
|
priority: 96,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.registerWidget({
|
|
||||||
name: 'posts',
|
|
||||||
widgetView: Module.PostsWidgetView,
|
|
||||||
priority: 96,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,365 +1,375 @@
|
|||||||
/**
|
/**
|
||||||
* Social icons content block
|
* Social icons content block
|
||||||
*/
|
*/
|
||||||
EditorApplication.module("blocks.social", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/blocks/social', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
'mailpoet',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette, MailPoet) {
|
||||||
|
|
||||||
var base = App.module('blocks.base'),
|
EditorApplication.module("blocks.social", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
SocialBlockSettingsIconSelectorView, SocialBlockSettingsIconView, SocialBlockSettingsStylesView;
|
"use strict";
|
||||||
|
|
||||||
Module.SocialIconModel = Backbone.SuperModel.extend({
|
var base = App.module('blocks.base'),
|
||||||
defaults: function() {
|
SocialBlockSettingsIconSelectorView, SocialBlockSettingsIconView, SocialBlockSettingsStylesView;
|
||||||
var defaultValues = App.getConfig().get('socialIcons.custom');
|
|
||||||
return {
|
|
||||||
type: 'socialIcon',
|
|
||||||
iconType: 'custom',
|
|
||||||
link: defaultValues.get('defaultLink'),
|
|
||||||
image: App.getAvailableStyles().get('socialIconSets.default.custom'),
|
|
||||||
height: '32px',
|
|
||||||
width: '32px',
|
|
||||||
text: defaultValues.get('title'),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
initialize: function(options) {
|
|
||||||
var that = this;
|
|
||||||
// Make model swap to default values for that type when iconType changes
|
|
||||||
this.on('change:iconType', function() {
|
|
||||||
var defaultValues = App.getConfig().get('socialIcons').get(that.get('iconType')),
|
|
||||||
iconSet = that.collection.iconBlockModel.getIconSet();
|
|
||||||
this.set({
|
|
||||||
link: defaultValues.get('defaultLink'),
|
|
||||||
image: iconSet.get(that.get('iconType')),
|
|
||||||
text: defaultValues.get('title'),
|
|
||||||
});
|
|
||||||
}, this);
|
|
||||||
this.on('change', function() { App.getChannel().trigger('autoSave'); });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.SocialIconCollectionModel = Backbone.Collection.extend({
|
Module.SocialIconModel = SuperModel.extend({
|
||||||
model: Module.SocialIconModel
|
defaults: function() {
|
||||||
});
|
var defaultValues = App.getConfig().get('socialIcons.custom');
|
||||||
|
return {
|
||||||
|
type: 'socialIcon',
|
||||||
|
iconType: 'custom',
|
||||||
|
link: defaultValues.get('defaultLink'),
|
||||||
|
image: App.getAvailableStyles().get('socialIconSets.default.custom'),
|
||||||
|
height: '32px',
|
||||||
|
width: '32px',
|
||||||
|
text: defaultValues.get('title'),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
initialize: function(options) {
|
||||||
|
var that = this;
|
||||||
|
// Make model swap to default values for that type when iconType changes
|
||||||
|
this.on('change:iconType', function() {
|
||||||
|
var defaultValues = App.getConfig().get('socialIcons').get(that.get('iconType')),
|
||||||
|
iconSet = that.collection.iconBlockModel.getIconSet();
|
||||||
|
this.set({
|
||||||
|
link: defaultValues.get('defaultLink'),
|
||||||
|
image: iconSet.get(that.get('iconType')),
|
||||||
|
text: defaultValues.get('title'),
|
||||||
|
});
|
||||||
|
}, this);
|
||||||
|
this.on('change', function() { App.getChannel().trigger('autoSave'); });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Module.SocialBlockModel = base.BlockModel.extend({
|
Module.SocialIconCollectionModel = Backbone.Collection.extend({
|
||||||
name: 'iconBlockModel',
|
model: Module.SocialIconModel
|
||||||
defaults: function() {
|
});
|
||||||
return this._getDefaults({
|
|
||||||
type: 'social',
|
|
||||||
iconSet: 'default',
|
|
||||||
icons: new Module.SocialIconCollectionModel(),
|
|
||||||
}, EditorApplication.getConfig().get('blockDefaults.social'));
|
|
||||||
},
|
|
||||||
relations: {
|
|
||||||
icons: Module.SocialIconCollectionModel,
|
|
||||||
},
|
|
||||||
initialize: function() {
|
|
||||||
this.get('icons').on('add remove change', this._iconsChanged, this);
|
|
||||||
this.on('change:iconSet', this.changeIconSet, this);
|
|
||||||
},
|
|
||||||
getIconSet: function() {
|
|
||||||
return App.getAvailableStyles().get('socialIconSets').get(this.get('iconSet'));
|
|
||||||
},
|
|
||||||
changeIconSet: function() {
|
|
||||||
var iconSet = this.getIconSet();
|
|
||||||
_.each(this.get('icons').models, function(model) {
|
|
||||||
model.set('image', iconSet.get(model.get('iconType')));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
_iconsChanged: function() {
|
|
||||||
App.getChannel().trigger('autoSave');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
var SocialIconView = Marionette.ItemView.extend({
|
Module.SocialBlockModel = base.BlockModel.extend({
|
||||||
tagName: 'span',
|
name: 'iconBlockModel',
|
||||||
getTemplate: function() { return templates.socialIconBlock; },
|
defaults: function() {
|
||||||
modelEvents: {
|
return this._getDefaults({
|
||||||
'change': 'render',
|
type: 'social',
|
||||||
},
|
iconSet: 'default',
|
||||||
templateHelpers: function() {
|
icons: new Module.SocialIconCollectionModel(),
|
||||||
var allIconSets = App.getAvailableStyles().get('socialIconSets');
|
}, EditorApplication.getConfig().get('blockDefaults.social'));
|
||||||
return {
|
},
|
||||||
model: this.model.toJSON(),
|
relations: {
|
||||||
allIconSets: allIconSets.toJSON(),
|
icons: Module.SocialIconCollectionModel,
|
||||||
};
|
},
|
||||||
},
|
initialize: function() {
|
||||||
});
|
this.get('icons').on('add remove change', this._iconsChanged, this);
|
||||||
|
this.on('change:iconSet', this.changeIconSet, this);
|
||||||
|
},
|
||||||
|
getIconSet: function() {
|
||||||
|
return App.getAvailableStyles().get('socialIconSets').get(this.get('iconSet'));
|
||||||
|
},
|
||||||
|
changeIconSet: function() {
|
||||||
|
var iconSet = this.getIconSet();
|
||||||
|
_.each(this.get('icons').models, function(model) {
|
||||||
|
model.set('image', iconSet.get(model.get('iconType')));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_iconsChanged: function() {
|
||||||
|
App.getChannel().trigger('autoSave');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Module.SocialBlockView = Marionette.CompositeView.extend({
|
var SocialIconView = Marionette.ItemView.extend({
|
||||||
regionClass: Marionette.Region,
|
tagName: 'span',
|
||||||
className: 'mailpoet_block mailpoet_social_block mailpoet_droppable_block',
|
getTemplate: function() { return templates.socialIconBlock; },
|
||||||
getTemplate: function() { return templates.socialBlock; },
|
modelEvents: {
|
||||||
childViewContainer: '.mailpoet_social',
|
'change': 'render',
|
||||||
modelEvents: {
|
},
|
||||||
'change': 'render'
|
templateHelpers: function() {
|
||||||
},
|
var allIconSets = App.getAvailableStyles().get('socialIconSets');
|
||||||
events: {
|
return {
|
||||||
"mouseover": "showTools",
|
model: this.model.toJSON(),
|
||||||
"mouseout": "hideTools",
|
allIconSets: allIconSets.toJSON(),
|
||||||
},
|
};
|
||||||
regions: {
|
},
|
||||||
toolsRegion: '> .mailpoet_tools',
|
});
|
||||||
},
|
|
||||||
ui: {
|
|
||||||
tools: '> .mailpoet_tools'
|
|
||||||
},
|
|
||||||
behaviors: {
|
|
||||||
DraggableBehavior: {
|
|
||||||
cloneOriginal: true,
|
|
||||||
hideOriginal: true,
|
|
||||||
onDrop: function(options) {
|
|
||||||
// After a clone of model has been dropped, cleanup
|
|
||||||
// and destroy self
|
|
||||||
options.dragBehavior.view.model.destroy();
|
|
||||||
},
|
|
||||||
onDragSubstituteBy: function(behavior) {
|
|
||||||
var WidgetView, node;
|
|
||||||
// When block is being dragged, display the widget icon instead.
|
|
||||||
// This will create an instance of block's widget view and
|
|
||||||
// use it's rendered DOM element instead of the content block
|
|
||||||
if (_.isFunction(behavior.view.onDragSubstituteBy)) {
|
|
||||||
WidgetView = new (behavior.view.onDragSubstituteBy())();
|
|
||||||
WidgetView.render();
|
|
||||||
node = WidgetView.$el.get(0).cloneNode(true);
|
|
||||||
WidgetView.destroy();
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
onDragSubstituteBy: function() { return Module.SocialWidgetView; },
|
|
||||||
constructor: function() {
|
|
||||||
// Set the block collection to be handled by this view as well
|
|
||||||
arguments[0].collection = arguments[0].model.get('icons');
|
|
||||||
Marionette.CompositeView.apply(this, arguments);
|
|
||||||
},
|
|
||||||
// Determines which view type should be used for a child
|
|
||||||
childView: SocialIconView,
|
|
||||||
templateHelpers: function() {
|
|
||||||
return {
|
|
||||||
model: this.model.toJSON(),
|
|
||||||
viewCid: this.cid,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
onRender: function() {
|
|
||||||
this._rebuildRegions();
|
|
||||||
this.toolsView = new Module.SocialBlockToolsView({ model: this.model });
|
|
||||||
this.toolsRegion.show(this.toolsView);
|
|
||||||
},
|
|
||||||
onBeforeDestroy: function() {
|
|
||||||
this.regionManager.destroy();
|
|
||||||
},
|
|
||||||
showTools: function(_event) {
|
|
||||||
this.$(this.ui.tools).show();
|
|
||||||
_event.stopPropagation();
|
|
||||||
},
|
|
||||||
hideTools: function(_event) {
|
|
||||||
this.$(this.ui.tools).hide();
|
|
||||||
_event.stopPropagation();
|
|
||||||
},
|
|
||||||
getDropFunc: function() {
|
|
||||||
var that = this;
|
|
||||||
return function() {
|
|
||||||
var newModel = that.model.clone();
|
|
||||||
//that.model.destroy();
|
|
||||||
return newModel;
|
|
||||||
};
|
|
||||||
},
|
|
||||||
_buildRegions: function(regions) {
|
|
||||||
var that = this;
|
|
||||||
|
|
||||||
var defaults = {
|
Module.SocialBlockView = Marionette.CompositeView.extend({
|
||||||
regionClass: this.getOption('regionClass'),
|
regionClass: Marionette.Region,
|
||||||
parentEl: function() { return that.$el; }
|
className: 'mailpoet_block mailpoet_social_block mailpoet_droppable_block',
|
||||||
};
|
getTemplate: function() { return templates.socialBlock; },
|
||||||
|
childViewContainer: '.mailpoet_social',
|
||||||
|
modelEvents: {
|
||||||
|
'change': 'render'
|
||||||
|
},
|
||||||
|
events: {
|
||||||
|
"mouseover": "showTools",
|
||||||
|
"mouseout": "hideTools",
|
||||||
|
},
|
||||||
|
regions: {
|
||||||
|
toolsRegion: '> .mailpoet_tools',
|
||||||
|
},
|
||||||
|
ui: {
|
||||||
|
tools: '> .mailpoet_tools'
|
||||||
|
},
|
||||||
|
behaviors: {
|
||||||
|
DraggableBehavior: {
|
||||||
|
cloneOriginal: true,
|
||||||
|
hideOriginal: true,
|
||||||
|
onDrop: function(options) {
|
||||||
|
// After a clone of model has been dropped, cleanup
|
||||||
|
// and destroy self
|
||||||
|
options.dragBehavior.view.model.destroy();
|
||||||
|
},
|
||||||
|
onDragSubstituteBy: function(behavior) {
|
||||||
|
var WidgetView, node;
|
||||||
|
// When block is being dragged, display the widget icon instead.
|
||||||
|
// This will create an instance of block's widget view and
|
||||||
|
// use it's rendered DOM element instead of the content block
|
||||||
|
if (_.isFunction(behavior.view.onDragSubstituteBy)) {
|
||||||
|
WidgetView = new (behavior.view.onDragSubstituteBy())();
|
||||||
|
WidgetView.render();
|
||||||
|
node = WidgetView.$el.get(0).cloneNode(true);
|
||||||
|
WidgetView.destroy();
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onDragSubstituteBy: function() { return Module.SocialWidgetView; },
|
||||||
|
constructor: function() {
|
||||||
|
// Set the block collection to be handled by this view as well
|
||||||
|
arguments[0].collection = arguments[0].model.get('icons');
|
||||||
|
Marionette.CompositeView.apply(this, arguments);
|
||||||
|
},
|
||||||
|
// Determines which view type should be used for a child
|
||||||
|
childView: SocialIconView,
|
||||||
|
templateHelpers: function() {
|
||||||
|
return {
|
||||||
|
model: this.model.toJSON(),
|
||||||
|
viewCid: this.cid,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onRender: function() {
|
||||||
|
this._rebuildRegions();
|
||||||
|
this.toolsView = new Module.SocialBlockToolsView({ model: this.model });
|
||||||
|
this.toolsRegion.show(this.toolsView);
|
||||||
|
},
|
||||||
|
onBeforeDestroy: function() {
|
||||||
|
this.regionManager.destroy();
|
||||||
|
},
|
||||||
|
showTools: function(_event) {
|
||||||
|
this.$(this.ui.tools).show();
|
||||||
|
_event.stopPropagation();
|
||||||
|
},
|
||||||
|
hideTools: function(_event) {
|
||||||
|
this.$(this.ui.tools).hide();
|
||||||
|
_event.stopPropagation();
|
||||||
|
},
|
||||||
|
getDropFunc: function() {
|
||||||
|
var that = this;
|
||||||
|
return function() {
|
||||||
|
var newModel = that.model.clone();
|
||||||
|
//that.model.destroy();
|
||||||
|
return newModel;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
_buildRegions: function(regions) {
|
||||||
|
var that = this;
|
||||||
|
|
||||||
return this.regionManager.addRegions(regions, defaults);
|
var defaults = {
|
||||||
},
|
regionClass: this.getOption('regionClass'),
|
||||||
_rebuildRegions: function() {
|
parentEl: function() { return that.$el; }
|
||||||
if (this.regionManager === undefined) {
|
};
|
||||||
this.regionManager = new Backbone.Marionette.RegionManager();
|
|
||||||
}
|
|
||||||
this.regionManager.destroy();
|
|
||||||
_.extend(this, this._buildRegions(this.regions));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.SocialBlockToolsView = base.BlockToolsView.extend({
|
return this.regionManager.addRegions(regions, defaults);
|
||||||
getSettingsView: function() { return Module.SocialBlockSettingsView; },
|
},
|
||||||
});
|
_rebuildRegions: function() {
|
||||||
|
if (this.regionManager === undefined) {
|
||||||
|
this.regionManager = new Backbone.Marionette.RegionManager();
|
||||||
|
}
|
||||||
|
this.regionManager.destroy();
|
||||||
|
_.extend(this, this._buildRegions(this.regions));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// Sidebar view container
|
Module.SocialBlockToolsView = base.BlockToolsView.extend({
|
||||||
Module.SocialBlockSettingsView = base.BlockSettingsView.extend({
|
getSettingsView: function() { return Module.SocialBlockSettingsView; },
|
||||||
getTemplate: function() { return templates.socialBlockSettings; },
|
});
|
||||||
regions: {
|
|
||||||
iconRegion: '#mailpoet_social_icons_selection',
|
|
||||||
stylesRegion: '#mailpoet_social_icons_styles',
|
|
||||||
},
|
|
||||||
events: function() {
|
|
||||||
return {
|
|
||||||
"click .mailpoet_done_editing": "close",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
initialize: function() {
|
|
||||||
base.BlockSettingsView.prototype.initialize.apply(this, arguments);
|
|
||||||
|
|
||||||
this._iconSelectorView = new SocialBlockSettingsIconSelectorView({ model: this.model });
|
// Sidebar view container
|
||||||
this._stylesView = new SocialBlockSettingsStylesView({ model: this.model });
|
Module.SocialBlockSettingsView = base.BlockSettingsView.extend({
|
||||||
},
|
getTemplate: function() { return templates.socialBlockSettings; },
|
||||||
onRender: function() {
|
regions: {
|
||||||
this.iconRegion.show(this._iconSelectorView);
|
iconRegion: '#mailpoet_social_icons_selection',
|
||||||
this.stylesRegion.show(this._stylesView);
|
stylesRegion: '#mailpoet_social_icons_styles',
|
||||||
}
|
},
|
||||||
});
|
events: function() {
|
||||||
|
return {
|
||||||
|
"click .mailpoet_done_editing": "close",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
initialize: function() {
|
||||||
|
base.BlockSettingsView.prototype.initialize.apply(this, arguments);
|
||||||
|
|
||||||
// Single icon settings view, used by the selector view
|
this._iconSelectorView = new SocialBlockSettingsIconSelectorView({ model: this.model });
|
||||||
SocialBlockSettingsIconView = Marionette.ItemView.extend({
|
this._stylesView = new SocialBlockSettingsStylesView({ model: this.model });
|
||||||
getTemplate: function() { return templates.socialSettingsIcon; },
|
},
|
||||||
events: function() {
|
onRender: function() {
|
||||||
return {
|
this.iconRegion.show(this._iconSelectorView);
|
||||||
"click .mailpoet_delete_block": "deleteIcon",
|
this.stylesRegion.show(this._stylesView);
|
||||||
"change .mailpoet_social_icon_field_type": _.partial(this.changeField, "iconType"),
|
}
|
||||||
"keyup .mailpoet_social_icon_field_image": _.partial(this.changeField, "image"),
|
});
|
||||||
"keyup .mailpoet_social_icon_field_link": this.changeLink,
|
|
||||||
"keyup .mailpoet_social_icon_field_text": _.partial(this.changeField, "text"),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
modelEvents: {
|
|
||||||
'change:iconType': 'render',
|
|
||||||
'change:image': function() {
|
|
||||||
this.$('.mailpoet_social_icon_image').attr('src', this.model.get('image'));
|
|
||||||
},
|
|
||||||
'change:text': function() {
|
|
||||||
this.$('.mailpoet_social_icon_image').attr('alt', this.model.get('text'));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
templateHelpers: function() {
|
|
||||||
var icons = App.getConfig().get('socialIcons'),
|
|
||||||
// Construct icon type list of format [{iconType: 'type', title: 'Title'}, ...]
|
|
||||||
availableIconTypes = _.map(_.keys(icons.attributes), function(key) { return { iconType: key, title: icons.get(key).get('title') }; }),
|
|
||||||
allIconSets = App.getAvailableStyles().get('socialIconSets');
|
|
||||||
return {
|
|
||||||
model: this.model.toJSON(),
|
|
||||||
iconTypes: availableIconTypes,
|
|
||||||
currentType: icons.get(this.model.get('iconType')).toJSON(),
|
|
||||||
allIconSets: allIconSets.toJSON(),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
deleteIcon: function() {
|
|
||||||
this.model.destroy();
|
|
||||||
},
|
|
||||||
changeLink: function(event) {
|
|
||||||
if (this.model.get('iconType') === 'email') {
|
|
||||||
this.model.set('link', 'mailto:' + jQuery(event.target).val());
|
|
||||||
} else {
|
|
||||||
return this.changeField('link', event);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
changeField: function(field, event) {
|
|
||||||
this.model.set(field, jQuery(event.target).val());
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Select icons section container view
|
// Single icon settings view, used by the selector view
|
||||||
SocialBlockSettingsIconSelectorView = Marionette.CompositeView.extend({
|
SocialBlockSettingsIconView = Marionette.ItemView.extend({
|
||||||
getTemplate: function() { return templates.socialSettingsIconSelector; },
|
getTemplate: function() { return templates.socialSettingsIcon; },
|
||||||
childView: SocialBlockSettingsIconView,
|
events: function() {
|
||||||
childViewContainer: '#mailpoet_social_icon_selector_contents',
|
return {
|
||||||
events: {
|
"click .mailpoet_delete_block": "deleteIcon",
|
||||||
'click .mailpoet_add_social_icon': 'addSocialIcon',
|
"change .mailpoet_social_icon_field_type": _.partial(this.changeField, "iconType"),
|
||||||
},
|
"keyup .mailpoet_social_icon_field_image": _.partial(this.changeField, "image"),
|
||||||
modelEvents: {
|
"keyup .mailpoet_social_icon_field_link": this.changeLink,
|
||||||
'change:iconSet': 'render',
|
"keyup .mailpoet_social_icon_field_text": _.partial(this.changeField, "text"),
|
||||||
},
|
};
|
||||||
behaviors: {
|
},
|
||||||
SortableBehavior: {
|
modelEvents: {
|
||||||
items: '#mailpoet_social_icon_selector_contents > div',
|
'change:iconType': 'render',
|
||||||
},
|
'change:image': function() {
|
||||||
},
|
this.$('.mailpoet_social_icon_image').attr('src', this.model.get('image'));
|
||||||
constructor: function() {
|
},
|
||||||
// Set the icon collection to be handled by this view as well
|
'change:text': function() {
|
||||||
arguments[0].collection = arguments[0].model.get('icons');
|
this.$('.mailpoet_social_icon_image').attr('alt', this.model.get('text'));
|
||||||
Marionette.CompositeView.apply(this, arguments);
|
},
|
||||||
},
|
},
|
||||||
addSocialIcon: function() {
|
templateHelpers: function() {
|
||||||
// Add a social icon with default values
|
var icons = App.getConfig().get('socialIcons'),
|
||||||
this.collection.add({});
|
// Construct icon type list of format [{iconType: 'type', title: 'Title'}, ...]
|
||||||
}
|
availableIconTypes = _.map(_.keys(icons.attributes), function(key) { return { iconType: key, title: icons.get(key).get('title') }; }),
|
||||||
});
|
allIconSets = App.getAvailableStyles().get('socialIconSets');
|
||||||
|
return {
|
||||||
|
model: this.model.toJSON(),
|
||||||
|
iconTypes: availableIconTypes,
|
||||||
|
currentType: icons.get(this.model.get('iconType')).toJSON(),
|
||||||
|
allIconSets: allIconSets.toJSON(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
deleteIcon: function() {
|
||||||
|
this.model.destroy();
|
||||||
|
},
|
||||||
|
changeLink: function(event) {
|
||||||
|
if (this.model.get('iconType') === 'email') {
|
||||||
|
this.model.set('link', 'mailto:' + jQuery(event.target).val());
|
||||||
|
} else {
|
||||||
|
return this.changeField('link', event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
changeField: function(field, event) {
|
||||||
|
this.model.set(field, jQuery(event.target).val());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
SocialBlockSettingsStylesView = Marionette.ItemView.extend({
|
// Select icons section container view
|
||||||
getTemplate: function() { return templates.socialSettingsStyles; },
|
SocialBlockSettingsIconSelectorView = Marionette.CompositeView.extend({
|
||||||
modelEvents: {
|
getTemplate: function() { return templates.socialSettingsIconSelector; },
|
||||||
'change': 'render',
|
childView: SocialBlockSettingsIconView,
|
||||||
},
|
childViewContainer: '#mailpoet_social_icon_selector_contents',
|
||||||
events: {
|
events: {
|
||||||
'click .mailpoet_social_icon_set': 'changeSocialIconSet',
|
'click .mailpoet_add_social_icon': 'addSocialIcon',
|
||||||
},
|
},
|
||||||
initialize: function() {
|
modelEvents: {
|
||||||
this.listenTo(this.model.get('icons'), 'add remove change', this.render);
|
'change:iconSet': 'render',
|
||||||
},
|
},
|
||||||
templateHelpers: function() {
|
behaviors: {
|
||||||
var allIconSets = App.getAvailableStyles().get('socialIconSets');
|
SortableBehavior: {
|
||||||
return {
|
items: '#mailpoet_social_icon_selector_contents > div',
|
||||||
activeSet: this.model.get('iconSet'),
|
},
|
||||||
socialIconSets: allIconSets.toJSON(),
|
},
|
||||||
availableSets: _.keys(allIconSets.toJSON()),
|
constructor: function() {
|
||||||
availableSocialIcons: this.model.get('icons').pluck('iconType'),
|
// Set the icon collection to be handled by this view as well
|
||||||
};
|
arguments[0].collection = arguments[0].model.get('icons');
|
||||||
},
|
Marionette.CompositeView.apply(this, arguments);
|
||||||
changeSocialIconSet: function(event) {
|
},
|
||||||
this.model.set('iconSet', jQuery(event.currentTarget).data('setname'));
|
addSocialIcon: function() {
|
||||||
},
|
// Add a social icon with default values
|
||||||
onBeforeDestroy: function() {
|
this.collection.add({});
|
||||||
this.model.get('icons').off('add remove', this.render, this);
|
}
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
Module.SocialWidgetView = base.WidgetView.extend({
|
SocialBlockSettingsStylesView = Marionette.ItemView.extend({
|
||||||
getTemplate: function() { return templates.socialInsertion; },
|
getTemplate: function() { return templates.socialSettingsStyles; },
|
||||||
behaviors: {
|
modelEvents: {
|
||||||
DraggableBehavior: {
|
'change': 'render',
|
||||||
cloneOriginal: true,
|
},
|
||||||
drop: function() {
|
events: {
|
||||||
return new Module.SocialBlockModel({
|
'click .mailpoet_social_icon_set': 'changeSocialIconSet',
|
||||||
type: 'social',
|
},
|
||||||
iconSet: 'default',
|
initialize: function() {
|
||||||
icons: [
|
this.listenTo(this.model.get('icons'), 'add remove change', this.render);
|
||||||
{
|
},
|
||||||
type: 'socialIcon',
|
templateHelpers: function() {
|
||||||
iconType: 'facebook',
|
var allIconSets = App.getAvailableStyles().get('socialIconSets');
|
||||||
link: 'http://example.com',
|
return {
|
||||||
image: App.getAvailableStyles().get('socialIconSets.default.facebook'),
|
activeSet: this.model.get('iconSet'),
|
||||||
height: '32px',
|
socialIconSets: allIconSets.toJSON(),
|
||||||
width: '32px',
|
availableSets: _.keys(allIconSets.toJSON()),
|
||||||
text: 'Facebook',
|
availableSocialIcons: this.model.get('icons').pluck('iconType'),
|
||||||
},
|
};
|
||||||
{
|
},
|
||||||
type: 'socialIcon',
|
changeSocialIconSet: function(event) {
|
||||||
iconType: 'twitter',
|
this.model.set('iconSet', jQuery(event.currentTarget).data('setname'));
|
||||||
link: 'http://example.com',
|
},
|
||||||
image: App.getAvailableStyles().get('socialIconSets.default.twitter'),
|
onBeforeDestroy: function() {
|
||||||
height: '32px',
|
this.model.get('icons').off('add remove', this.render, this);
|
||||||
width: '32px',
|
},
|
||||||
text: 'Twitter',
|
});
|
||||||
},
|
|
||||||
],
|
|
||||||
}, { parse: true });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
App.on('before:start', function() {
|
Module.SocialWidgetView = base.WidgetView.extend({
|
||||||
App.registerBlockType('social', {
|
getTemplate: function() { return templates.socialInsertion; },
|
||||||
blockModel: Module.SocialBlockModel,
|
behaviors: {
|
||||||
blockView: Module.SocialBlockView,
|
DraggableBehavior: {
|
||||||
});
|
cloneOriginal: true,
|
||||||
|
drop: function() {
|
||||||
|
return new Module.SocialBlockModel({
|
||||||
|
type: 'social',
|
||||||
|
iconSet: 'default',
|
||||||
|
icons: [
|
||||||
|
{
|
||||||
|
type: 'socialIcon',
|
||||||
|
iconType: 'facebook',
|
||||||
|
link: 'http://example.com',
|
||||||
|
image: App.getAvailableStyles().get('socialIconSets.default.facebook'),
|
||||||
|
height: '32px',
|
||||||
|
width: '32px',
|
||||||
|
text: 'Facebook',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'socialIcon',
|
||||||
|
iconType: 'twitter',
|
||||||
|
link: 'http://example.com',
|
||||||
|
image: App.getAvailableStyles().get('socialIconSets.default.twitter'),
|
||||||
|
height: '32px',
|
||||||
|
width: '32px',
|
||||||
|
text: 'Twitter',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}, { parse: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
App.on('before:start', function() {
|
||||||
|
App.registerBlockType('social', {
|
||||||
|
blockModel: Module.SocialBlockModel,
|
||||||
|
blockView: Module.SocialBlockView,
|
||||||
|
});
|
||||||
|
|
||||||
|
App.registerWidget({
|
||||||
|
name: 'social',
|
||||||
|
widgetView: Module.SocialWidgetView,
|
||||||
|
priority: 95,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.registerWidget({
|
|
||||||
name: 'social',
|
|
||||||
widgetView: Module.SocialWidgetView,
|
|
||||||
priority: 95,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,96 +1,106 @@
|
|||||||
/**
|
/**
|
||||||
* Spacer content block
|
* Spacer content block
|
||||||
*/
|
*/
|
||||||
EditorApplication.module("blocks.spacer", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/blocks/spacer', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
'mailpoet',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette, MailPoet) {
|
||||||
|
|
||||||
var base = App.module('blocks.base');
|
EditorApplication.module("blocks.spacer", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
Module.SpacerBlockModel = base.BlockModel.extend({
|
var base = App.module('blocks.base');
|
||||||
defaults: function() {
|
|
||||||
return this._getDefaults({
|
|
||||||
type: 'spacer',
|
|
||||||
styles: {
|
|
||||||
block: {
|
|
||||||
backgroundColor: 'transparent',
|
|
||||||
height: '40px',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, EditorApplication.getConfig().get('blockDefaults.spacer'));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.SpacerBlockView = base.BlockView.extend({
|
Module.SpacerBlockModel = base.BlockModel.extend({
|
||||||
className: "mailpoet_block mailpoet_spacer_block mailpoet_droppable_block",
|
defaults: function() {
|
||||||
getTemplate: function() { return templates.spacerBlock; },
|
return this._getDefaults({
|
||||||
behaviors: _.defaults({
|
type: 'spacer',
|
||||||
ResizableBehavior: {
|
styles: {
|
||||||
elementSelector: '.mailpoet_spacer',
|
block: {
|
||||||
resizeHandleSelector: '.mailpoet_resize_handle',
|
backgroundColor: 'transparent',
|
||||||
minLength: 20, // TODO: Move this number to editor configuration
|
height: '40px',
|
||||||
modelField: 'styles.block.height',
|
},
|
||||||
},
|
},
|
||||||
}, base.BlockView.prototype.behaviors),
|
}, EditorApplication.getConfig().get('blockDefaults.spacer'));
|
||||||
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'),
|
},
|
||||||
onDragSubstituteBy: function() { return Module.SpacerWidgetView; },
|
});
|
||||||
initialize: function() {
|
|
||||||
base.BlockView.prototype.initialize.apply(this, arguments);
|
|
||||||
|
|
||||||
this.listenTo(this.model, 'change:styles.block.backgroundColor', this.render);
|
Module.SpacerBlockView = base.BlockView.extend({
|
||||||
this.listenTo(this.model, 'change:styles.block.height', this.changeHeight);
|
className: "mailpoet_block mailpoet_spacer_block mailpoet_droppable_block",
|
||||||
},
|
getTemplate: function() { return templates.spacerBlock; },
|
||||||
onRender: function() {
|
behaviors: _.defaults({
|
||||||
this.toolsView = new Module.SpacerBlockToolsView({ model: this.model });
|
ResizableBehavior: {
|
||||||
this.toolsRegion.show(this.toolsView);
|
elementSelector: '.mailpoet_spacer',
|
||||||
},
|
resizeHandleSelector: '.mailpoet_resize_handle',
|
||||||
changeHeight: function() {
|
minLength: 20, // TODO: Move this number to editor configuration
|
||||||
this.$('.mailpoet_spacer').css('height', this.model.get('styles.block.height'));
|
modelField: 'styles.block.height',
|
||||||
this.$('.mailpoet_resize_handle_text').text(this.model.get('styles.block.height'));
|
},
|
||||||
},
|
}, base.BlockView.prototype.behaviors),
|
||||||
onBeforeDestroy: function() {
|
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'),
|
||||||
this.stopListening(this.model);
|
onDragSubstituteBy: function() { return Module.SpacerWidgetView; },
|
||||||
},
|
initialize: function() {
|
||||||
});
|
base.BlockView.prototype.initialize.apply(this, arguments);
|
||||||
|
|
||||||
Module.SpacerBlockToolsView = base.BlockToolsView.extend({
|
this.listenTo(this.model, 'change:styles.block.backgroundColor', this.render);
|
||||||
getSettingsView: function() { return Module.SpacerBlockSettingsView; },
|
this.listenTo(this.model, 'change:styles.block.height', this.changeHeight);
|
||||||
});
|
},
|
||||||
|
onRender: function() {
|
||||||
|
this.toolsView = new Module.SpacerBlockToolsView({ model: this.model });
|
||||||
|
this.toolsRegion.show(this.toolsView);
|
||||||
|
},
|
||||||
|
changeHeight: function() {
|
||||||
|
this.$('.mailpoet_spacer').css('height', this.model.get('styles.block.height'));
|
||||||
|
this.$('.mailpoet_resize_handle_text').text(this.model.get('styles.block.height'));
|
||||||
|
},
|
||||||
|
onBeforeDestroy: function() {
|
||||||
|
this.stopListening(this.model);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Module.SpacerBlockSettingsView = base.BlockSettingsView.extend({
|
Module.SpacerBlockToolsView = base.BlockToolsView.extend({
|
||||||
getTemplate: function() { return templates.spacerBlockSettings; },
|
getSettingsView: function() { return Module.SpacerBlockSettingsView; },
|
||||||
events: function() {
|
});
|
||||||
return {
|
|
||||||
"change .mailpoet_field_spacer_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
|
|
||||||
"click .mailpoet_done_editing": "close",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
behaviors: {
|
|
||||||
ColorPickerBehavior: {},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.SpacerWidgetView = base.WidgetView.extend({
|
Module.SpacerBlockSettingsView = base.BlockSettingsView.extend({
|
||||||
getTemplate: function() { return templates.spacerInsertion; },
|
getTemplate: function() { return templates.spacerBlockSettings; },
|
||||||
behaviors: {
|
events: function() {
|
||||||
DraggableBehavior: {
|
return {
|
||||||
cloneOriginal: true,
|
"change .mailpoet_field_spacer_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
|
||||||
drop: function() {
|
"click .mailpoet_done_editing": "close",
|
||||||
return new Module.SpacerBlockModel();
|
};
|
||||||
},
|
},
|
||||||
}
|
behaviors: {
|
||||||
},
|
ColorPickerBehavior: {},
|
||||||
});
|
},
|
||||||
|
});
|
||||||
|
|
||||||
App.on('before:start', function() {
|
Module.SpacerWidgetView = base.WidgetView.extend({
|
||||||
App.registerBlockType('spacer', {
|
getTemplate: function() { return templates.spacerInsertion; },
|
||||||
blockModel: Module.SpacerBlockModel,
|
behaviors: {
|
||||||
blockView: Module.SpacerBlockView,
|
DraggableBehavior: {
|
||||||
});
|
cloneOriginal: true,
|
||||||
|
drop: function() {
|
||||||
|
return new Module.SpacerBlockModel();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
App.on('before:start', function() {
|
||||||
|
App.registerBlockType('spacer', {
|
||||||
|
blockModel: Module.SpacerBlockModel,
|
||||||
|
blockView: Module.SpacerBlockView,
|
||||||
|
});
|
||||||
|
|
||||||
|
App.registerWidget({
|
||||||
|
name: 'spacer',
|
||||||
|
widgetView: Module.SpacerWidgetView,
|
||||||
|
priority: 94,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.registerWidget({
|
|
||||||
name: 'spacer',
|
|
||||||
widgetView: Module.SpacerWidgetView,
|
|
||||||
priority: 94,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,116 +1,129 @@
|
|||||||
/**
|
/**
|
||||||
* Text content block
|
* Text content block
|
||||||
*/
|
*/
|
||||||
EditorApplication.module("blocks.text", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/blocks/text', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
'mailpoet',
|
||||||
|
'jquery',
|
||||||
|
//'tinymce',
|
||||||
|
//'jquery.tinymce',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette, MailPoet, jQuery, TinyMCE) {
|
||||||
|
|
||||||
var base = App.module('blocks.base');
|
EditorApplication.module("blocks.text", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
Module.TextBlockModel = base.BlockModel.extend({
|
var base = App.module('blocks.base');
|
||||||
defaults: function() {
|
|
||||||
return this._getDefaults({
|
|
||||||
type: 'text',
|
|
||||||
text: 'Edit this to insert text',
|
|
||||||
}, EditorApplication.getConfig().get('blockDefaults.text'));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.TextBlockView = base.BlockView.extend({
|
Module.TextBlockModel = base.BlockModel.extend({
|
||||||
className: "mailpoet_block mailpoet_text_block mailpoet_droppable_block",
|
defaults: function() {
|
||||||
getTemplate: function() { return templates.textBlock; },
|
return this._getDefaults({
|
||||||
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'), // Prevent rerendering on model change due to text editor redrawing
|
type: 'text',
|
||||||
initialize: function(options) {
|
text: 'Edit this to insert text',
|
||||||
this.renderOptions = _.defaults(options.renderOptions || {}, {
|
}, EditorApplication.getConfig().get('blockDefaults.text'));
|
||||||
disableTextEditor: false,
|
},
|
||||||
});
|
});
|
||||||
},
|
|
||||||
onDragSubstituteBy: function() { return Module.TextWidgetView; },
|
|
||||||
onRender: function() {
|
|
||||||
this.toolsView = new Module.TextBlockToolsView({
|
|
||||||
model: this.model,
|
|
||||||
tools: {
|
|
||||||
settings: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
this.toolsRegion.show(this.toolsView);
|
|
||||||
},
|
|
||||||
onDomRefresh: function() {
|
|
||||||
this.attachTextEditor();
|
|
||||||
},
|
|
||||||
attachTextEditor: function() {
|
|
||||||
var that = this;
|
|
||||||
if (!this.renderOptions.disableTextEditor) {
|
|
||||||
this.$('.mailpoet_content').tinymce({
|
|
||||||
inline: true,
|
|
||||||
|
|
||||||
menubar: false,
|
Module.TextBlockView = base.BlockView.extend({
|
||||||
toolbar1: "styleselect bold italic forecolor | link unlink",
|
className: "mailpoet_block mailpoet_text_block mailpoet_droppable_block",
|
||||||
toolbar2: "alignleft aligncenter alignright alignjustify | bullist numlist blockquote | code mailpoet_custom_fields",
|
getTemplate: function() { return templates.textBlock; },
|
||||||
|
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'), // Prevent rerendering on model change due to text editor redrawing
|
||||||
|
initialize: function(options) {
|
||||||
|
this.renderOptions = _.defaults(options.renderOptions || {}, {
|
||||||
|
disableTextEditor: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onDragSubstituteBy: function() { return Module.TextWidgetView; },
|
||||||
|
onRender: function() {
|
||||||
|
this.toolsView = new Module.TextBlockToolsView({
|
||||||
|
model: this.model,
|
||||||
|
tools: {
|
||||||
|
settings: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.toolsRegion.show(this.toolsView);
|
||||||
|
},
|
||||||
|
onDomRefresh: function() {
|
||||||
|
this.attachTextEditor();
|
||||||
|
},
|
||||||
|
attachTextEditor: function() {
|
||||||
|
var that = this;
|
||||||
|
if (!this.renderOptions.disableTextEditor) {
|
||||||
|
this.$('.mailpoet_content').tinymce({
|
||||||
|
inline: true,
|
||||||
|
|
||||||
//forced_root_block: 'p',
|
menubar: false,
|
||||||
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]",
|
toolbar1: "styleselect bold italic forecolor | link unlink",
|
||||||
invalid_elements: "script",
|
toolbar2: "alignleft aligncenter alignright alignjustify | bullist numlist blockquote | code mailpoet_custom_fields",
|
||||||
style_formats: [
|
|
||||||
{title: 'Heading 1', block: 'h1'},
|
|
||||||
{title: 'Heading 2', block: 'h2'},
|
|
||||||
{title: 'Heading 3', block: 'h3'},
|
|
||||||
|
|
||||||
{title: 'Paragraph', block: 'p'},
|
//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",
|
||||||
|
style_formats: [
|
||||||
|
{title: 'Heading 1', block: 'h1'},
|
||||||
|
{title: 'Heading 2', block: 'h2'},
|
||||||
|
{title: 'Heading 3', block: 'h3'},
|
||||||
|
|
||||||
plugins: "wplink code textcolor mailpoet_custom_fields",
|
{title: 'Paragraph', block: 'p'},
|
||||||
|
],
|
||||||
|
|
||||||
setup: function(editor) {
|
plugins: "wplink code textcolor mailpoet_custom_fields",
|
||||||
editor.on('change', function(e) {
|
|
||||||
that.model.set('text', editor.getContent());
|
|
||||||
});
|
|
||||||
|
|
||||||
editor.on('focus', function(e) {
|
setup: function(editor) {
|
||||||
that.disableShowingTools();
|
editor.on('change', function(e) {
|
||||||
});
|
that.model.set('text', editor.getContent());
|
||||||
|
});
|
||||||
|
|
||||||
editor.on('blur', function(e) {
|
editor.on('focus', function(e) {
|
||||||
that.enableShowingTools();
|
that.disableShowingTools();
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
mailpoet_custom_fields: App.getConfig().get('customFields').toJSON(),
|
editor.on('blur', function(e) {
|
||||||
mailpoet_custom_fields_window_title: App.getConfig().get('translations.customFieldsWindowTitle'),
|
that.enableShowingTools();
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.TextBlockToolsView = base.BlockToolsView.extend({
|
mailpoet_custom_fields: App.getConfig().get('customFields').toJSON(),
|
||||||
getSettingsView: function() { return Module.TextBlockSettingsView; },
|
mailpoet_custom_fields_window_title: App.getConfig().get('translations.customFieldsWindowTitle'),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Module.TextBlockSettingsView = base.BlockSettingsView.extend({
|
Module.TextBlockToolsView = base.BlockToolsView.extend({
|
||||||
getTemplate: function() { return templates.textBlockSettings; },
|
getSettingsView: function() { return Module.TextBlockSettingsView; },
|
||||||
});
|
});
|
||||||
|
|
||||||
Module.TextWidgetView = base.WidgetView.extend({
|
Module.TextBlockSettingsView = base.BlockSettingsView.extend({
|
||||||
getTemplate: function() { return templates.textInsertion; },
|
getTemplate: function() { return templates.textBlockSettings; },
|
||||||
behaviors: {
|
});
|
||||||
DraggableBehavior: {
|
|
||||||
cloneOriginal: true,
|
|
||||||
drop: function() {
|
|
||||||
return new Module.TextBlockModel();
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
App.on('before:start', function() {
|
Module.TextWidgetView = base.WidgetView.extend({
|
||||||
App.registerBlockType('text', {
|
getTemplate: function() { return templates.textInsertion; },
|
||||||
blockModel: Module.TextBlockModel,
|
behaviors: {
|
||||||
blockView: Module.TextBlockView,
|
DraggableBehavior: {
|
||||||
});
|
cloneOriginal: true,
|
||||||
|
drop: function() {
|
||||||
|
return new Module.TextBlockModel();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
App.on('before:start', function() {
|
||||||
|
App.registerBlockType('text', {
|
||||||
|
blockModel: Module.TextBlockModel,
|
||||||
|
blockView: Module.TextBlockView,
|
||||||
|
});
|
||||||
|
|
||||||
|
App.registerWidget({
|
||||||
|
name: 'text',
|
||||||
|
widgetView: Module.TextWidgetView,
|
||||||
|
priority: 90,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.registerWidget({
|
|
||||||
name: 'text',
|
|
||||||
widgetView: Module.TextWidgetView,
|
|
||||||
priority: 90,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,28 +1,36 @@
|
|||||||
EditorApplication.module("components.config", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/components/config', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel) {
|
||||||
|
|
||||||
Module.ConfigModel = Backbone.SuperModel.extend({
|
EditorApplication.module("components.config", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
defaults: {
|
"use strict";
|
||||||
availableStyles: {},
|
|
||||||
socialIcons: {},
|
|
||||||
blockDefaults: {},
|
|
||||||
translations: {},
|
|
||||||
sidepanelWidth: '331px',
|
|
||||||
validation: {},
|
|
||||||
urls: {},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Global and available styles for access in blocks and their settings
|
Module.ConfigModel = SuperModel.extend({
|
||||||
Module._config = {};
|
defaults: {
|
||||||
Module.getConfig = function() { return Module._config; };
|
availableStyles: {},
|
||||||
Module.setConfig = function(options) { Module._config = new Module.ConfigModel(options, { parse: true }); return Module._config; };
|
socialIcons: {},
|
||||||
|
blockDefaults: {},
|
||||||
|
translations: {},
|
||||||
|
sidepanelWidth: '331px',
|
||||||
|
validation: {},
|
||||||
|
urls: {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
App.on('before:start', function(options) {
|
// Global and available styles for access in blocks and their settings
|
||||||
// Expose config methods globally
|
Module._config = {};
|
||||||
App.getConfig = Module.getConfig;
|
Module.getConfig = function() { return Module._config; };
|
||||||
App.setConfig = Module.setConfig;
|
Module.setConfig = function(options) { Module._config = new Module.ConfigModel(options, { parse: true }); return Module._config; };
|
||||||
|
|
||||||
|
App.on('before:start', function(options) {
|
||||||
|
// Expose config methods globally
|
||||||
|
App.getConfig = Module.getConfig;
|
||||||
|
App.setConfig = Module.setConfig;
|
||||||
|
|
||||||
|
App.setConfig(options.config);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.setConfig(options.config);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,72 +1,81 @@
|
|||||||
EditorApplication.module("components.content", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/components/content', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette) {
|
||||||
|
|
||||||
// Holds newsletter entry fields, such as subject or creation datetime.
|
EditorApplication.module("components.content", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
// Does not hold newsletter content nor newsletter styles, those are
|
"use strict";
|
||||||
// handled by other components.
|
|
||||||
Module.NewsletterModel = Backbone.SuperModel.extend({
|
|
||||||
stale: ['data', 'styles'],
|
|
||||||
initialize: function(options) {
|
|
||||||
this.on('change', function() {
|
|
||||||
App.getChannel().trigger('autoSave');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
toJSON: function() {
|
|
||||||
// Remove stale attributes from resulting JSON object
|
|
||||||
return _.omit(Backbone.SuperModel.prototype.toJSON.call(this), this.stale);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Content block view and model handlers for different content types
|
// Holds newsletter entry fields, such as subject or creation datetime.
|
||||||
Module._blockTypes = {};
|
// Does not hold newsletter content nor newsletter styles, those are
|
||||||
Module.registerBlockType = function(type, data) {
|
// handled by other components.
|
||||||
Module._blockTypes[type] = data;
|
Module.NewsletterModel = SuperModel.extend({
|
||||||
};
|
stale: ['data', 'styles'],
|
||||||
Module.getBlockTypeModel = function(type) {
|
initialize: function(options) {
|
||||||
if (type in Module._blockTypes) {
|
this.on('change', function() {
|
||||||
return Module._blockTypes[type].blockModel;
|
App.getChannel().trigger('autoSave');
|
||||||
} else {
|
});
|
||||||
throw "Block type not supported: " + type;
|
},
|
||||||
}
|
toJSON: function() {
|
||||||
};
|
// Remove stale attributes from resulting JSON object
|
||||||
Module.getBlockTypeView = function(type) {
|
return _.omit(SuperModel.prototype.toJSON.call(this), this.stale);
|
||||||
if (type in Module._blockTypes) {
|
},
|
||||||
return Module._blockTypes[type].blockView;
|
});
|
||||||
} else {
|
|
||||||
throw "Block type not supported: " + type;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Module.toJSON = function() {
|
// Content block view and model handlers for different content types
|
||||||
return _.extend({
|
Module._blockTypes = {};
|
||||||
data: App._contentContainer.toJSON(),
|
Module.registerBlockType = function(type, data) {
|
||||||
styles: App.getGlobalStyles().toJSON(),
|
Module._blockTypes[type] = data;
|
||||||
}, App.getNewsletter().toJSON());
|
};
|
||||||
};
|
Module.getBlockTypeModel = function(type) {
|
||||||
|
if (type in Module._blockTypes) {
|
||||||
|
return Module._blockTypes[type].blockModel;
|
||||||
|
} else {
|
||||||
|
throw "Block type not supported: " + type;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Module.getBlockTypeView = function(type) {
|
||||||
|
if (type in Module._blockTypes) {
|
||||||
|
return Module._blockTypes[type].blockView;
|
||||||
|
} else {
|
||||||
|
throw "Block type not supported: " + type;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Module.getNewsletter = function() {
|
Module.toJSON = function() {
|
||||||
return Module.newsletter;
|
return _.extend({
|
||||||
};
|
data: App._contentContainer.toJSON(),
|
||||||
|
styles: App.getGlobalStyles().toJSON(),
|
||||||
|
}, App.getNewsletter().toJSON());
|
||||||
|
};
|
||||||
|
|
||||||
App.on('before:start', function(options) {
|
Module.getNewsletter = function() {
|
||||||
// Expose block methods globally
|
return Module.newsletter;
|
||||||
App.registerBlockType = Module.registerBlockType;
|
};
|
||||||
App.getBlockTypeModel = Module.getBlockTypeModel;
|
|
||||||
App.getBlockTypeView = Module.getBlockTypeView;
|
|
||||||
App.toJSON = Module.toJSON;
|
|
||||||
App.getNewsletter = Module.getNewsletter;
|
|
||||||
|
|
||||||
Module.newsletter = new Module.NewsletterModel(options.newsletter);
|
App.on('before:start', function(options) {
|
||||||
});
|
// Expose block methods globally
|
||||||
|
App.registerBlockType = Module.registerBlockType;
|
||||||
|
App.getBlockTypeModel = Module.getBlockTypeModel;
|
||||||
|
App.getBlockTypeView = Module.getBlockTypeView;
|
||||||
|
App.toJSON = Module.toJSON;
|
||||||
|
App.getNewsletter = Module.getNewsletter;
|
||||||
|
|
||||||
App.on('start', function(options) {
|
Module.newsletter = new Module.NewsletterModel(options.newsletter);
|
||||||
// TODO: Other newsletter information will be needed as well.
|
});
|
||||||
App._contentContainer = new (this.getBlockTypeModel('container'))(options.newsletter.data, {parse: true});
|
|
||||||
App._contentContainerView = new (this.getBlockTypeView('container'))({
|
App.on('start', function(options) {
|
||||||
model: App._contentContainer,
|
// TODO: Other newsletter information will be needed as well.
|
||||||
renderOptions: { depth: 0 },
|
App._contentContainer = new (this.getBlockTypeModel('container'))(options.newsletter.data, {parse: true});
|
||||||
});
|
App._contentContainerView = new (this.getBlockTypeView('container'))({
|
||||||
|
model: App._contentContainer,
|
||||||
|
renderOptions: { depth: 0 },
|
||||||
|
});
|
||||||
|
|
||||||
|
App._appView.contentRegion.show(App._contentContainerView);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App._appView.contentRegion.show(App._contentContainerView);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,26 +1,33 @@
|
|||||||
EditorApplication.module("components.heading", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/components/heading', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.marionette',
|
||||||
|
], function(EditorApplication, Backbone, Marionette) {
|
||||||
|
|
||||||
Module.HeadingView = Marionette.ItemView.extend({
|
EditorApplication.module("components.heading", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
getTemplate: function() { return templates.heading; },
|
"use strict";
|
||||||
templateHelpers: function() {
|
|
||||||
return {
|
Module.HeadingView = Marionette.ItemView.extend({
|
||||||
model: this.model.toJSON(),
|
getTemplate: function() { return templates.heading; },
|
||||||
};
|
templateHelpers: function() {
|
||||||
},
|
return {
|
||||||
events: function() {
|
model: this.model.toJSON(),
|
||||||
return {
|
};
|
||||||
'keyup .mailpoet_input_title': _.partial(this.changeField, "newsletter_subject"),
|
},
|
||||||
'keyup .mailpoet_input_preheader': _.partial(this.changeField, "newsletter_preheader"),
|
events: function() {
|
||||||
};
|
return {
|
||||||
},
|
'keyup .mailpoet_input_title': _.partial(this.changeField, "newsletter_subject"),
|
||||||
changeField: function(field, event) {
|
'keyup .mailpoet_input_preheader': _.partial(this.changeField, "newsletter_preheader"),
|
||||||
this.model.set(field, jQuery(event.target).val());
|
};
|
||||||
},
|
},
|
||||||
});
|
changeField: function(field, event) {
|
||||||
|
this.model.set(field, jQuery(event.target).val());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
App.on('start', function(options) {
|
||||||
|
App._appView.headingRegion.show(new Module.HeadingView({ model: App.getNewsletter() }));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.on('start', function(options) {
|
|
||||||
App._appView.headingRegion.show(new Module.HeadingView({ model: App.getNewsletter() }));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,169 +1,177 @@
|
|||||||
EditorApplication.module("components.save", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/components/save', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
var saveTimeout;
|
'backbone',
|
||||||
|
'backbone.marionette',
|
||||||
|
], function(EditorApplication, Backbone, Marionette) {
|
||||||
|
|
||||||
// Save editor contents to server
|
EditorApplication.module("components.save", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
Module.save = function() {
|
"use strict";
|
||||||
App.getChannel().trigger('beforeEditorSave');
|
var saveTimeout;
|
||||||
|
|
||||||
var json = App.toJSON();
|
// Save editor contents to server
|
||||||
|
Module.save = function() {
|
||||||
|
App.getChannel().trigger('beforeEditorSave');
|
||||||
|
|
||||||
|
var json = App.toJSON();
|
||||||
|
|
||||||
|
|
||||||
// save newsletter
|
// save newsletter
|
||||||
mailpoet_post_wpi('newsletter_save.php', json, function(response) {
|
mailpoet_post_wpi('newsletter_save.php', json, function(response) {
|
||||||
if(response.success !== undefined && response.success === true) {
|
if(response.success !== undefined && response.success === true) {
|
||||||
//MailPoet.Notice.success("<?php _e('Newsletter has been saved.'); ?>");
|
//MailPoet.Notice.success("<?php _e('Newsletter has been saved.'); ?>");
|
||||||
} else if(response.error !== undefined) {
|
} else if(response.error !== undefined) {
|
||||||
if(response.error.length === 0) {
|
if(response.error.length === 0) {
|
||||||
// TODO: Handle translations
|
// TODO: Handle translations
|
||||||
MailPoet.Notice.error("<?php _e('An unknown error occurred, please check your settings.'); ?>");
|
MailPoet.Notice.error("<?php _e('An unknown error occurred, please check your settings.'); ?>");
|
||||||
} else {
|
} else {
|
||||||
$(response.error).each(function(i, error) {
|
$(response.error).each(function(i, error) {
|
||||||
MailPoet.Notice.error(error);
|
MailPoet.Notice.error(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
App.getChannel().trigger('afterEditorSave', json, response);
|
App.getChannel().trigger('afterEditorSave', json, response);
|
||||||
}, function(error) {
|
}, function(error) {
|
||||||
// TODO: Handle saving errors
|
// TODO: Handle saving errors
|
||||||
App.getChannel().trigger('afterEditorSave', {}, error);
|
App.getChannel().trigger('afterEditorSave', {}, error);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Module.SaveView = Marionette.LayoutView.extend({
|
Module.SaveView = Marionette.LayoutView.extend({
|
||||||
getTemplate: function() { return templates.save; },
|
getTemplate: function() { return templates.save; },
|
||||||
events: {
|
events: {
|
||||||
'click .mailpoet_save_button': 'save',
|
'click .mailpoet_save_button': 'save',
|
||||||
'click .mailpoet_save_show_options': 'toggleSaveOptions',
|
'click .mailpoet_save_show_options': 'toggleSaveOptions',
|
||||||
'click .mailpoet_save_next': 'next',
|
'click .mailpoet_save_next': 'next',
|
||||||
/* Save as template */
|
/* Save as template */
|
||||||
'click .mailpoet_save_template': 'toggleSaveAsTemplate',
|
'click .mailpoet_save_template': 'toggleSaveAsTemplate',
|
||||||
'click .mailpoet_save_as_template': 'saveAsTemplate',
|
'click .mailpoet_save_as_template': 'saveAsTemplate',
|
||||||
/* Export template */
|
/* Export template */
|
||||||
'click .mailpoet_save_export': 'exportTemplate',
|
'click .mailpoet_save_export': 'exportTemplate',
|
||||||
},
|
},
|
||||||
initialize: function(options) {
|
initialize: function(options) {
|
||||||
App.getChannel().on('beforeEditorSave', this.beforeSave, this);
|
App.getChannel().on('beforeEditorSave', this.beforeSave, this);
|
||||||
App.getChannel().on('afterEditorSave', this.afterSave, this);
|
App.getChannel().on('afterEditorSave', this.afterSave, this);
|
||||||
|
|
||||||
this.validateNewsletter(App.toJSON());
|
this.validateNewsletter(App.toJSON());
|
||||||
},
|
},
|
||||||
save: function() {
|
save: function() {
|
||||||
this.hideOptionContents();
|
this.hideOptionContents();
|
||||||
App.getChannel().trigger('save');
|
App.getChannel().trigger('save');
|
||||||
},
|
},
|
||||||
beforeSave: function() {
|
beforeSave: function() {
|
||||||
// TODO: Add a loading animation instead
|
// TODO: Add a loading animation instead
|
||||||
this.$('.mailpoet_autosaved_at').text('Saving...');
|
this.$('.mailpoet_autosaved_at').text('Saving...');
|
||||||
},
|
},
|
||||||
afterSave: function(json, response) {
|
afterSave: function(json, response) {
|
||||||
this.validateNewsletter(json);
|
this.validateNewsletter(json);
|
||||||
// Update 'Last saved timer'
|
// Update 'Last saved timer'
|
||||||
this.$('.mailpoet_editor_last_saved').removeClass('mailpoet_hidden');
|
this.$('.mailpoet_editor_last_saved').removeClass('mailpoet_hidden');
|
||||||
this.$('.mailpoet_autosaved_at').text(response.time);
|
this.$('.mailpoet_autosaved_at').text(response.time);
|
||||||
},
|
},
|
||||||
toggleSaveOptions: function() {
|
toggleSaveOptions: function() {
|
||||||
this.$('.mailpoet_save_options').toggleClass('mailpoet_hidden');
|
this.$('.mailpoet_save_options').toggleClass('mailpoet_hidden');
|
||||||
this.$('.mailpoet_save_show_options').toggleClass('mailpoet_save_show_options_active');
|
this.$('.mailpoet_save_show_options').toggleClass('mailpoet_save_show_options_active');
|
||||||
},
|
},
|
||||||
toggleSaveAsTemplate: function() {
|
toggleSaveAsTemplate: function() {
|
||||||
this.$('.mailpoet_save_as_template_container').toggleClass('mailpoet_hidden');
|
this.$('.mailpoet_save_as_template_container').toggleClass('mailpoet_hidden');
|
||||||
this.toggleSaveOptions();
|
this.toggleSaveOptions();
|
||||||
},
|
},
|
||||||
showSaveAsTemplate: function() {
|
showSaveAsTemplate: function() {
|
||||||
this.$('.mailpoet_save_as_template_container').removeClass('mailpoet_hidden');
|
this.$('.mailpoet_save_as_template_container').removeClass('mailpoet_hidden');
|
||||||
this.toggleSaveOptions();
|
this.toggleSaveOptions();
|
||||||
},
|
},
|
||||||
hideSaveAsTemplate: function() {
|
hideSaveAsTemplate: function() {
|
||||||
this.$('.mailpoet_save_as_template_container').addClass('mailpoet_hidden');
|
this.$('.mailpoet_save_as_template_container').addClass('mailpoet_hidden');
|
||||||
},
|
},
|
||||||
saveAsTemplate: function() {
|
saveAsTemplate: function() {
|
||||||
var templateName = this.$('.mailpoet_save_as_template_name').val(),
|
var templateName = this.$('.mailpoet_save_as_template_name').val(),
|
||||||
templateDescription = this.$('.mailpoet_save_as_template_description').val();
|
templateDescription = this.$('.mailpoet_save_as_template_description').val();
|
||||||
|
|
||||||
console.log('Saving template with ', templateName, templateDescription);
|
console.log('Saving template with ', templateName, templateDescription);
|
||||||
|
|
||||||
this.hideOptionContents();
|
this.hideOptionContents();
|
||||||
},
|
},
|
||||||
exportTemplate: function() {
|
exportTemplate: function() {
|
||||||
console.log('Exporting template');
|
console.log('Exporting template');
|
||||||
this.hideOptionContents();
|
this.hideOptionContents();
|
||||||
},
|
},
|
||||||
hideOptionContents: function() {
|
hideOptionContents: function() {
|
||||||
this.hideSaveAsTemplate();
|
this.hideSaveAsTemplate();
|
||||||
this.$('.mailpoet_save_options').addClass('mailpoet_hidden');
|
this.$('.mailpoet_save_options').addClass('mailpoet_hidden');
|
||||||
},
|
},
|
||||||
next: function() {
|
next: function() {
|
||||||
this.hideOptionContents();
|
this.hideOptionContents();
|
||||||
console.log('Next');
|
console.log('Next');
|
||||||
window.location.href = App.getConfig().get('urls.send');
|
window.location.href = App.getConfig().get('urls.send');
|
||||||
},
|
},
|
||||||
validateNewsletter: function(jsonObject) {
|
validateNewsletter: function(jsonObject) {
|
||||||
if (!App._contentContainer.isValid()) {
|
if (!App._contentContainer.isValid()) {
|
||||||
this.showValidationError(App._contentContainer.validationError);
|
this.showValidationError(App._contentContainer.validationError);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (App.getConfig().get('validation.validateUnsubscribeLinkPresent') &&
|
if (App.getConfig().get('validation.validateUnsubscribeLinkPresent') &&
|
||||||
JSON.stringify(jsonObject).indexOf("[unsubscribeUrl]") < 0) {
|
JSON.stringify(jsonObject).indexOf("[unsubscribeUrl]") < 0) {
|
||||||
this.showValidationError(App.getConfig().get('translations.unsubscribeLinkMissing'));
|
this.showValidationError(App.getConfig().get('translations.unsubscribeLinkMissing'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.hideValidationError();
|
this.hideValidationError();
|
||||||
},
|
},
|
||||||
showValidationError: function(message) {
|
showValidationError: function(message) {
|
||||||
var $el = this.$('.mailpoet_save_error');
|
var $el = this.$('.mailpoet_save_error');
|
||||||
$el.text(message);
|
$el.text(message);
|
||||||
$el.removeClass('mailpoet_hidden');
|
$el.removeClass('mailpoet_hidden');
|
||||||
|
|
||||||
this.$('.mailpoet_save_next').addClass('button-disabled');
|
this.$('.mailpoet_save_next').addClass('button-disabled');
|
||||||
},
|
},
|
||||||
hideValidationError: function() {
|
hideValidationError: function() {
|
||||||
this.$('.mailpoet_save_error').addClass('mailpoet_hidden');
|
this.$('.mailpoet_save_error').addClass('mailpoet_hidden');
|
||||||
this.$('.mailpoet_save_next').removeClass('button-disabled');
|
this.$('.mailpoet_save_next').removeClass('button-disabled');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Module.autoSave = function() {
|
Module.autoSave = function() {
|
||||||
// Delay in saving editor contents, during which a new autosave
|
// Delay in saving editor contents, during which a new autosave
|
||||||
// may be requested
|
// may be requested
|
||||||
var AUTOSAVE_DELAY_DURATION = 1000;
|
var AUTOSAVE_DELAY_DURATION = 1000;
|
||||||
|
|
||||||
// Cancel save timer if another change happens before it completes
|
// Cancel save timer if another change happens before it completes
|
||||||
if (saveTimeout) clearTimeout(saveTimeout);
|
if (saveTimeout) clearTimeout(saveTimeout);
|
||||||
saveTimeout = setTimeout(function() {
|
saveTimeout = setTimeout(function() {
|
||||||
App.getChannel().trigger('save');
|
App.getChannel().trigger('save');
|
||||||
clearTimeout(saveTimeout);
|
clearTimeout(saveTimeout);
|
||||||
saveTimeout = undefined;
|
saveTimeout = undefined;
|
||||||
}, AUTOSAVE_DELAY_DURATION);
|
}, AUTOSAVE_DELAY_DURATION);
|
||||||
};
|
};
|
||||||
|
|
||||||
Module.beforeExitWithUnsavedChanges = function(e) {
|
Module.beforeExitWithUnsavedChanges = function(e) {
|
||||||
if (saveTimeout) {
|
if (saveTimeout) {
|
||||||
// TODO: Translate this message
|
// TODO: Translate this message
|
||||||
var message = "There are unsaved changes which will be lost if you leave this page.";
|
var message = "There are unsaved changes which will be lost if you leave this page.";
|
||||||
e = e || window.event;
|
e = e || window.event;
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
e.returnValue = message;
|
e.returnValue = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
App.on('before:start', function(options) {
|
App.on('before:start', function(options) {
|
||||||
App.save = Module.save;
|
App.save = Module.save;
|
||||||
App.getChannel().on('autoSave', Module.autoSave);
|
App.getChannel().on('autoSave', Module.autoSave);
|
||||||
|
|
||||||
window.onbeforeunload = Module.beforeExitWithUnsavedChanges;
|
window.onbeforeunload = Module.beforeExitWithUnsavedChanges;
|
||||||
|
|
||||||
App.getChannel().on('save', function() { App.save(); });
|
App.getChannel().on('save', function() { App.save(); });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
App.on('start', function(options) {
|
||||||
|
var saveView = new Module.SaveView();
|
||||||
|
App._appView.bottomRegion.show(saveView);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.on('start', function(options) {
|
|
||||||
var saveView = new Module.SaveView();
|
|
||||||
App._appView.bottomRegion.show(saveView);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,249 +1,259 @@
|
|||||||
EditorApplication.module("components.sidebar", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/components/sidebar', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
'sticky-kit',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette) {
|
||||||
|
|
||||||
// Widget handlers for use to create new content blocks via drag&drop
|
EditorApplication.module("components.sidebar", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
Module._contentWidgets = new (Backbone.Collection.extend({
|
"use strict";
|
||||||
model: Backbone.SuperModel.extend({
|
|
||||||
defaults: {
|
|
||||||
name: '',
|
|
||||||
priority: 100,
|
|
||||||
widgetView: undefined,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
comparator: 'priority',
|
|
||||||
}))();
|
|
||||||
Module.registerWidget = function(widget) { return Module._contentWidgets.add(widget); };
|
|
||||||
Module.getWidgets = function() { return Module._contentWidgets; };
|
|
||||||
|
|
||||||
// Layout widget handlers for use to create new layout blocks via drag&drop
|
// Widget handlers for use to create new content blocks via drag&drop
|
||||||
Module._layoutWidgets = new (Backbone.Collection.extend({
|
Module._contentWidgets = new (Backbone.Collection.extend({
|
||||||
model: Backbone.SuperModel.extend({
|
model: SuperModel.extend({
|
||||||
defaults: {
|
defaults: {
|
||||||
name: '',
|
name: '',
|
||||||
priority: 100,
|
priority: 100,
|
||||||
widgetView: undefined,
|
widgetView: undefined,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
comparator: 'priority',
|
comparator: 'priority',
|
||||||
}))();
|
}))();
|
||||||
Module.registerLayoutWidget = function(widget) { return Module._layoutWidgets.add(widget); };
|
Module.registerWidget = function(widget) { return Module._contentWidgets.add(widget); };
|
||||||
Module.getLayoutWidgets = function() { return Module._layoutWidgets; };
|
Module.getWidgets = function() { return Module._contentWidgets; };
|
||||||
|
|
||||||
var SidebarView = Backbone.Marionette.LayoutView.extend({
|
// Layout widget handlers for use to create new layout blocks via drag&drop
|
||||||
getTemplate: function() { return templates.sidebar; },
|
Module._layoutWidgets = new (Backbone.Collection.extend({
|
||||||
regions: {
|
model: SuperModel.extend({
|
||||||
contentRegion: '.mailpoet_content_region',
|
defaults: {
|
||||||
layoutRegion: '.mailpoet_layout_region',
|
name: '',
|
||||||
stylesRegion: '.mailpoet_styles_region',
|
priority: 100,
|
||||||
previewRegion: '.mailpoet_preview_region',
|
widgetView: undefined,
|
||||||
},
|
},
|
||||||
events: {
|
}),
|
||||||
'click .mailpoet_sidebar_region h3, .mailpoet_sidebar_region .handlediv': function(event) {
|
comparator: 'priority',
|
||||||
this.$el.find('.mailpoet_sidebar_region').addClass('closed');
|
}))();
|
||||||
this.$el.find(event.target).parent().parent().removeClass('closed');
|
Module.registerLayoutWidget = function(widget) { return Module._layoutWidgets.add(widget); };
|
||||||
},
|
Module.getLayoutWidgets = function() { return Module._layoutWidgets; };
|
||||||
},
|
|
||||||
initialize: function(options) {
|
|
||||||
$(window)
|
|
||||||
.on('resize', this.updateHorizontalScroll.bind(this))
|
|
||||||
.on('scroll', this.updateHorizontalScroll.bind(this));
|
|
||||||
},
|
|
||||||
onRender: function() {
|
|
||||||
this.contentRegion.show(new Module.SidebarWidgetsView({
|
|
||||||
collection: App.getWidgets(),
|
|
||||||
}));
|
|
||||||
this.layoutRegion.show(new Module.SidebarLayoutWidgetsView({
|
|
||||||
collection: App.getLayoutWidgets(),
|
|
||||||
}));
|
|
||||||
this.stylesRegion.show(new Module.SidebarStylesView({
|
|
||||||
model: App.getGlobalStyles(),
|
|
||||||
availableStyles: App.getAvailableStyles(),
|
|
||||||
}));
|
|
||||||
this.previewRegion.show(new Module.SidebarPreviewView());
|
|
||||||
},
|
|
||||||
updateHorizontalScroll: function() {
|
|
||||||
// Fixes the sidebar so that on narrower screens the horizontal
|
|
||||||
// position of the sidebar would be scrollable and not fixed
|
|
||||||
// partially out of visible screen
|
|
||||||
this.$el.parent().each(function () {
|
|
||||||
var calculated_left, self;
|
|
||||||
|
|
||||||
self = $(this);
|
var SidebarView = Backbone.Marionette.LayoutView.extend({
|
||||||
|
getTemplate: function() { return templates.sidebar; },
|
||||||
|
regions: {
|
||||||
|
contentRegion: '.mailpoet_content_region',
|
||||||
|
layoutRegion: '.mailpoet_layout_region',
|
||||||
|
stylesRegion: '.mailpoet_styles_region',
|
||||||
|
previewRegion: '.mailpoet_preview_region',
|
||||||
|
},
|
||||||
|
events: {
|
||||||
|
'click .mailpoet_sidebar_region h3, .mailpoet_sidebar_region .handlediv': function(event) {
|
||||||
|
this.$el.find('.mailpoet_sidebar_region').addClass('closed');
|
||||||
|
this.$el.find(event.target).parent().parent().removeClass('closed');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
initialize: function(options) {
|
||||||
|
$(window)
|
||||||
|
.on('resize', this.updateHorizontalScroll.bind(this))
|
||||||
|
.on('scroll', this.updateHorizontalScroll.bind(this));
|
||||||
|
},
|
||||||
|
onRender: function() {
|
||||||
|
this.contentRegion.show(new Module.SidebarWidgetsView({
|
||||||
|
collection: App.getWidgets(),
|
||||||
|
}));
|
||||||
|
this.layoutRegion.show(new Module.SidebarLayoutWidgetsView({
|
||||||
|
collection: App.getLayoutWidgets(),
|
||||||
|
}));
|
||||||
|
this.stylesRegion.show(new Module.SidebarStylesView({
|
||||||
|
model: App.getGlobalStyles(),
|
||||||
|
availableStyles: App.getAvailableStyles(),
|
||||||
|
}));
|
||||||
|
this.previewRegion.show(new Module.SidebarPreviewView());
|
||||||
|
},
|
||||||
|
updateHorizontalScroll: function() {
|
||||||
|
// Fixes the sidebar so that on narrower screens the horizontal
|
||||||
|
// position of the sidebar would be scrollable and not fixed
|
||||||
|
// partially out of visible screen
|
||||||
|
this.$el.parent().each(function () {
|
||||||
|
var calculated_left, self;
|
||||||
|
|
||||||
if (self.css('position') === 'fixed') {
|
self = $(this);
|
||||||
calculated_left = self.parent().offset().left - $(window).scrollLeft();
|
|
||||||
self.css('left', calculated_left + 'px');
|
|
||||||
} else {
|
|
||||||
self.css('left', '');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onDomRefresh: function() {
|
|
||||||
var that = this;
|
|
||||||
this.$el.parent().stick_in_parent({
|
|
||||||
offset_top: 32,
|
|
||||||
});
|
|
||||||
this.$el.parent().on('sticky_kit:stick', this.updateHorizontalScroll.bind(this));
|
|
||||||
this.$el.parent().on('sticky_kit:unstick', this.updateHorizontalScroll.bind(this));
|
|
||||||
this.$el.parent().on('sticky_kit:bottom', this.updateHorizontalScroll.bind(this));
|
|
||||||
this.$el.parent().on('sticky_kit:unbottom', this.updateHorizontalScroll.bind(this));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
if (self.css('position') === 'fixed') {
|
||||||
* Responsible for rendering draggable content widgets
|
calculated_left = self.parent().offset().left - $(window).scrollLeft();
|
||||||
*/
|
self.css('left', calculated_left + 'px');
|
||||||
Module.SidebarWidgetsView = Backbone.Marionette.CompositeView.extend({
|
} else {
|
||||||
getTemplate: function() { return templates.sidebarContent; },
|
self.css('left', '');
|
||||||
getChildView: function(model) {
|
}
|
||||||
return model.get('widgetView');
|
});
|
||||||
},
|
},
|
||||||
childViewContainer: '.mailpoet_region_content',
|
onDomRefresh: function() {
|
||||||
});
|
var that = this;
|
||||||
|
this.$el.parent().stick_in_parent({
|
||||||
|
offset_top: 32,
|
||||||
|
});
|
||||||
|
this.$el.parent().on('sticky_kit:stick', this.updateHorizontalScroll.bind(this));
|
||||||
|
this.$el.parent().on('sticky_kit:unstick', this.updateHorizontalScroll.bind(this));
|
||||||
|
this.$el.parent().on('sticky_kit:bottom', this.updateHorizontalScroll.bind(this));
|
||||||
|
this.$el.parent().on('sticky_kit:unbottom', this.updateHorizontalScroll.bind(this));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responsible for rendering draggable layout widgets
|
* Responsible for rendering draggable content widgets
|
||||||
*/
|
*/
|
||||||
Module.SidebarLayoutWidgetsView = Module.SidebarWidgetsView.extend({
|
Module.SidebarWidgetsView = Backbone.Marionette.CompositeView.extend({
|
||||||
getTemplate: function() { return templates.sidebarLayout; },
|
getTemplate: function() { return templates.sidebarContent; },
|
||||||
});
|
getChildView: function(model) {
|
||||||
/**
|
return model.get('widgetView');
|
||||||
* Responsible for managing global styles
|
},
|
||||||
*/
|
childViewContainer: '.mailpoet_region_content',
|
||||||
Module.SidebarStylesView = Backbone.Marionette.LayoutView.extend({
|
});
|
||||||
getTemplate: function() { return templates.sidebarStyles; },
|
|
||||||
events: function() {
|
|
||||||
return {
|
|
||||||
"change #mailpoet_text_font_color": _.partial(this.changeColorField, 'text.fontColor'),
|
|
||||||
"change #mailpoet_text_font_family": function(event) {
|
|
||||||
this.model.set('text.fontFamily', event.target.value);
|
|
||||||
},
|
|
||||||
"change #mailpoet_text_font_size": function(event) {
|
|
||||||
this.model.set('text.fontSize', event.target.value);
|
|
||||||
},
|
|
||||||
"change #mailpoet_h1_font_color": _.partial(this.changeColorField, 'h1.fontColor'),
|
|
||||||
"change #mailpoet_h1_font_family": function(event) {
|
|
||||||
this.model.set('h1.fontFamily', event.target.value);
|
|
||||||
},
|
|
||||||
"change #mailpoet_h1_font_size": function(event) {
|
|
||||||
this.model.set('h1.fontSize', event.target.value);
|
|
||||||
},
|
|
||||||
"change #mailpoet_h2_font_color": _.partial(this.changeColorField, 'h2.fontColor'),
|
|
||||||
"change #mailpoet_h2_font_family": function(event) {
|
|
||||||
this.model.set('h2.fontFamily', event.target.value);
|
|
||||||
},
|
|
||||||
"change #mailpoet_h2_font_size": function(event) {
|
|
||||||
this.model.set('h2.fontSize', event.target.value);
|
|
||||||
},
|
|
||||||
"change #mailpoet_h3_font_color": _.partial(this.changeColorField, 'h3.fontColor'),
|
|
||||||
"change #mailpoet_h3_font_family": function(event) {
|
|
||||||
this.model.set('h3.fontFamily', event.target.value);
|
|
||||||
},
|
|
||||||
"change #mailpoet_h3_font_size": function(event) {
|
|
||||||
this.model.set('h3.fontSize', event.target.value);
|
|
||||||
},
|
|
||||||
"change #mailpoet_a_font_color": _.partial(this.changeColorField, 'link.fontColor'),
|
|
||||||
"change #mailpoet_a_font_underline": function(event) {
|
|
||||||
this.model.set('link.textDecoration', (event.target.checked) ? event.target.value : 'none');
|
|
||||||
},
|
|
||||||
"change #mailpoet_newsletter_background_color": _.partial(this.changeColorField, 'newsletter.backgroundColor'),
|
|
||||||
"change #mailpoet_background_color": _.partial(this.changeColorField, 'background.backgroundColor'),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
templateHelpers: function() {
|
|
||||||
return {
|
|
||||||
model: this.model.toJSON(),
|
|
||||||
availableStyles: this.availableStyles.toJSON(),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
initialize: function(options) {
|
|
||||||
this.availableStyles = options.availableStyles;
|
|
||||||
var that = this;
|
|
||||||
},
|
|
||||||
onRender: function() {
|
|
||||||
var that = this;
|
|
||||||
this.$('.mailpoet_color').spectrum({
|
|
||||||
clickoutFiresChange: true,
|
|
||||||
showInput: true,
|
|
||||||
showInitial: true,
|
|
||||||
preferredFormat: "hex6",
|
|
||||||
allowEmpty: true,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
changeField: function(field, event) {
|
|
||||||
this.model.set(field, jQuery(event.target).val());
|
|
||||||
},
|
|
||||||
changeColorField: function(field, event) {
|
|
||||||
var value = jQuery(event.target).val();
|
|
||||||
if (value === '') {
|
|
||||||
value = 'transparent';
|
|
||||||
}
|
|
||||||
this.model.set(field, value);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.SidebarPreviewView = Backbone.Marionette.LayoutView.extend({
|
/**
|
||||||
getTemplate: function() { return templates.sidebarPreview; },
|
* Responsible for rendering draggable layout widgets
|
||||||
events: {
|
*/
|
||||||
'click .mailpoet_show_preview': 'showPreview',
|
Module.SidebarLayoutWidgetsView = Module.SidebarWidgetsView.extend({
|
||||||
'click #mailpoet_send_preview': 'sendPreview',
|
getTemplate: function() { return templates.sidebarLayout; },
|
||||||
},
|
});
|
||||||
showPreview: function() {
|
/**
|
||||||
var json = App.toJSON();
|
* Responsible for managing global styles
|
||||||
|
*/
|
||||||
|
Module.SidebarStylesView = Backbone.Marionette.LayoutView.extend({
|
||||||
|
getTemplate: function() { return templates.sidebarStyles; },
|
||||||
|
events: function() {
|
||||||
|
return {
|
||||||
|
"change #mailpoet_text_font_color": _.partial(this.changeColorField, 'text.fontColor'),
|
||||||
|
"change #mailpoet_text_font_family": function(event) {
|
||||||
|
this.model.set('text.fontFamily', event.target.value);
|
||||||
|
},
|
||||||
|
"change #mailpoet_text_font_size": function(event) {
|
||||||
|
this.model.set('text.fontSize', event.target.value);
|
||||||
|
},
|
||||||
|
"change #mailpoet_h1_font_color": _.partial(this.changeColorField, 'h1.fontColor'),
|
||||||
|
"change #mailpoet_h1_font_family": function(event) {
|
||||||
|
this.model.set('h1.fontFamily', event.target.value);
|
||||||
|
},
|
||||||
|
"change #mailpoet_h1_font_size": function(event) {
|
||||||
|
this.model.set('h1.fontSize', event.target.value);
|
||||||
|
},
|
||||||
|
"change #mailpoet_h2_font_color": _.partial(this.changeColorField, 'h2.fontColor'),
|
||||||
|
"change #mailpoet_h2_font_family": function(event) {
|
||||||
|
this.model.set('h2.fontFamily', event.target.value);
|
||||||
|
},
|
||||||
|
"change #mailpoet_h2_font_size": function(event) {
|
||||||
|
this.model.set('h2.fontSize', event.target.value);
|
||||||
|
},
|
||||||
|
"change #mailpoet_h3_font_color": _.partial(this.changeColorField, 'h3.fontColor'),
|
||||||
|
"change #mailpoet_h3_font_family": function(event) {
|
||||||
|
this.model.set('h3.fontFamily', event.target.value);
|
||||||
|
},
|
||||||
|
"change #mailpoet_h3_font_size": function(event) {
|
||||||
|
this.model.set('h3.fontSize', event.target.value);
|
||||||
|
},
|
||||||
|
"change #mailpoet_a_font_color": _.partial(this.changeColorField, 'link.fontColor'),
|
||||||
|
"change #mailpoet_a_font_underline": function(event) {
|
||||||
|
this.model.set('link.textDecoration', (event.target.checked) ? event.target.value : 'none');
|
||||||
|
},
|
||||||
|
"change #mailpoet_newsletter_background_color": _.partial(this.changeColorField, 'newsletter.backgroundColor'),
|
||||||
|
"change #mailpoet_background_color": _.partial(this.changeColorField, 'background.backgroundColor'),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
templateHelpers: function() {
|
||||||
|
return {
|
||||||
|
model: this.model.toJSON(),
|
||||||
|
availableStyles: this.availableStyles.toJSON(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
initialize: function(options) {
|
||||||
|
this.availableStyles = options.availableStyles;
|
||||||
|
var that = this;
|
||||||
|
},
|
||||||
|
onRender: function() {
|
||||||
|
var that = this;
|
||||||
|
this.$('.mailpoet_color').spectrum({
|
||||||
|
clickoutFiresChange: true,
|
||||||
|
showInput: true,
|
||||||
|
showInitial: true,
|
||||||
|
preferredFormat: "hex6",
|
||||||
|
allowEmpty: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
changeField: function(field, event) {
|
||||||
|
this.model.set(field, jQuery(event.target).val());
|
||||||
|
},
|
||||||
|
changeColorField: function(field, event) {
|
||||||
|
var value = jQuery(event.target).val();
|
||||||
|
if (value === '') {
|
||||||
|
value = 'transparent';
|
||||||
|
}
|
||||||
|
this.model.set(field, value);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
mailpoet_post_json('newsletter_render.php', { data: json }, function(response) {
|
Module.SidebarPreviewView = Backbone.Marionette.LayoutView.extend({
|
||||||
console.log('Should open a new window');
|
getTemplate: function() { return templates.sidebarPreview; },
|
||||||
window.open('data:text/html,' + encodeURIComponent(response), '_blank');
|
events: {
|
||||||
}, function(error) {
|
'click .mailpoet_show_preview': 'showPreview',
|
||||||
console.log('Preview error', json);
|
'click #mailpoet_send_preview': 'sendPreview',
|
||||||
alert('Something went wrong, check console');
|
},
|
||||||
});
|
showPreview: function() {
|
||||||
},
|
var json = App.toJSON();
|
||||||
sendPreview: function() {
|
|
||||||
// testing sending method
|
|
||||||
console.log('trying to send a preview');
|
|
||||||
// get form data
|
|
||||||
var data = {
|
|
||||||
from_name: this.$('#mailpoet_preview_from_name').val(),
|
|
||||||
from_email: this.$('#mailpoet_preview_from_email').val(),
|
|
||||||
to_email: this.$('#mailpoet_preview_to_email').val(),
|
|
||||||
newsletter: App.newsletterId,
|
|
||||||
};
|
|
||||||
|
|
||||||
// send test email
|
mailpoet_post_json('newsletter_render.php', { data: json }, function(response) {
|
||||||
MailPoet.Modal.loading(true);
|
console.log('Should open a new window');
|
||||||
|
window.open('data:text/html,' + encodeURIComponent(response), '_blank');
|
||||||
|
}, function(error) {
|
||||||
|
console.log('Preview error', json);
|
||||||
|
alert('Something went wrong, check console');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
sendPreview: function() {
|
||||||
|
// testing sending method
|
||||||
|
console.log('trying to send a preview');
|
||||||
|
// get form data
|
||||||
|
var data = {
|
||||||
|
from_name: this.$('#mailpoet_preview_from_name').val(),
|
||||||
|
from_email: this.$('#mailpoet_preview_from_email').val(),
|
||||||
|
to_email: this.$('#mailpoet_preview_to_email').val(),
|
||||||
|
newsletter: App.newsletterId,
|
||||||
|
};
|
||||||
|
|
||||||
mailpoet_post_wpi('newsletter_preview.php', data, function(response) {
|
// send test email
|
||||||
if(response.success !== undefined && response.success === true) {
|
MailPoet.Modal.loading(true);
|
||||||
MailPoet.Notice.success(App.getConfig().get('translations.testEmailSent'));
|
|
||||||
} else if(response.error !== undefined) {
|
|
||||||
if(response.error.length === 0) {
|
|
||||||
MailPoet.Notice.error(App.getConfig().get('translations.unknownErrorOccurred'));
|
|
||||||
} else {
|
|
||||||
$(response.error).each(function(i, error) {
|
|
||||||
MailPoet.Notice.error(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MailPoet.Modal.loading(false);
|
|
||||||
}, function(error) {
|
|
||||||
// an error occurred
|
|
||||||
MailPoet.Modal.loading(false);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
App.on('before:start', function(options) {
|
mailpoet_post_wpi('newsletter_preview.php', data, function(response) {
|
||||||
App.registerWidget = Module.registerWidget;
|
if(response.success !== undefined && response.success === true) {
|
||||||
App.getWidgets = Module.getWidgets;
|
MailPoet.Notice.success(App.getConfig().get('translations.testEmailSent'));
|
||||||
App.registerLayoutWidget = Module.registerLayoutWidget;
|
} else if(response.error !== undefined) {
|
||||||
App.getLayoutWidgets = Module.getLayoutWidgets;
|
if(response.error.length === 0) {
|
||||||
});
|
MailPoet.Notice.error(App.getConfig().get('translations.unknownErrorOccurred'));
|
||||||
|
} else {
|
||||||
|
$(response.error).each(function(i, error) {
|
||||||
|
MailPoet.Notice.error(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MailPoet.Modal.loading(false);
|
||||||
|
}, function(error) {
|
||||||
|
// an error occurred
|
||||||
|
MailPoet.Modal.loading(false);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
App.on('start', function(options) {
|
App.on('before:start', function(options) {
|
||||||
var stylesModel = App.getGlobalStyles(),
|
App.registerWidget = Module.registerWidget;
|
||||||
sidebarView = new SidebarView();
|
App.getWidgets = Module.getWidgets;
|
||||||
|
App.registerLayoutWidget = Module.registerLayoutWidget;
|
||||||
|
App.getLayoutWidgets = Module.getLayoutWidgets;
|
||||||
|
});
|
||||||
|
|
||||||
|
App.on('start', function(options) {
|
||||||
|
var stylesModel = App.getGlobalStyles(),
|
||||||
|
sidebarView = new SidebarView();
|
||||||
|
|
||||||
|
App._appView.sidebarRegion.show(sidebarView);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App._appView.sidebarRegion.show(sidebarView);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,75 +1,84 @@
|
|||||||
EditorApplication.module("components.styles", function(Module, App, Backbone, Marionette, $, _) {
|
define('newsletter_editor/components/styles', [
|
||||||
"use strict";
|
'newsletter_editor/App',
|
||||||
|
'backbone',
|
||||||
|
'backbone.supermodel',
|
||||||
|
'backbone.marionette',
|
||||||
|
], function(EditorApplication, Backbone, SuperModel, Marionette) {
|
||||||
|
|
||||||
Module.StylesModel = Backbone.SuperModel.extend({
|
EditorApplication.module("components.styles", function(Module, App, Backbone, Marionette, $, _) {
|
||||||
defaults: {
|
"use strict";
|
||||||
text: {
|
|
||||||
fontColor: '#000000',
|
|
||||||
fontFamily: 'Arial',
|
|
||||||
fontSize: '16px',
|
|
||||||
},
|
|
||||||
h1: {
|
|
||||||
fontColor: '#111111',
|
|
||||||
fontFamily: 'Arial Black',
|
|
||||||
fontSize: '40px'
|
|
||||||
},
|
|
||||||
h2: {
|
|
||||||
fontColor: '#222222',
|
|
||||||
fontFamily: 'Tahoma',
|
|
||||||
fontSize: '32px',
|
|
||||||
},
|
|
||||||
h3: {
|
|
||||||
fontColor: '#333333',
|
|
||||||
fontFamily: 'Verdana',
|
|
||||||
fontSize: '24px',
|
|
||||||
},
|
|
||||||
link: {
|
|
||||||
fontColor: '#21759B',
|
|
||||||
textDecoration: 'underline',
|
|
||||||
},
|
|
||||||
newsletter: {
|
|
||||||
backgroundColor: '#ffffff',
|
|
||||||
},
|
|
||||||
background: {
|
|
||||||
backgroundColor: '#cccccc',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
initialize: function() {
|
|
||||||
this.on('change', function() { App.getChannel().trigger('autoSave'); });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Module.StylesView = Marionette.ItemView.extend({
|
Module.StylesModel = SuperModel.extend({
|
||||||
getTemplate: function() { return templates.styles; },
|
defaults: {
|
||||||
modelEvents: {
|
text: {
|
||||||
'change': 'render',
|
fontColor: '#000000',
|
||||||
},
|
fontFamily: 'Arial',
|
||||||
});
|
fontSize: '16px',
|
||||||
|
},
|
||||||
|
h1: {
|
||||||
|
fontColor: '#111111',
|
||||||
|
fontFamily: 'Arial Black',
|
||||||
|
fontSize: '40px'
|
||||||
|
},
|
||||||
|
h2: {
|
||||||
|
fontColor: '#222222',
|
||||||
|
fontFamily: 'Tahoma',
|
||||||
|
fontSize: '32px',
|
||||||
|
},
|
||||||
|
h3: {
|
||||||
|
fontColor: '#333333',
|
||||||
|
fontFamily: 'Verdana',
|
||||||
|
fontSize: '24px',
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
fontColor: '#21759B',
|
||||||
|
textDecoration: 'underline',
|
||||||
|
},
|
||||||
|
newsletter: {
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
},
|
||||||
|
background: {
|
||||||
|
backgroundColor: '#cccccc',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
initialize: function() {
|
||||||
|
this.on('change', function() { App.getChannel().trigger('autoSave'); });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Module._globalStyles = new Backbone.SuperModel();
|
Module.StylesView = Marionette.ItemView.extend({
|
||||||
Module.getGlobalStyles = function() {
|
getTemplate: function() { return templates.styles; },
|
||||||
return Module._globalStyles;
|
modelEvents: {
|
||||||
};
|
'change': 'render',
|
||||||
Module.setGlobalStyles = function(options) {
|
},
|
||||||
Module._globalStyles = new Module.StylesModel(options);
|
});
|
||||||
return Module._globalStyles;
|
|
||||||
};
|
|
||||||
Module.getAvailableStyles = function() {
|
|
||||||
return App.getConfig().get('availableStyles');
|
|
||||||
};
|
|
||||||
|
|
||||||
App.on('before:start', function(options) {
|
Module._globalStyles = new SuperModel();
|
||||||
// Expose style methods to global application
|
Module.getGlobalStyles = function() {
|
||||||
App.getGlobalStyles = Module.getGlobalStyles;
|
return Module._globalStyles;
|
||||||
App.setGlobalStyles = Module.setGlobalStyles;
|
};
|
||||||
|
Module.setGlobalStyles = function(options) {
|
||||||
|
Module._globalStyles = new Module.StylesModel(options);
|
||||||
|
return Module._globalStyles;
|
||||||
|
};
|
||||||
|
Module.getAvailableStyles = function() {
|
||||||
|
return App.getConfig().get('availableStyles');
|
||||||
|
};
|
||||||
|
|
||||||
App.getAvailableStyles = Module.getAvailableStyles;
|
App.on('before:start', function(options) {
|
||||||
|
// Expose style methods to global application
|
||||||
|
App.getGlobalStyles = Module.getGlobalStyles;
|
||||||
|
App.setGlobalStyles = Module.setGlobalStyles;
|
||||||
|
|
||||||
this.setGlobalStyles(options.newsletter.styles);
|
App.getAvailableStyles = Module.getAvailableStyles;
|
||||||
});
|
|
||||||
|
this.setGlobalStyles(options.newsletter.styles);
|
||||||
|
});
|
||||||
|
|
||||||
|
App.on('start', function(options) {
|
||||||
|
var stylesView = new Module.StylesView({ model: App.getGlobalStyles() });
|
||||||
|
App._appView.stylesRegion.show(stylesView);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
App.on('start', function(options) {
|
|
||||||
var stylesView = new Module.StylesView({ model: App.getGlobalStyles() });
|
|
||||||
App._appView.stylesRegion.show(stylesView);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,28 +0,0 @@
|
|||||||
var EditorApplication = (function() {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var app = new Backbone.Marionette.Application(), AppView;
|
|
||||||
|
|
||||||
// Decoupled communication between application components
|
|
||||||
app.getChannel = function(channel) {
|
|
||||||
if (channel === undefined) return app.channel;
|
|
||||||
return Radio.channel(channel);
|
|
||||||
};
|
|
||||||
|
|
||||||
AppView = Marionette.LayoutView.extend({
|
|
||||||
el: '#mailpoet_editor',
|
|
||||||
regions: {
|
|
||||||
stylesRegion: '#mailpoet_editor_styles',
|
|
||||||
contentRegion: '#mailpoet_editor_content',
|
|
||||||
sidebarRegion: '#mailpoet_editor_sidebar',
|
|
||||||
bottomRegion: '#mailpoet_editor_bottom',
|
|
||||||
headingRegion: '#mailpoet_editor_heading',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
app.on('start', function(options) {
|
|
||||||
app._appView = new AppView();
|
|
||||||
});
|
|
||||||
|
|
||||||
return app;
|
|
||||||
})();
|
|
@ -10,50 +10,51 @@
|
|||||||
|
|
||||||
/*jshint unused:false */
|
/*jshint unused:false */
|
||||||
/*global tinymce:true */
|
/*global tinymce:true */
|
||||||
|
define('mailpoet_custom_fields', ['jquery', 'tinymce'], function(jQuery, tinymce) {
|
||||||
|
tinymce.PluginManager.add('mailpoet_custom_fields', function(editor, url) {
|
||||||
|
var appendLabelAndClose = function(text) {
|
||||||
|
editor.insertContent('[' + text + ']');
|
||||||
|
editor.windowManager.close();
|
||||||
|
},
|
||||||
|
generateOnClickFunc = function(id) {
|
||||||
|
return function() {
|
||||||
|
appendLabelAndClose(id);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
tinymce.PluginManager.add('mailpoet_custom_fields', function(editor, url) {
|
editor.addButton('mailpoet_custom_fields', {
|
||||||
var appendLabelAndClose = function(text) {
|
icon: 'mailpoet_custom_fields',
|
||||||
editor.insertContent('[' + text + ']');
|
onclick: function() {
|
||||||
editor.windowManager.close();
|
var customFields = [],
|
||||||
},
|
configCustomFields = editor.settings.mailpoet_custom_fields;
|
||||||
generateOnClickFunc = function(id) {
|
|
||||||
return function() {
|
|
||||||
appendLabelAndClose(id);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
editor.addButton('mailpoet_custom_fields', {
|
for (var segment in configCustomFields) {
|
||||||
icon: 'mailpoet_custom_fields',
|
if (configCustomFields.hasOwnProperty(segment)) {
|
||||||
onclick: function() {
|
customFields.push({
|
||||||
var customFields = [],
|
type: 'label',
|
||||||
configCustomFields = editor.settings.mailpoet_custom_fields;
|
text: segment,
|
||||||
|
});
|
||||||
|
|
||||||
for (var segment in configCustomFields) {
|
for (var i = 0; i < configCustomFields[segment].length; i += 1) {
|
||||||
if (configCustomFields.hasOwnProperty(segment)) {
|
customFields.push({
|
||||||
customFields.push({
|
type: 'button',
|
||||||
type: 'label',
|
text: configCustomFields[segment][i].text,
|
||||||
text: segment,
|
onClick: generateOnClickFunc(configCustomFields[segment][i].shortcode)
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0; i < configCustomFields[segment].length; i += 1) {
|
// Open window
|
||||||
customFields.push({
|
editor.windowManager.open({
|
||||||
type: 'button',
|
height: parseInt(editor.getParam("plugin_mailpoet_custom_fields_height", 400)),
|
||||||
text: configCustomFields[segment][i].text,
|
width: parseInt(editor.getParam("plugin_mailpoet_custom_fields_width", 450)),
|
||||||
onClick: generateOnClickFunc(configCustomFields[segment][i].shortcode)
|
autoScroll: true,
|
||||||
});
|
title: editor.settings.mailpoet_custom_fields_window_title,
|
||||||
}
|
body: customFields,
|
||||||
}
|
buttons: [],
|
||||||
}
|
});
|
||||||
|
},
|
||||||
// Open window
|
});
|
||||||
editor.windowManager.open({
|
});
|
||||||
height: parseInt(editor.getParam("plugin_mailpoet_custom_fields_height", 400)),
|
|
||||||
width: parseInt(editor.getParam("plugin_mailpoet_custom_fields_width", 450)),
|
|
||||||
autoScroll: true,
|
|
||||||
title: editor.settings.mailpoet_custom_fields_window_title,
|
|
||||||
body: customFields,
|
|
||||||
buttons: [],
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -82,6 +82,7 @@ class Menu {
|
|||||||
|
|
||||||
function newsletterEditor() {
|
function newsletterEditor() {
|
||||||
$data = array();
|
$data = array();
|
||||||
|
wp_enqueue_media();
|
||||||
echo $this->renderer->render('newsletter/editor.html', $data);
|
echo $this->renderer->render('newsletter/editor.html', $data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,12 +97,13 @@
|
|||||||
<%= partial('newsletter_editor_template_automated_latest_content_block', 'newsletter/templates/blocks/automatedLatestContent/block.hbs') %>
|
<%= partial('newsletter_editor_template_automated_latest_content_block', 'newsletter/templates/blocks/automatedLatestContent/block.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_automated_latest_content_widget', 'newsletter/templates/blocks/automatedLatestContent/widget.hbs') %>
|
<%= partial('newsletter_editor_template_automated_latest_content_widget', 'newsletter/templates/blocks/automatedLatestContent/widget.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_automated_latest_content_settings', 'newsletter/templates/blocks/automatedLatestContent/settings.hbs') %>
|
<%= partial('newsletter_editor_template_automated_latest_content_settings', 'newsletter/templates/blocks/automatedLatestContent/settings.hbs') %>
|
||||||
|
|
||||||
<%= partial('newsletter_editor_template_button_block', 'newsletter/templates/blocks/button/block.hbs') %>
|
<%= partial('newsletter_editor_template_button_block', 'newsletter/templates/blocks/button/block.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_button_widget', 'newsletter/templates/blocks/button/widget.hbs') %>
|
<%= partial('newsletter_editor_template_button_widget', 'newsletter/templates/blocks/button/widget.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_button_settings', 'newsletter/templates/blocks/button/settings.hbs') %>
|
<%= partial('newsletter_editor_template_button_settings', 'newsletter/templates/blocks/button/settings.hbs') %>
|
||||||
|
|
||||||
<%= partial('newsletter_editor_template_container_block', 'newsletter/templates/blocks/container/block.hbs') %>
|
<%= partial('newsletter_editor_template_container_block', 'newsletter/templates/blocks/container/block.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_container_block', 'newsletter/templates/blocks/container/emptyBlock.hbs') %>
|
<%= partial('newsletter_editor_template_container_block_empty', 'newsletter/templates/blocks/container/emptyBlock.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_container_one_column_widget', 'newsletter/templates/blocks/container/oneColumnLayoutWidget.hbs') %>
|
<%= partial('newsletter_editor_template_container_one_column_widget', 'newsletter/templates/blocks/container/oneColumnLayoutWidget.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_container_two_column_widget', 'newsletter/templates/blocks/container/twoColumnLayoutWidget.hbs') %>
|
<%= partial('newsletter_editor_template_container_two_column_widget', 'newsletter/templates/blocks/container/twoColumnLayoutWidget.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_container_three_column_widget', 'newsletter/templates/blocks/container/threeColumnLayoutWidget.hbs') %>
|
<%= partial('newsletter_editor_template_container_three_column_widget', 'newsletter/templates/blocks/container/threeColumnLayoutWidget.hbs') %>
|
||||||
@ -133,6 +134,7 @@
|
|||||||
<%= partial('newsletter_editor_template_posts_settings_single_post', 'newsletter/templates/blocks/posts/settingsSinglePost.hbs') %>
|
<%= partial('newsletter_editor_template_posts_settings_single_post', 'newsletter/templates/blocks/posts/settingsSinglePost.hbs') %>
|
||||||
|
|
||||||
<%= partial('newsletter_editor_template_social_block', 'newsletter/templates/blocks/social/block.hbs') %>
|
<%= partial('newsletter_editor_template_social_block', 'newsletter/templates/blocks/social/block.hbs') %>
|
||||||
|
<%= partial('newsletter_editor_template_social_block_icon', 'newsletter/templates/blocks/social/blockIcon.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_social_widget', 'newsletter/templates/blocks/social/widget.hbs') %>
|
<%= partial('newsletter_editor_template_social_widget', 'newsletter/templates/blocks/social/widget.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_social_settings', 'newsletter/templates/blocks/social/settings.hbs') %>
|
<%= partial('newsletter_editor_template_social_settings', 'newsletter/templates/blocks/social/settings.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_social_settings_icon', 'newsletter/templates/blocks/social/settingsIcon.hbs') %>
|
<%= partial('newsletter_editor_template_social_settings_icon', 'newsletter/templates/blocks/social/settingsIcon.hbs') %>
|
||||||
@ -152,10 +154,670 @@
|
|||||||
<%= partial('newsletter_editor_template_styles', 'newsletter/templates/components/styles.hbs') %>
|
<%= partial('newsletter_editor_template_styles', 'newsletter/templates/components/styles.hbs') %>
|
||||||
|
|
||||||
<%= partial('newsletter_editor_template_sidebar', 'newsletter/templates/components/sidebar/sidebar.hbs') %>
|
<%= partial('newsletter_editor_template_sidebar', 'newsletter/templates/components/sidebar/sidebar.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_content', 'newsletter/templates/components/sidebar/content.hbs') %>
|
<%= partial('newsletter_editor_template_sidebar_content', 'newsletter/templates/components/sidebar/content.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_layout', 'newsletter/templates/components/sidebar/layout.hbs') %>
|
<%= partial('newsletter_editor_template_sidebar_layout', 'newsletter/templates/components/sidebar/layout.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_preview', 'newsletter/templates/components/sidebar/preview.hbs') %>
|
<%= partial('newsletter_editor_template_sidebar_preview', 'newsletter/templates/components/sidebar/preview.hbs') %>
|
||||||
<%= partial('newsletter_editor_template_styles', 'newsletter/templates/components/sidebar/styles.hbs') %>
|
<%= partial('newsletter_editor_template_sidebar_styles', 'newsletter/templates/components/sidebar/styles.hbs') %>
|
||||||
|
|
||||||
<%= stylesheet('newsletter_editor.css') %>
|
<%= stylesheet(
|
||||||
|
'lib/select2/select2.css',
|
||||||
|
'lib/spectrum.css',
|
||||||
|
'newsletter_editor.css'
|
||||||
|
) %>
|
||||||
|
|
||||||
|
<%= javascript(
|
||||||
|
'vendor.js',
|
||||||
|
'newsletter_editor.js'
|
||||||
|
) %>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var templates = {
|
||||||
|
styles: Handlebars.compile(jQuery('#newsletter_editor_template_styles').html()),
|
||||||
|
save: Handlebars.compile(jQuery('#newsletter_editor_template_save').html()),
|
||||||
|
heading: Handlebars.compile(jQuery('#newsletter_editor_template_heading').html()),
|
||||||
|
|
||||||
|
sidebar: Handlebars.compile(jQuery('#newsletter_editor_template_sidebar').html()),
|
||||||
|
sidebarContent: Handlebars.compile(jQuery('#newsletter_editor_template_sidebar_content').html()),
|
||||||
|
sidebarLayout: Handlebars.compile(jQuery('#newsletter_editor_template_sidebar_layout').html()),
|
||||||
|
sidebarStyles: Handlebars.compile(jQuery('#newsletter_editor_template_sidebar_styles').html()),
|
||||||
|
sidebarPreview: Handlebars.compile(jQuery('#newsletter_editor_template_sidebar_preview').html()),
|
||||||
|
|
||||||
|
genericBlockTools: Handlebars.compile(jQuery('#newsletter_editor_template_tools_generic').html()),
|
||||||
|
|
||||||
|
containerBlock: Handlebars.compile(jQuery('#newsletter_editor_template_container_block').html()),
|
||||||
|
containerEmpty: Handlebars.compile(jQuery('#newsletter_editor_template_container_block_empty').html()),
|
||||||
|
oneColumnLayoutInsertion: Handlebars.compile(jQuery('#newsletter_editor_template_container_one_column_widget').html()),
|
||||||
|
twoColumnLayoutInsertion: Handlebars.compile(jQuery('#newsletter_editor_template_container_two_column_widget').html()),
|
||||||
|
threeColumnLayoutInsertion: Handlebars.compile(jQuery('#newsletter_editor_template_container_three_column_widget').html()),
|
||||||
|
containerBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_container_settings').html()),
|
||||||
|
|
||||||
|
buttonBlock: Handlebars.compile(jQuery('#newsletter_editor_template_button_block').html()),
|
||||||
|
buttonInsertion: Handlebars.compile(jQuery('#newsletter_editor_template_button_widget').html()),
|
||||||
|
buttonBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_button_settings').html()),
|
||||||
|
|
||||||
|
dividerBlock: Handlebars.compile(jQuery('#newsletter_editor_template_divider_block').html()),
|
||||||
|
dividerInsertion: Handlebars.compile(jQuery('#newsletter_editor_template_divider_widget').html()),
|
||||||
|
dividerBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_divider_settings').html()),
|
||||||
|
|
||||||
|
footerBlock: Handlebars.compile(jQuery('#newsletter_editor_template_footer_block').html()),
|
||||||
|
footerInsertion: Handlebars.compile(jQuery('#newsletter_editor_template_footer_widget').html()),
|
||||||
|
footerBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_footer_settings').html()),
|
||||||
|
|
||||||
|
headerBlock: Handlebars.compile(jQuery('#newsletter_editor_template_header_block').html()),
|
||||||
|
headerInsertion: Handlebars.compile(jQuery('#newsletter_editor_template_header_widget').html()),
|
||||||
|
headerBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_header_settings').html()),
|
||||||
|
|
||||||
|
imageBlock: Handlebars.compile(jQuery('#newsletter_editor_template_image_block').html()),
|
||||||
|
imageInsertion: Handlebars.compile(jQuery('#newsletter_editor_template_image_widget').html()),
|
||||||
|
imageBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_image_settings').html()),
|
||||||
|
|
||||||
|
socialBlock: Handlebars.compile(jQuery('#newsletter_editor_template_social_block').html()),
|
||||||
|
socialIconBlock: Handlebars.compile(jQuery('#newsletter_editor_template_social_block_icon').html()),
|
||||||
|
socialInsertion: Handlebars.compile(jQuery('#newsletter_editor_template_social_widget').html()),
|
||||||
|
socialBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_social_settings').html()),
|
||||||
|
socialSettingsIconSelector: Handlebars.compile(jQuery('#newsletter_editor_template_social_settings_icon_selector').html()),
|
||||||
|
socialSettingsIcon: Handlebars.compile(jQuery('#newsletter_editor_template_social_settings_icon').html()),
|
||||||
|
socialSettingsStyles: Handlebars.compile(jQuery('#newsletter_editor_template_social_settings_styles').html()),
|
||||||
|
|
||||||
|
spacerBlock: Handlebars.compile(jQuery('#newsletter_editor_template_spacer_block').html()),
|
||||||
|
spacerInsertion: Handlebars.compile(jQuery('#newsletter_editor_template_spacer_widget').html()),
|
||||||
|
spacerBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_spacer_settings').html()),
|
||||||
|
|
||||||
|
automatedLatestContentBlock: Handlebars.compile(jQuery('#newsletter_editor_template_automated_latest_content_block').html()),
|
||||||
|
automatedLatestContentInsertion: Handlebars.compile(jQuery('#newsletter_editor_template_automated_latest_content_widget').html()),
|
||||||
|
automatedLatestContentBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_automated_latest_content_settings').html()),
|
||||||
|
|
||||||
|
postsBlock: Handlebars.compile(jQuery('#newsletter_editor_template_posts_block').html()),
|
||||||
|
postsInsertion: Handlebars.compile(jQuery('#newsletter_editor_template_posts_widget').html()),
|
||||||
|
postsBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_posts_settings').html()),
|
||||||
|
postSelectionPostsBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_posts_settings_selection').html()),
|
||||||
|
emptyPostPostsBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_posts_settings_selection_empty').html()),
|
||||||
|
singlePostPostsBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_posts_settings_single_post').html()),
|
||||||
|
displayOptionsPostsBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_posts_settings_display_options').html()),
|
||||||
|
|
||||||
|
textBlock: Handlebars.compile(jQuery('#newsletter_editor_template_text_block').html()),
|
||||||
|
textInsertion: Handlebars.compile(jQuery('#newsletter_editor_template_text_widget').html()),
|
||||||
|
textBlockSettings: Handlebars.compile(jQuery('#newsletter_editor_template_text_settings').html()),
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var newsletter = {
|
||||||
|
data: {},
|
||||||
|
styles: {
|
||||||
|
text: {
|
||||||
|
fontColor: "#565656",
|
||||||
|
fontFamily: "Arial",
|
||||||
|
fontSize: "16px"
|
||||||
|
},
|
||||||
|
h1: {
|
||||||
|
fontColor: "#565656",
|
||||||
|
fontFamily: "Arial",
|
||||||
|
fontSize: "36px"
|
||||||
|
},
|
||||||
|
h2: {
|
||||||
|
fontColor: "#565656",
|
||||||
|
fontFamily: "Arial",
|
||||||
|
fontSize: "26px"
|
||||||
|
},
|
||||||
|
h3: {
|
||||||
|
fontColor: "#565656",
|
||||||
|
fontFamily: "Arial",
|
||||||
|
fontSize: "18px"
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
fontColor: "#a86b6b",
|
||||||
|
textDecoration: "underline"
|
||||||
|
},
|
||||||
|
newsletter: {
|
||||||
|
backgroundColor: "#999999"
|
||||||
|
},
|
||||||
|
background: {
|
||||||
|
backgroundColor: "#333333"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
}, config = {
|
||||||
|
availableStyles: {
|
||||||
|
textSizes: [
|
||||||
|
'9px', '10px', '11px', '12px', '13px', '14px', '15px', '16px', '17px', '18px', '19px', '20px', '21px', '22px', '23px', '24px',
|
||||||
|
],
|
||||||
|
headingSizes: [
|
||||||
|
'10px', '12px', '14px', '16px', '18px', '20px', '22px', '24px', '26px', '30px', '36px', '40px',
|
||||||
|
],
|
||||||
|
fonts: [
|
||||||
|
'Arial',
|
||||||
|
'Comic Sans',
|
||||||
|
'Courier New',
|
||||||
|
'Georgia',
|
||||||
|
'Lucida',
|
||||||
|
'Tahoma',
|
||||||
|
'Times New Roman',
|
||||||
|
'Trebuchet MS',
|
||||||
|
'Verdana',
|
||||||
|
],
|
||||||
|
socialIconSets: {
|
||||||
|
'default': {
|
||||||
|
'custom': '<%= 'assets/img/newsletter_editor/social-icons/custom.png' %>',
|
||||||
|
'facebook': '<%= 'assets/img/newsletter_editor/social-icons/01-social/Facebook.png' %>',
|
||||||
|
'twitter': '<%= 'assets/img/newsletter_editor/social-icons/01-social/Twitter.png' %>',
|
||||||
|
'google-plus': '<%= 'assets/img/newsletter_editor/social-icons/01-social/Google-Plus.png' %>',
|
||||||
|
'youtube': '<%= 'assets/img/newsletter_editor/social-icons/01-social/Youtube.png' %>',
|
||||||
|
'website': '<%= 'assets/img/newsletter_editor/social-icons/01-social/Website.png' %>',
|
||||||
|
'email': '<%= 'assets/img/newsletter_editor/social-icons/01-social/Email.png' %>',
|
||||||
|
'instagram': '<%= 'assets/img/newsletter_editor/social-icons/01-social/Instagram.png' %>',
|
||||||
|
'pinterest': '<%= 'assets/img/newsletter_editor/social-icons/01-social/Pinterest.png' %>',
|
||||||
|
'linkedin': '<%= 'assets/img/newsletter_editor/social-icons/01-social/LinkedIn.png' %>',
|
||||||
|
},
|
||||||
|
'grey': {
|
||||||
|
'custom': '<%= 'assets/img/newsletter_editor/social-icons/custom.png' %>',
|
||||||
|
'facebook': '<%= 'assets/img/newsletter_editor/social-icons/02-grey/Facebook.png' %>',
|
||||||
|
'twitter': '<%= 'assets/img/newsletter_editor/social-icons/02-grey/Twitter.png' %>',
|
||||||
|
'google-plus': '<%= 'assets/img/newsletter_editor/social-icons/02-grey/Google-Plus.png' %>',
|
||||||
|
'youtube': '<%= 'assets/img/newsletter_editor/social-icons/02-grey/Youtube.png' %>',
|
||||||
|
'website': '<%= 'assets/img/newsletter_editor/social-icons/02-grey/Website.png' %>',
|
||||||
|
'email': '<%= 'assets/img/newsletter_editor/social-icons/02-grey/Email.png' %>',
|
||||||
|
'instagram': '<%= 'assets/img/newsletter_editor/social-icons/02-grey/Instagram.png' %>',
|
||||||
|
'pinterest': '<%= 'assets/img/newsletter_editor/social-icons/02-grey/Pinterest.png' %>',
|
||||||
|
'linkedin': '<%= 'assets/img/newsletter_editor/social-icons/02-grey/LinkedIn.png' %>',
|
||||||
|
},
|
||||||
|
'circles': {
|
||||||
|
'custom': '<%= 'assets/img/newsletter_editor/social-icons/custom.png' %>',
|
||||||
|
'facebook': '<%= 'assets/img/newsletter_editor/social-icons/03-circles/Facebook.png' %>',
|
||||||
|
'twitter': '<%= 'assets/img/newsletter_editor/social-icons/03-circles/Twitter.png' %>',
|
||||||
|
'google-plus': '<%= 'assets/img/newsletter_editor/social-icons/03-circles/Google-Plus.png' %>',
|
||||||
|
'youtube': '<%= 'assets/img/newsletter_editor/social-icons/03-circles/Youtube.png' %>',
|
||||||
|
'website': '<%= 'assets/img/newsletter_editor/social-icons/03-circles/Website.png' %>',
|
||||||
|
'email': '<%= 'assets/img/newsletter_editor/social-icons/03-circles/Email.png' %>',
|
||||||
|
'instagram': '<%= 'assets/img/newsletter_editor/social-icons/03-circles/Instagram.png' %>',
|
||||||
|
'pinterest': '<%= 'assets/img/newsletter_editor/social-icons/03-circles/Pinterest.png' %>',
|
||||||
|
'linkedin': '<%= 'assets/img/newsletter_editor/social-icons/03-circles/LinkedIn.png' %>',
|
||||||
|
},
|
||||||
|
'full-flat-roundrect': {
|
||||||
|
'custom': '<%= 'assets/img/newsletter_editor/social-icons/custom.png' %>',
|
||||||
|
'facebook': '<%= 'assets/img/newsletter_editor/social-icons/04-full-flat-roundrect/Facebook.png' %>',
|
||||||
|
'twitter': '<%= 'assets/img/newsletter_editor/social-icons/04-full-flat-roundrect/Twitter.png' %>',
|
||||||
|
'google-plus': '<%= 'assets/img/newsletter_editor/social-icons/04-full-flat-roundrect/Google-Plus.png' %>',
|
||||||
|
'youtube': '<%= 'assets/img/newsletter_editor/social-icons/04-full-flat-roundrect/Youtube.png' %>',
|
||||||
|
'website': '<%= 'assets/img/newsletter_editor/social-icons/04-full-flat-roundrect/Website.png' %>',
|
||||||
|
'email': '<%= 'assets/img/newsletter_editor/social-icons/04-full-flat-roundrect/Email.png' %>',
|
||||||
|
'instagram': '<%= 'assets/img/newsletter_editor/social-icons/04-full-flat-roundrect/Instagram.png' %>',
|
||||||
|
'pinterest': '<%= 'assets/img/newsletter_editor/social-icons/04-full-flat-roundrect/Pinterest.png' %>',
|
||||||
|
'linkedin': '<%= 'assets/img/newsletter_editor/social-icons/04-full-flat-roundrect/LinkedIn.png' %>',
|
||||||
|
},
|
||||||
|
'full-gradient-square': {
|
||||||
|
'custom': '<%= 'assets/img/newsletter_editor/social-icons/custom.png' %>',
|
||||||
|
'facebook': '<%= 'assets/img/newsletter_editor/social-icons/05-full-gradient-square/Facebook.png' %>',
|
||||||
|
'twitter': '<%= 'assets/img/newsletter_editor/social-icons/05-full-gradient-square/Twitter.png' %>',
|
||||||
|
'google-plus': '<%= 'assets/img/newsletter_editor/social-icons/05-full-gradient-square/Google-Plus.png' %>',
|
||||||
|
'youtube': '<%= 'assets/img/newsletter_editor/social-icons/05-full-gradient-square/Youtube.png' %>',
|
||||||
|
'website': '<%= 'assets/img/newsletter_editor/social-icons/05-full-gradient-square/Website.png' %>',
|
||||||
|
'email': '<%= 'assets/img/newsletter_editor/social-icons/05-full-gradient-square/Email.png' %>',
|
||||||
|
'instagram': '<%= 'assets/img/newsletter_editor/social-icons/05-full-gradient-square/Instagram.png' %>',
|
||||||
|
'pinterest': '<%= 'assets/img/newsletter_editor/social-icons/05-full-gradient-square/Pinterest.png' %>',
|
||||||
|
'linkedin': '<%= 'assets/img/newsletter_editor/social-icons/05-full-gradient-square/LinkedIn.png' %>',
|
||||||
|
},
|
||||||
|
'full-symbol-color': {
|
||||||
|
'custom': '<%= 'assets/img/newsletter_editor/social-icons/custom.png' %>',
|
||||||
|
'facebook': '<%= 'assets/img/newsletter_editor/social-icons/06-full-symbol-color/Facebook.png' %>',
|
||||||
|
'twitter': '<%= 'assets/img/newsletter_editor/social-icons/06-full-symbol-color/Twitter.png' %>',
|
||||||
|
'google-plus': '<%= 'assets/img/newsletter_editor/social-icons/06-full-symbol-color/Google-Plus.png' %>',
|
||||||
|
'youtube': '<%= 'assets/img/newsletter_editor/social-icons/06-full-symbol-color/Youtube.png' %>',
|
||||||
|
'website': '<%= 'assets/img/newsletter_editor/social-icons/06-full-symbol-color/Website.png' %>',
|
||||||
|
'email': '<%= 'assets/img/newsletter_editor/social-icons/06-full-symbol-color/Email.png' %>',
|
||||||
|
'instagram': '<%= 'assets/img/newsletter_editor/social-icons/06-full-symbol-color/Instagram.png' %>',
|
||||||
|
'pinterest': '<%= 'assets/img/newsletter_editor/social-icons/06-full-symbol-color/Pinterest.png' %>',
|
||||||
|
'linkedin': '<%= 'assets/img/newsletter_editor/social-icons/06-full-symbol-color/LinkedIn.png' %>',
|
||||||
|
},
|
||||||
|
'full-symbol-black': {
|
||||||
|
'custom': '<%= 'assets/img/newsletter_editor/social-icons/custom.png' %>',
|
||||||
|
'facebook': '<%= 'assets/img/newsletter_editor/social-icons/07-full-symbol-black/Facebook.png' %>',
|
||||||
|
'twitter': '<%= 'assets/img/newsletter_editor/social-icons/07-full-symbol-black/Twitter.png' %>',
|
||||||
|
'google-plus': '<%= 'assets/img/newsletter_editor/social-icons/07-full-symbol-black/Google-Plus.png' %>',
|
||||||
|
'youtube': '<%= 'assets/img/newsletter_editor/social-icons/07-full-symbol-black/Youtube.png' %>',
|
||||||
|
'website': '<%= 'assets/img/newsletter_editor/social-icons/07-full-symbol-black/Website.png' %>',
|
||||||
|
'email': '<%= 'assets/img/newsletter_editor/social-icons/07-full-symbol-black/Email.png' %>',
|
||||||
|
'instagram': '<%= 'assets/img/newsletter_editor/social-icons/07-full-symbol-black/Instagram.png' %>',
|
||||||
|
'pinterest': '<%= 'assets/img/newsletter_editor/social-icons/07-full-symbol-black/Pinterest.png' %>',
|
||||||
|
'linkedin': '<%= 'assets/img/newsletter_editor/social-icons/07-full-symbol-black/LinkedIn.png' %>',
|
||||||
|
},
|
||||||
|
'full-symbol-grey': {
|
||||||
|
'custom': '<%= 'assets/img/newsletter_editor/social-icons/custom.png' %>',
|
||||||
|
'facebook': '<%= 'assets/img/newsletter_editor/social-icons/08-full-symbol-grey/Facebook.png' %>',
|
||||||
|
'twitter': '<%= 'assets/img/newsletter_editor/social-icons/08-full-symbol-grey/Twitter.png' %>',
|
||||||
|
'google-plus': '<%= 'assets/img/newsletter_editor/social-icons/08-full-symbol-grey/Google-Plus.png' %>',
|
||||||
|
'youtube': '<%= 'assets/img/newsletter_editor/social-icons/08-full-symbol-grey/Youtube.png' %>',
|
||||||
|
'website': '<%= 'assets/img/newsletter_editor/social-icons/08-full-symbol-grey/Website.png' %>',
|
||||||
|
'email': '<%= 'assets/img/newsletter_editor/social-icons/08-full-symbol-grey/Email.png' %>',
|
||||||
|
'instagram': '<%= 'assets/img/newsletter_editor/social-icons/08-full-symbol-grey/Instagram.png' %>',
|
||||||
|
'pinterest': '<%= 'assets/img/newsletter_editor/social-icons/08-full-symbol-grey/Pinterest.png' %>',
|
||||||
|
'linkedin': '<%= 'assets/img/newsletter_editor/social-icons/08-full-symbol-grey/LinkedIn.png' %>',
|
||||||
|
},
|
||||||
|
'line-roundrect': {
|
||||||
|
'custom': '<%= 'assets/img/newsletter_editor/social-icons/custom.png' %>',
|
||||||
|
'facebook': '<%= 'assets/img/newsletter_editor/social-icons/09-line-roundrect/Facebook.png' %>',
|
||||||
|
'twitter': '<%= 'assets/img/newsletter_editor/social-icons/09-line-roundrect/Twitter.png' %>',
|
||||||
|
'google-plus': '<%= 'assets/img/newsletter_editor/social-icons/09-line-roundrect/Google-Plus.png' %>',
|
||||||
|
'youtube': '<%= 'assets/img/newsletter_editor/social-icons/09-line-roundrect/Youtube.png' %>',
|
||||||
|
'website': '<%= 'assets/img/newsletter_editor/social-icons/09-line-roundrect/Website.png' %>',
|
||||||
|
'email': '<%= 'assets/img/newsletter_editor/social-icons/09-line-roundrect/Email.png' %>',
|
||||||
|
'instagram': '<%= 'assets/img/newsletter_editor/social-icons/09-line-roundrect/Instagram.png' %>',
|
||||||
|
'pinterest': '<%= 'assets/img/newsletter_editor/social-icons/09-line-roundrect/Pinterest.png' %>',
|
||||||
|
'linkedin': '<%= 'assets/img/newsletter_editor/social-icons/09-line-roundrect/LinkedIn.png' %>',
|
||||||
|
},
|
||||||
|
'line-square': {
|
||||||
|
'custom': '<%= 'assets/img/newsletter_editor/social-icons/custom.png' %>',
|
||||||
|
'facebook': '<%= 'assets/img/newsletter_editor/social-icons/10-line-square/Facebook.png' %>',
|
||||||
|
'twitter': '<%= 'assets/img/newsletter_editor/social-icons/10-line-square/Twitter.png' %>',
|
||||||
|
'google-plus': '<%= 'assets/img/newsletter_editor/social-icons/10-line-square/Google-Plus.png' %>',
|
||||||
|
'youtube': '<%= 'assets/img/newsletter_editor/social-icons/10-line-square/Youtube.png' %>',
|
||||||
|
'website': '<%= 'assets/img/newsletter_editor/social-icons/10-line-square/Website.png' %>',
|
||||||
|
'email': '<%= 'assets/img/newsletter_editor/social-icons/10-line-square/Email.png' %>',
|
||||||
|
'instagram': '<%= 'assets/img/newsletter_editor/social-icons/10-line-square/Instagram.png' %>',
|
||||||
|
'pinterest': '<%= 'assets/img/newsletter_editor/social-icons/10-line-square/Pinterest.png' %>',
|
||||||
|
'linkedin': '<%= 'assets/img/newsletter_editor/social-icons/10-line-square/LinkedIn.png' %>',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
dividers: [
|
||||||
|
'hidden',
|
||||||
|
'dotted',
|
||||||
|
'dashed',
|
||||||
|
'solid',
|
||||||
|
'double',
|
||||||
|
'groove',
|
||||||
|
'ridge',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
socialIcons: {
|
||||||
|
'facebook': {
|
||||||
|
title: 'Facebook',
|
||||||
|
linkFieldName: '<%= __('Link') %>',
|
||||||
|
defaultLink: 'http://www.facebook.com',
|
||||||
|
},
|
||||||
|
'twitter': {
|
||||||
|
title: 'Twitter',
|
||||||
|
linkFieldName: '<%= __('Link') %>',
|
||||||
|
defaultLink: 'http://www.twitter.com',
|
||||||
|
},
|
||||||
|
'google-plus': {
|
||||||
|
title: 'Google Plus',
|
||||||
|
linkFieldName: '<%= __('Link') %>',
|
||||||
|
defaultLink: 'http://plus.google.com',
|
||||||
|
},
|
||||||
|
'youtube': {
|
||||||
|
title: 'Youtube',
|
||||||
|
linkFieldName: '<%= __('Link') %>',
|
||||||
|
defaultLink: 'http://www.youtube.com',
|
||||||
|
},
|
||||||
|
'website': {
|
||||||
|
title: '<%= __('Website') %>',
|
||||||
|
linkFieldName: '<%= __('Link') %>',
|
||||||
|
defaultLink: 'http://example.org',
|
||||||
|
},
|
||||||
|
'email': {
|
||||||
|
title: '<%= __('Email') %>',
|
||||||
|
linkFieldName: '<%= __('Email') %>',
|
||||||
|
defaultLink: 'mailto:mail@example.org',
|
||||||
|
},
|
||||||
|
'instagram': {
|
||||||
|
title: 'Instagram',
|
||||||
|
linkFieldName: '<%= __('Link') %>',
|
||||||
|
defaultLink: 'http://instagram.com',
|
||||||
|
},
|
||||||
|
'pinterest': {
|
||||||
|
title: 'Pinterest',
|
||||||
|
linkFieldName: '<%= __('Link') %>',
|
||||||
|
defaultLink: 'http://www.pinterest.com',
|
||||||
|
},
|
||||||
|
'linkedin': {
|
||||||
|
title: 'LinkedIn',
|
||||||
|
linkFieldName: '<%= __('Link') %>',
|
||||||
|
defaultLink: 'http://www.linkedin.com',
|
||||||
|
},
|
||||||
|
'custom': {
|
||||||
|
title: '<%= __('Custom') %>',
|
||||||
|
linkFieldName: '<%= __('Link') %>',
|
||||||
|
defaultLink: 'http://example.org',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
blockDefaults: {
|
||||||
|
automatedLatestContent: {
|
||||||
|
amount: '5',
|
||||||
|
contentType: 'post', // 'post'|'page'|'mailpoet_page'
|
||||||
|
inclusionType: 'include', // 'include'|'exclude'
|
||||||
|
displayType: 'excerpt', // 'excerpt'|'full'|'titleOnly'
|
||||||
|
titleFormat: 'h1', // 'h1'|'h2'|'h3'|'ul'
|
||||||
|
titlePosition: 'inTextBlock', // 'inTextBlock'|'aboveBlock',
|
||||||
|
titleAlignment: 'left', // 'left'|'center'|'right'
|
||||||
|
titleIsLink: false, // false|true
|
||||||
|
imagePadded: true, // true|false
|
||||||
|
showAuthor: 'no', // 'no'|'aboveText'|'belowText'
|
||||||
|
authorPrecededBy: '<%= __('Author:') %>',
|
||||||
|
showCategories: 'no', // 'no'|'aboveText'|'belowText'
|
||||||
|
categoriesPrecededBy: '<%= __('Categories:') %>',
|
||||||
|
readMoreType: 'button', // 'link'|'button'
|
||||||
|
readMoreText: 'Read more', // 'link'|'button'
|
||||||
|
readMoreButton: {
|
||||||
|
text: '<%= __('Read more') %>',
|
||||||
|
url: '[postLink]',
|
||||||
|
styles: {
|
||||||
|
block: {
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
borderColor: '#00ddff',
|
||||||
|
borderWidth: '1px',
|
||||||
|
borderRadius: '5px',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
width: '120px',
|
||||||
|
lineHeight: '30px',
|
||||||
|
fontColor: '#00ddff',
|
||||||
|
fontFamily: 'Arial',
|
||||||
|
fontSize: '20px',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sortBy: 'newest', // 'newest'|'oldest',
|
||||||
|
showDivider: true, // true|false
|
||||||
|
divider: {
|
||||||
|
styles: {
|
||||||
|
block: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
padding: '13px',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderWidth: '3px',
|
||||||
|
borderColor: '#aaaaaa',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
backgroundColorAlternate: '#eeeeee',
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
text: '<%= __('Button') %>',
|
||||||
|
url: 'http://example.org',
|
||||||
|
styles: {
|
||||||
|
block: {
|
||||||
|
backgroundColor: '#2ea1cd',
|
||||||
|
borderColor: '#0074a2',
|
||||||
|
borderWidth: '1px',
|
||||||
|
borderRadius: '7px',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
width: '120px',
|
||||||
|
lineHeight: '35px',
|
||||||
|
fontColor: '#ffffff',
|
||||||
|
fontFamily: 'Verdana',
|
||||||
|
fontSize: '18px',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
styles: {
|
||||||
|
block: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
divider: {
|
||||||
|
styles: {
|
||||||
|
block: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
padding: '13px',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderWidth: '3px',
|
||||||
|
borderColor: '#aaaaaa',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
footer: {
|
||||||
|
text: '<a href="[unsubscribeUrl]"><%= __('Unsubscribe') %></a> | <a href="[manageSubscriptionUrl]"><%= __('Manage subscription') %></a><br /><b><%= __('Add your postal address here!') %></b>',
|
||||||
|
styles: {
|
||||||
|
block: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
fontColor: '#222222',
|
||||||
|
fontFamily: 'Arial',
|
||||||
|
fontSize: '12px',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
fontColor: '#6cb7d4',
|
||||||
|
textDecoration: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
link: 'http://example.org',
|
||||||
|
src: '<%= 'assets/img/newsletter_editor/pigeon.png' %>',
|
||||||
|
alt: '<%= __('An image of...') %>',
|
||||||
|
padded: true,
|
||||||
|
width: '281px',
|
||||||
|
height: '190px',
|
||||||
|
styles: {
|
||||||
|
block: {
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
posts: {
|
||||||
|
amount: '10',
|
||||||
|
contentType: 'post', // 'post'|'page'|'mailpoet_page'
|
||||||
|
postStatus: 'publish', // 'draft'|'pending'|'private'|'publish'|'future'
|
||||||
|
inclusionType: 'include', // 'include'|'exclude'
|
||||||
|
displayType: 'excerpt', // 'excerpt'|'full'|'titleOnly'
|
||||||
|
titleFormat: 'h1', // 'h1'|'h2'|'h3'|'ul'
|
||||||
|
titlePosition: 'inTextBlock', // 'inTextBlock'|'aboveBlock',
|
||||||
|
titleAlignment: 'left', // 'left'|'center'|'right'
|
||||||
|
titleIsLink: false, // false|true
|
||||||
|
imagePadded: true, // true|false
|
||||||
|
showAuthor: 'no', // 'no'|'aboveText'|'belowText'
|
||||||
|
authorPrecededBy: '<%= __('Author:') %>',
|
||||||
|
showCategories: 'no', // 'no'|'aboveText'|'belowText'
|
||||||
|
categoriesPrecededBy: '<%= __('Categories:') %>',
|
||||||
|
readMoreType: 'link', // 'link'|'button'
|
||||||
|
readMoreText: 'Read more', // 'link'|'button'
|
||||||
|
readMoreButton: {
|
||||||
|
text: '<%= __('Read more') %>',
|
||||||
|
url: '[postLink]',
|
||||||
|
styles: {
|
||||||
|
block: {
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
borderColor: '#000000',
|
||||||
|
borderWidth: '1px',
|
||||||
|
borderRadius: '5px',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
width: '120px',
|
||||||
|
lineHeight: '30px',
|
||||||
|
fontColor: '#000000',
|
||||||
|
fontFamily: 'Arial',
|
||||||
|
fontSize: '20px',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sortBy: 'newest', // 'newest'|'oldest',
|
||||||
|
showDivider: true, // true|false
|
||||||
|
divider: {
|
||||||
|
styles: {
|
||||||
|
block: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
padding: '13px',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderWidth: '3px',
|
||||||
|
borderColor: '#aaaaaa',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
backgroundColorAlternate: '#eeeeee',
|
||||||
|
},
|
||||||
|
social: {
|
||||||
|
iconSet: 'default',
|
||||||
|
icons: [
|
||||||
|
{
|
||||||
|
type: 'socialIcon',
|
||||||
|
iconType: 'facebook',
|
||||||
|
link: 'http://example.com',
|
||||||
|
image: '<%= 'assets/img/newsletter_editor/social-icons/01-social/Facebook.png' %>',
|
||||||
|
height: '32px',
|
||||||
|
width: '32px',
|
||||||
|
text: '<%= __('Facebook') %>',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'socialIcon',
|
||||||
|
iconType: 'twitter',
|
||||||
|
link: 'http://example.com',
|
||||||
|
image: '<%= 'assets/img/newsletter_editor/social-icons/01-social/Twitter.png' %>',
|
||||||
|
height: '32px',
|
||||||
|
width: '32px',
|
||||||
|
text: '<%= __('Twitter') %>',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
spacer: {
|
||||||
|
styles: {
|
||||||
|
block: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
height: '40px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
text: '<%= __('Edit this to insert text') %>',
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
text: '<%= __('Display problems?') %> <a href="[viewInBrowserUrl]"><%= __('View it in your browser') %></a>',
|
||||||
|
styles: {
|
||||||
|
block: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
fontColor: '#222222',
|
||||||
|
fontFamily: 'Arial',
|
||||||
|
fontSize: '12px',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
fontColor: '#6cb7d4',
|
||||||
|
textDecoration: 'underline',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
customFields: {
|
||||||
|
'<%= __('Subscriber') %>': [
|
||||||
|
{
|
||||||
|
text: '<%= __('First Name') %>',
|
||||||
|
shortcode: 'user:firstname | default:reader',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '<%= __('Last Name') %>',
|
||||||
|
shortcode: 'user:lastname | default:reader',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '<%= __('Email Address') %>',
|
||||||
|
shortcode: 'user:email',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '<%= __('Wordpress user display name') %>',
|
||||||
|
shortcode: 'user:displayname | default:member',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '<%= __('Total of subscribers') %>',
|
||||||
|
shortcode: 'user:count',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'<%= __('Newsletter') %>': [
|
||||||
|
{
|
||||||
|
text: '<%= __('Newsletter Subject') %>',
|
||||||
|
shortcode: 'newsletter:subject',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'<%= __('Post Notifications') %>': [
|
||||||
|
{
|
||||||
|
text: '<%= __('Total number of posts or pages') %>',
|
||||||
|
shortcode: 'newsletter:total',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '<%= __('Latest post title') %>',
|
||||||
|
shortcode: 'newsletter:post_title',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '<%= __('Issue number') %>',
|
||||||
|
shortcode: 'newsletter:number',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'<%= __('Date') %>': [
|
||||||
|
{
|
||||||
|
text: '<%= __('Current day of the month number') %>',
|
||||||
|
shortcode: 'date:d',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '<%= __('Current day of the month in ordinal, ie. 2nd, 3rd, etc.') %>',
|
||||||
|
shortcode: 'date:dordinal',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '<%= __('Full name of current day') %>',
|
||||||
|
shortcode: 'date:dtext',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '<%= __('Current month number') %>',
|
||||||
|
shortcode: 'date:m',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '<%= __('Full name of current month') %>',
|
||||||
|
shortcode: 'date:mtext',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '<%= __('Year') %>',
|
||||||
|
shortcode: 'date:y',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'<%= __('Links') %>': [
|
||||||
|
{
|
||||||
|
text: '<%= __('Unsubscribe link') %>',
|
||||||
|
shortcode: 'global:unsubscribe',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '<%= __('Edit subscription page link') %>',
|
||||||
|
shortcode: 'global:manage',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '<%= __('View in browser link') %>',
|
||||||
|
shortcode: 'global:browser',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'<%= __('Custom fields') %>': [
|
||||||
|
{
|
||||||
|
text: '<%= __('Temporary sample custom field') %>',
|
||||||
|
shortcode: 'custom:samplefield',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
translations: {
|
||||||
|
customFieldsWindowTitle: '<%= __('Select a shortcode') %>',
|
||||||
|
unsubscribeLinkMissing: '<%= __('Please include an unsubscribe link to continue.') %>',
|
||||||
|
|
||||||
|
testEmailSent: '<%= __('Test email succesfully sent!') %>',
|
||||||
|
unknownErrorOccurred: '<%= __('An unknown error occurred, please check your settings.') %>',
|
||||||
|
},
|
||||||
|
sidepanelWidth: '331px',
|
||||||
|
validation: {
|
||||||
|
validateUnsubscribeLinkPresent: true, // TODO: Add validation based on whether Mailpoet MTA is used or not
|
||||||
|
},
|
||||||
|
urls: {
|
||||||
|
termSearch: ajaxurl + '?action=mailpoet_ajax&mailpoet_file=search_terms.php',
|
||||||
|
send: '?page=mailpoet-newsletters&action=send&newsletter=1', // TODO: Add saving path based on newsletter id
|
||||||
|
imageMissing: '<%= 'assets/img/newsletter_editor/image-missing.svg' %>',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// start editor
|
||||||
|
var editor = EditorApplication.start({
|
||||||
|
newsletter: newsletter,
|
||||||
|
config: config,
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
<% endblock %>
|
<% endblock %>
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
<div class="mailpoet_container_empty">{{#if isRoot}}<?php _e('Drop layout here'); ?>{{else}}<?php _e('Drop content here'); ?>{{/if}}</div>
|
<div class="mailpoet_container_empty">{{#if isRoot}}<%= __('Drop layout here') %>{{else}}<%= __('Drop content here') %>{{/if}}</div>
|
||||||
{{debug}}
|
{{debug}}
|
||||||
|
@ -17,7 +17,11 @@ baseConfig = {
|
|||||||
],
|
],
|
||||||
alias: {
|
alias: {
|
||||||
'handlebars': 'handlebars/dist/handlebars.js',
|
'handlebars': 'handlebars/dist/handlebars.js',
|
||||||
},
|
'backbone.marionette': 'backbone.marionette/lib/backbone.marionette',
|
||||||
|
'sticky-kit': 'sticky-kit/jquery.sticky-kit',
|
||||||
|
//'tinymce': 'tinymce/tinymce.jquery',
|
||||||
|
//'jquery.tinymce': 'tinymce/jquery.tinymce.min.js',
|
||||||
|
}
|
||||||
},
|
},
|
||||||
node: {
|
node: {
|
||||||
fs: 'empty'
|
fs: 'empty'
|
||||||
@ -45,7 +49,54 @@ config.push(_.extend({}, baseConfig, {
|
|||||||
'newsletters/newsletters.jsx',
|
'newsletters/newsletters.jsx',
|
||||||
'newsletters/list.jsx',
|
'newsletters/list.jsx',
|
||||||
'newsletters/form.jsx'
|
'newsletters/form.jsx'
|
||||||
]
|
],
|
||||||
|
newsletter_editor: [
|
||||||
|
'underscore',
|
||||||
|
'backbone',
|
||||||
|
'backbone.marionette',
|
||||||
|
'backbone.supermodel/build/backbone.supermodel.amd',
|
||||||
|
'interact.js',
|
||||||
|
'backbone.radio',
|
||||||
|
//'moment-with-locales',
|
||||||
|
'tinymce/tinymce.jquery.js',
|
||||||
|
'tinymce/jquery.tinymce.min.js',
|
||||||
|
//'tinymce',
|
||||||
|
//'jquery.tinymce',
|
||||||
|
'select2',
|
||||||
|
'spectrum-colorpicker',
|
||||||
|
'sticky-kit',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//'newsletter_editor/tinymce/wplink.js',
|
||||||
|
//'newsletter_editor/tinymce/mailpoet_custom_fields/plugin.js',
|
||||||
|
'newsletter_editor/communicationsFix.js',
|
||||||
|
'newsletter_editor/App',
|
||||||
|
'newsletter_editor/components/config.js',
|
||||||
|
'newsletter_editor/components/styles.js',
|
||||||
|
'newsletter_editor/components/sidebar.js',
|
||||||
|
'newsletter_editor/components/content.js',
|
||||||
|
'newsletter_editor/components/heading.js',
|
||||||
|
'newsletter_editor/components/save.js',
|
||||||
|
'newsletter_editor/behaviors/BehaviorsLookup.js',
|
||||||
|
'newsletter_editor/behaviors/ColorPickerBehavior.js',
|
||||||
|
'newsletter_editor/behaviors/ContainerDropZoneBehavior.js',
|
||||||
|
'newsletter_editor/behaviors/DraggableBehavior.js',
|
||||||
|
'newsletter_editor/behaviors/ResizableBehavior.js',
|
||||||
|
'newsletter_editor/behaviors/SortableBehavior.js',
|
||||||
|
'newsletter_editor/blocks/base.js',
|
||||||
|
'newsletter_editor/blocks/container.js',
|
||||||
|
'newsletter_editor/blocks/button.js',
|
||||||
|
'newsletter_editor/blocks/image.js',
|
||||||
|
'newsletter_editor/blocks/divider.js',
|
||||||
|
'newsletter_editor/blocks/text.js',
|
||||||
|
'newsletter_editor/blocks/spacer.js',
|
||||||
|
'newsletter_editor/blocks/footer.js',
|
||||||
|
'newsletter_editor/blocks/header.js',
|
||||||
|
'newsletter_editor/blocks/automatedLatestContent.js',
|
||||||
|
'newsletter_editor/blocks/posts.js',
|
||||||
|
'newsletter_editor/blocks/social.js',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js'),
|
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js'),
|
||||||
|
Reference in New Issue
Block a user