diff --git a/assets/js/src/form_editor/form_editor.js b/assets/js/src/form_editor/form_editor.js
index 98fec58922..687d5a34df 100644
--- a/assets/js/src/form_editor/form_editor.js
+++ b/assets/js/src/form_editor/form_editor.js
@@ -1,1069 +1,1069 @@
-/*
- * name: MailPoet Form Editor
- * author: Jonathan Labreuille
- * company: Wysija
- * framework: prototype 1.7.2
- */
-'use strict';
-
-Event.cacheDelegated = {};
-Object.extend(document, (function() {
- var cache = Event.cacheDelegated;
-
- function getCacheForSelector(selector) {
- cache[selector] = cache[selector] || {};
- return cache[selector];
- }
-
- function getWrappersForSelector(selector, eventName) {
- var c = getCacheForSelector(selector);
- c[eventName] = c[eventName] || [];
- return c[eventName];
- }
-
- function findWrapper(selector, eventName, handler) {
- var c = getWrappersForSelector(selector, eventName);
- return c.find(function(wrapper) {
- return wrapper.handler === handler
- });
- }
-
- function destroyWrapper(selector, eventName, handler) {
- var c = getCacheForSelector(selector);
- if(!c[eventName]) return false;
- var wrapper = findWrapper(selector, eventName, handler)
- c[eventName] = c[eventName].without(wrapper);
- return wrapper;
- }
-
- function createWrapper(selector, eventName, handler, context) {
- var wrapper, c = getWrappersForSelector(selector, eventName);
- if(c.pluck('handler').include(handler)) return false;
- wrapper = function(event) {
- var element = event.findElement(selector);
- if(element) handler.call(context || element, event, element);
- };
- wrapper.handler = handler;
- c.push(wrapper);
- return wrapper;
- }
- return {
- delegate: function(selector, eventName, handler, context) {
- var wrapper = createWrapper.apply(null, arguments);
- if(wrapper) document.observe(eventName, wrapper);
- return document;
- },
- stopDelegating: function(selector, eventName, handler) {
- var length = arguments.length;
- switch(length) {
- case 2:
- getWrappersForSelector(selector, eventName).each(function(wrapper) {
- document.stopDelegating(selector, eventName, wrapper.handler);
- });
- break;
- case 1:
- Object.keys(getCacheForSelector(selector)).each(function(eventName) {
- document.stopDelegating(selector, eventName);
- });
- break;
- case 0:
- Object.keys(cache).each(function(selector) {
- document.stopDelegating(selector);
- });
- break;
- default:
- var wrapper = destroyWrapper.apply(null, arguments);
- if(wrapper) document.stopObserving(eventName, wrapper);
- }
- return document;
- }
- }
-})());
-
-var Observable = (function() {
- function getEventName(nameA, namespace) {
- var name = nameA.substring(2);
- if(namespace) name = namespace + ':' + name;
- return name.underscore().split('_').join(':');
- }
-
- function getHandlers(klass) {
- var proto = klass.prototype,
- namespace = proto.namespace;
- return Object.keys(proto).grep(/^on/).inject($H(), function(handlers, name) {
- if(name === 'onDomLoaded') return handlers;
- handlers.set(getEventName(name, namespace), getWrapper(proto[name], klass));
- return handlers;
- });
- }
-
- function getWrapper(handler, klass) {
- return function(event) {
- return handler.call(new klass(this), event, event.memo);
- }
- }
-
- function onDomLoad(selector, klass) {
- $$(selector).each(function(element) {
- new klass(element).onDomLoaded();
- });
- }
- return {
- observe: function(selector) {
- if(!this.handlers) this.handlers = {};
- if(this.handlers[selector]) return;
- var klass = this;
- if(this.prototype.onDomLoaded) document.loaded ? onDomLoad(selector, klass) : document.observe('dom:loaded', onDomLoad.curry(selector, klass));
- this.handlers[selector] = getHandlers(klass).each(function(handler) {
- document.delegate(selector, handler.key, handler.value);
- });
- },
- stopObserving: function(selector) {
- if(!this.handlers || !this.handlers[selector]) return;
- this.handlers[selector].each(function(handler) {
- document.stopDelegating(selector, handler.key, handler.value);
- });
- delete this.handlers[selector];
- }
- }
-})();
-
-// override droppables
-Object.extend(Droppables, {
- deactivate: Droppables.deactivate.wrap(function(proceed, drop, draggable) {
- if(drop.onLeave) drop.onLeave(draggable, drop.element);
- return proceed(drop);
- }),
- activate: Droppables.activate.wrap(function(proceed, drop, draggable) {
- if(drop.onEnter) drop.onEnter(draggable, drop.element);
- return proceed(drop);
- }),
- show: function(point, element) {
- if(!this.drops.length) return;
- var drop, affected = [];
- this.drops.each(function(drop) {
- if(Droppables.isAffected(point, element, drop)) affected.push(drop);
- });
- if(affected.length > 0) drop = Droppables.findDeepestChild(affected);
- if(this.last_active && this.last_active !== drop) this.deactivate(this.last_active, element);
- if(drop) {
- Position.within(drop.element, point[0], point[1]);
- if(drop.onHover) drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
- if(drop !== this.last_active) Droppables.activate(drop, element);
- }
- },
- displayArea: function(draggable) {
- if(!this.drops.length) return;
-
- // hide controls when displaying drop areas.
- WysijaForm.hideBlockControls();
-
- this.drops.each(function(drop, iterator) {
- if(drop.element.hasClassName('block_placeholder')) {
- drop.element.addClassName('active');
- }
- });
- },
- hideArea: function() {
- if(!this.drops.length) return;
- this.drops.each(function(drop, iterator) {
- if(drop.element.hasClassName('block_placeholder')) {
- drop.element.removeClassName('active');
- } else if(drop.element.hasClassName('image_placeholder')) {
- drop.element.removeClassName('active');
- drop.element.up().removeClassName('active');
- } else if(drop.element.hasClassName('text_placeholder')) {
- drop.element.removeClassName('active');
- }
- });
- },
- reset: function(draggable) {
- if(this.last_active) this.deactivate(this.last_active, draggable);
- }
-});
-
-/*
- Wysija History handling
- POTENTIAL FEATURES:
- - set a maximum number of items to be stored
-
-*/
-var WysijaHistory = {
- container: 'mailpoet_form_history',
- size: 30,
- enqueue: function(element) {
- // create deep clone (includes child elements) of passed element
- var clone = element.clone(true);
-
- // check if the field is unique
- if(parseInt(clone.readAttribute('wysija_unique'), 10) === 1) {
- // check if the field is already in the queue
- $(WysijaHistory.container).select('[wysija_name="' + clone.readAttribute('wysija_name') + '"]').invoke('remove');
- }
-
- // check history size
- if($(WysijaHistory.container).select('> div').length >= WysijaHistory.size) {
- // remove oldest element (last in the list)
- $(WysijaHistory.container).select('> div').last().remove();
- }
-
- // store block in history
- $(WysijaHistory.container).insert({
- top: clone
- });
- },
- dequeue: function() {
- // pop last block off the history
- var block = $(WysijaHistory.container).select('div').first();
-
- if(block !== undefined) {
- // insert block back into the editor
- $(WysijaForm.options.body).insert({
- top: block
- });
- }
- },
- clear: function() {
- $(WysijaHistory.container).innerHTML = '';
- },
- remove: function(field) {
- $(WysijaHistory.container).select('[wysija_name="' + field + '"]').invoke('remove');
- }
-};
-
-/* MailPoet Form */
-var WysijaForm = {
- version: '0.7',
- options: {
- container: 'mailpoet_form_container',
- editor: 'mailpoet_form_editor',
- body: 'mailpoet_form_body',
- toolbar: 'mailpoet_form_toolbar',
- templates: 'wysija_widget_templates',
- debug: false
- },
- toolbar: {
- effect: null,
- x: null,
- y: null,
- top: null,
- left: null
- },
- scroll: {
- top: 0,
- left: 0
- },
- flags: {
- doSave: false
- },
- locks: {
- dragging: false,
- selectingColor: false,
- showingTools: false
- },
- encodeHtmlValue: function(str) {
- return str.replace(/&/g, '&').replace(/>/g, '>').replace(/').replace(/</g, '<').replace(/"/g, '"');
- // ": fix for FileMerge because the previous line fucks up its syntax coloring
- },
- loading: function(is_loading) {
- if(is_loading) {
- $(WysijaForm.options.editor).addClassName('loading');
- $(WysijaForm.options.toolbar).addClassName('loading');
- } else {
- $(WysijaForm.options.editor).removeClassName('loading');
- $(WysijaForm.options.toolbar).removeClassName('loading');
- }
- },
- loadStatic: function(blocks) {
- $A(blocks).each(function(block) {
- // create block
- WysijaForm.Block.create(block, $('block_placeholder'));
- });
- },
- load: function(data) {
- if(data === undefined) return;
-
- // load body
- if(data.body !== undefined) {
- $A(data.body).each(function(block) {
- // create block
- WysijaForm.Block.create(block, $('block_placeholder'));
- });
-
- // load settings
- var settings_elements = $('mailpoet_form_settings').getElements();
- settings_elements.each(function(setting) {
- // skip lists
- if(setting.name === 'segments') {
- return true;
- } else if(setting.name === 'on_success') {
- // if the input value is equal to the one stored in the settings
- if(setting.value === data.settings[setting.name]) {
- // check selected value
- $(setting).checked = true;
- }
- } else if(data.settings[setting.name] !== undefined) {
- if(typeof data.settings[setting.name] === 'string') {
- setting.setValue(WysijaForm.decodeHtmlValue(data.settings[setting.name]));
- } else {
- setting.setValue(data.settings[setting.name]);
- }
- }
- });
- }
- },
- save: function() {
- var position = 1,
- data = {
- name: $F('mailpoet_form_name'),
- settings: $('mailpoet_form_settings').serialize(true),
- body: [],
- styles: (MailPoet.CodeEditor !== undefined) ? MailPoet.CodeEditor.getValue() : null
- };
- // body
- WysijaForm.getBlocks().each(function(b) {
- var block_data = (typeof(b.block['save']) === 'function') ? b.block.save() : null;
-
- if(block_data !== null) {
- // set block position
- block_data['position'] = position;
-
- // increment position
- position++;
-
- // add block data to body
- data['body'].push(block_data);
- }
- });
-
- return data;
- },
- init: function() {
- // set document scroll
- info('init -> set scroll offsets');
- WysijaForm.setScrollOffsets();
-
- // position toolbar
- info('init -> set toolbar position');
- WysijaForm.setToolbarPosition();
-
- // enable droppable targets
- info('init -> make droppable');
- WysijaForm.makeDroppable();
-
- // enable sortable
- info('init -> make sortable');
- WysijaForm.makeSortable();
-
- // hide controls
- info('init -> hide controls');
- WysijaForm.hideControls();
-
- // hide settings
- info('init -> hide settings');
- WysijaForm.hideSettings();
-
- // set settings buttons position
- info('init -> init settings');
- WysijaForm.setSettingsPosition();
-
- // toggle widgets
- info('init -> toggle widgets');
- WysijaForm.toggleWidgets();
- },
- getFieldData: function(element) {
- // get basic field data
- var data = {
- type: element.readAttribute('wysija_type'),
- name: element.readAttribute('wysija_name'),
- id: element.readAttribute('wysija_id'),
- unique: parseInt(element.readAttribute('wysija_unique') || 0, 10),
- static: parseInt(element.readAttribute('wysija_static') || 0, 10),
- element: element,
- params: ''
- };
-
- // get params (may be empty)
- if(element.readAttribute('wysija_params') !== null && element.readAttribute('wysija_params').length > 0) {
- data.params = JSON.parse(element.readAttribute('wysija_params'));
- }
- return data;
- },
- toggleWidgets: function() {
- $$('a[wysija_unique="1"]').invoke('removeClassName', 'disabled');
-
- // loop through each unique field already inserted in the editor and disable its toolbar equivalent
- $$('#' + WysijaForm.options.editor + ' [wysija_unique="1"]').map(function(element) {
- var field = $$('#' + WysijaForm.options.toolbar + ' [wysija_id="' + element.readAttribute('wysija_id') + '"]');
- if(field.length > 0) {
- field.first().addClassName('disabled');
- }
- });
-
- var hasSegmentSelection = WysijaForm.hasSegmentSelection();
-
- if(hasSegmentSelection) {
- $('mailpoet_form_segments').writeAttribute('required', false).disable();
- $('mailpoet_settings_segment_selection').hide();
- } else {
- $('mailpoet_form_segments').writeAttribute('required', true).enable();
- $('mailpoet_settings_segment_selection').show();
- }
- },
- hasSegmentSelection: function() {
- return ($$('#' + WysijaForm.options.editor + ' [wysija_id="segments"]').length > 0);
- },
- isSegmentSelectionValid: function() {
- var segment_selection = $$('#' + WysijaForm.options.editor + ' [wysija_id="segments"]')[0];
- if(segment_selection !== undefined) {
- var block = WysijaForm.get(segment_selection).block.getData();
- return (
- (block.params.values !== undefined)
- &&
- (block.params.values.length > 0)
- );
- }
- return false;
- },
- setBlockPositions: function(event, target) {
- // release dragging lock
- WysijaForm.locks.dragging = false;
-
- var index = 1;
- WysijaForm.getBlocks().each(function(container) {
- container.setPosition(index++);
- // remove z-index value to avoid issues when resizing images
- if(container['block'] !== undefined) {
- container.block.element.setStyle({
- zIndex: ''
- });
- }
- });
-
- if(target !== undefined) {
- // get placeholders (previous placeholder matches the placeholder linked to the next block)
- var block_placeholder = $(target.element.readAttribute('wysija_placeholder')),
- previous_placeholder = target.element.previous('.block_placeholder');
-
- if(block_placeholder !== null) {
- // put block placeholder before the current block
- target.element.insert({
- before: block_placeholder
- });
-
- // if the next block is a wysija_block, insert previous placeholder
- if(target.element.next() !== undefined && target.element.next().hasClassName('mailpoet_form_block') && previous_placeholder !== undefined) {
- target.element.insert({
- after: previous_placeholder
- });
- }
- }
- }
- },
- setScrollOffsets: function() {
- WysijaForm.scroll = document.viewport.getScrollOffsets();
- },
- hideSettings: function() {
- $(WysijaForm.options.container).select('.wysija_settings').invoke('hide');
- },
- setSettingsPosition: function() {
- // get viewport offsets and dimensions
- var viewportHeight = document.viewport.getHeight(),
- blockPadding = 5;
-
- $(WysijaForm.options.container).select('.wysija_settings').each(function(element) {
- // get parent dimensions and position
- var parentDim = element.up('.mailpoet_form_block').getDimensions(),
- parentPos = element.up('.mailpoet_form_block').cumulativeOffset(),
- is_visible = (parentPos.top <= (WysijaForm.scroll.top + viewportHeight)) ? true : false,
- buttonMargin = 5,
- relativeTop = buttonMargin;
-
- if(is_visible) {
- // desired position is set to center of viewport
- var absoluteTop = parseInt(WysijaForm.scroll.top + ((viewportHeight / 2) - (element.getHeight() / 2)), 10),
- parentTop = parseInt(parentPos.top - blockPadding, 10),
- parentBottom = parseInt(parentPos.top + parentDim.height - blockPadding, 10);
-
- // always center
- relativeTop = parseInt((parentDim.height / 2) - (element.getHeight() / 2), 10);
- }
- // set position for button
- $(element).setStyle({
- left: parseInt((parentDim.width / 2) - (element.getWidth() / 2)) + 'px',
- top: relativeTop + 'px'
- });
- });
- },
- initToolbarPosition: function() {
- if(WysijaForm.toolbar.top === null) WysijaForm.toolbar.top = parseInt($(WysijaForm.options.container).positionedOffset().top);
- if(WysijaForm.toolbar.y === null) WysijaForm.toolbar.y = parseInt(WysijaForm.toolbar.top);
-
- if(isRtl) {
- if(WysijaForm.toolbar.left === null) WysijaForm.toolbar.left = 0;
- } else {
- if(WysijaForm.toolbar.left === null) WysijaForm.toolbar.left = parseInt($(WysijaForm.options.container).positionedOffset().left);
- }
- if(WysijaForm.toolbar.x === null) WysijaForm.toolbar.x = parseInt(WysijaForm.toolbar.left + $(WysijaForm.options.container).getDimensions().width + 15);
-
- },
- setToolbarPosition: function() {
- WysijaForm.initToolbarPosition();
-
- var position = {
- top: WysijaForm.toolbar.y + 'px',
- visibility: 'visible'
- };
-
- if(isRtl) {
- position.right = WysijaForm.toolbar.x + 'px';
- } else {
- position.left = WysijaForm.toolbar.x + 'px';
- }
-
- $(WysijaForm.options.toolbar).setStyle(position);
- },
- updateToolbarPosition: function() {
- // init toolbar position (updates scroll and toolbar y)
- WysijaForm.initToolbarPosition();
-
- // cancel previous effect
- if(WysijaForm.toolbar.effect !== null) WysijaForm.toolbar.effect.cancel();
-
- if(WysijaForm.scroll.top >= (WysijaForm.toolbar.top - 20)) {
- WysijaForm.toolbar.y = parseInt(20 + WysijaForm.scroll.top);
- // start effect
- WysijaForm.toolbar.effect = new Effect.Move(WysijaForm.options.toolbar, {
- x: WysijaForm.toolbar.x,
- y: WysijaForm.toolbar.y,
- mode: 'absolute',
- duration: 0.2
- });
- } else {
- $(WysijaForm.options.toolbar).setStyle({
- left: WysijaForm.toolbar.x + 'px',
- top: WysijaForm.toolbar.top + 'px'
- });
- }
- },
- blockDropOptions: {
- accept: $w('mailpoet_form_field'), // acceptable items (classes array)
- onEnter: function(draggable, droppable) {
- $(droppable).addClassName('hover');
- },
- onLeave: function(draggable, droppable) {
- $(droppable).removeClassName('hover');
- },
- onDrop: function(draggable, droppable) {
- // custom data for images
- droppable.fire('wjfe:item:drop', WysijaForm.getFieldData(draggable));
- $(droppable).removeClassName('hover');
- }
- },
- hideControls: function() {
- try {
- return WysijaForm.getBlocks().invoke('hideControls');
- } catch(e) {
- return;
- }
- },
- hideTools: function() {
- $$('.wysija_tools').invoke('hide');
- WysijaForm.locks.showingTools = false;
- },
- instances: {},
- get: function(element, typ) {
- var type = typ;
- if(type === undefined) type = 'block';
- // identify element
- var id = element.identify();
- var instance = WysijaForm.instances[id] || new WysijaForm[type.capitalize().camelize()](id);
-
- WysijaForm.instances[id] = instance;
- return instance;
- },
- makeDroppable: function() {
- Droppables.add('block_placeholder', WysijaForm.blockDropOptions);
- },
- makeSortable: function() {
- var body = $(WysijaForm.options.body);
- Sortable.create(body, {
- tag: 'div',
- only: 'mailpoet_form_block',
- scroll: window,
- handle: 'handle',
- constraint: 'vertical'
-
- });
- Draggables.removeObserver(body);
- Draggables.addObserver({
- element: body,
- onStart: WysijaForm.startBlockPositions,
- onEnd: WysijaForm.setBlockPositions
- });
- },
- hideBlockControls: function() {
- $$('.wysija_controls').invoke('hide');
- this.getBlockElements().invoke('removeClassName', 'hover');
- },
- getBlocks: function() {
- return WysijaForm.getBlockElements().map(function(element) {
- return WysijaForm.get(element);
- });
- },
- getBlockElements: function() {
- return $(WysijaForm.options.container).select('.mailpoet_form_block');
- },
- startBlockPositions: function(event, target) {
- if(target.element.hasClassName('mailpoet_form_block')) {
- // store block placeholder id for the block that is being repositionned
- if(target.element.previous('.block_placeholder') !== undefined) {
- target.element.writeAttribute('wysija_placeholder', target.element.previous('.block_placeholder').identify());
- }
- }
- WysijaForm.locks.dragging = true;
- },
- encodeURIComponent: function(str) {
- // check if it's a url and if so, prevent encoding of protocol
- var regexp = new RegExp(/^http[s]?:\/\//),
- protocol = regexp.exec(str);
-
- if(protocol === null) {
- // this is not a url so encode the whole thing
- return encodeURIComponent(str).replace(/[!'()*]/g, escape);
- } else if(protocol.length === 1) {
- // this is a url, so do not encode the protocol
- return encodeURI(str).replace(/[!'()*]/g, escape);
- }
- },
- updateBlock: function(field) {
- var hasUpdated = false;
- WysijaForm.getBlocks().each(function(b) {
- if(b.block.getData().id === field.id) {
- hasUpdated = true;
- b.block.redraw(field);
- }
- });
-
- return hasUpdated;
- },
- removeBlock: function(field, callback) {
- var hasRemoved = false;
- WysijaForm.getBlocks().each(function(b) {
- if(b.block.getData().id === field.id) {
- hasRemoved = true;
- b.block.removeBlock(callback);
- }
- });
-
- return hasRemoved;
- }
-};
-
-WysijaForm.DraggableItem = Class.create({
- initialize: function(element) {
- this.elementType = $(element).readAttribute('wysija_type');
- this.element = $(element).down() || $(element);
- this.clone = this.cloneElement();
- this.insert();
- },
- STYLES: new Template('position: absolute; top: #{top}px; left: #{left}px;'),
- cloneElement: function() {
- var clone = this.element.clone(),
- offset = this.element.cumulativeOffset(),
- list = this.getList(),
- styles = this.STYLES.evaluate({
- top: offset.top - list.scrollTop,
- left: offset.left - list.scrollLeft
- });
- clone.setStyle(styles);
-
- clone.addClassName('mailpoet_form_widget');
- clone.addClassName(this.elementType);
- clone.innerHTML = this.element.innerHTML;
- return clone;
- },
- getOffset: function() {
- return this.element.offsetTop - this.getList().scrollTop;
- },
- getList: function() {
- return this.element.up('ul');
- },
- insert: function() {
- $$('body')[0].insert(this.clone);
- },
- onMousedown: function(event) {
- var draggable = new Draggable(this.clone, {
- scroll: window,
- onStart: function() {
- Droppables.displayArea(draggable);
- },
- onEnd: function(drag) {
- drag.destroy();
- drag.element.remove();
- Droppables.hideArea();
- },
- starteffect: function(element) {
- new Effect.Opacity(element, {
- duration: 0.2,
- from: element.getOpacity(),
- to: 0.7
- });
- },
- endeffect: Prototype.emptyFunction
- });
- draggable.initDrag(event);
- draggable.startDrag(event);
- return draggable;
- }
-});
-Object.extend(WysijaForm.DraggableItem, Observable).observe('a[class="mailpoet_form_field"]');
-
-
-WysijaForm.Block = Class.create({
- /* Invoked on load */
- initialize: function(element) {
- info('block -> init');
-
- this.element = $(element);
- this.block = new WysijaForm.Widget(this.element);
-
- // enable block placeholder
- this.block.makeBlockDroppable();
-
- // setup events
- if(this.block['setup'] !== undefined) {
- this.block.setup();
- }
- return this;
- },
- setPosition: function(position) {
- this.element.writeAttribute('wysija_position', position);
- },
- hideControls: function() {
- if(this['getControls']) {
- this.element.removeClassName('hover');
- this.getControls().hide();
- }
- },
- showControls: function() {
- if(this['getControls']) {
- this.element.addClassName('hover');
- try {
- this.getControls().show();
- } catch(e) {;
- }
- }
- },
- makeBlockDroppable: function() {
- if(this.isBlockDroppableEnabled() === false) {
- var block_placeholder = this.getBlockDroppable();
- Droppables.add(block_placeholder.identify(), WysijaForm.blockDropOptions);
- block_placeholder.addClassName('enabled');
- }
- },
- removeBlockDroppable: function() {
- if(this.isBlockDroppableEnabled()) {
- var block_placeholder = this.getBlockDroppable();
- Droppables.remove(block_placeholder.identify());
- block_placeholder.removeClassName('enabled');
- }
- },
- isBlockDroppableEnabled: function() {
- // if the block_placeholder does not exist, create it
- var block_placeholder = this.getBlockDroppable();
- if(block_placeholder === null) {
- return this.createBlockDroppable().hasClassName('enabled');
- } else {
- return block_placeholder.hasClassName('enabled');
- }
- },
- createBlockDroppable: function() {
- info('block -> createBlockDroppable');
- this.element.insert({
- before: '
' + $('block_placeholder').innerHTML + '
'
- });
- return this.element.previous('.block_placeholder');
- },
- getBlockDroppable: function() {
- if(this.element.previous() === undefined || this.element.previous().hasClassName('block_placeholder') === false) {
- return null;
- } else {
- return this.element.previous();
- }
- },
- getControls: function() {
- return this.element.down('.wysija_controls');
- },
- setupControls: function() {
- // enable controls
- this.controls = this.getControls();
-
- if(this.controls) {
- // setup events for block controls
- this.element.observe('mouseover', function() {
- // special cases where controls shouldn't be displayed
- if(WysijaForm.locks.dragging === true || WysijaForm.locks.selectingColor === true || WysijaForm.locks.showingTools === true) return;
-
- // set block flag
- this.element.addClassName('hover');
-
- // show controls
- this.showControls();
-
- // show settings if present
- if(this.element.down('.wysija_settings') !== undefined) {
- this.element.down('.wysija_settings').show();
- }
- }.bind(this));
-
- this.element.observe('mouseout', function() {
- // special cases where controls shouldn't hide
- if(WysijaForm.locks.dragging === true || WysijaForm.locks.selectingColor === true) return;
-
- // hide controls
- this.hideControls();
-
- // hide settings if present
- if(this.element.down('.wysija_settings') !== undefined) {
- this.element.down('.wysija_settings').hide();
- }
- }.bind(this));
-
-
- // setup click event for remove button
- this.removeButton = this.controls.down('.remove') || null;
- if(this.removeButton !== null) {
- this.removeButton.observe('click', function() {
- this.removeBlock();
- this.removeButton.stopObserving('click');
- }.bind(this));
- }
-
- // setup click event for settings button
- this.settingsButton = this.element.down('.settings') || null;
-
- if(this.settingsButton !== null) {
- this.settingsButton.observe('click', function(event) {
- // TODO: refactor
- var block = $(event.target).up('.mailpoet_form_block') || null;
- if(block !== null) {
- var field = WysijaForm.getFieldData(block);
- this.editSettings();
- }
- }.bind(this));
- }
- }
- return this;
- },
- removeBlock: function(callback) {
- info('block -> removeBlock');
-
- // save block in history
- WysijaHistory.enqueue(this.element);
-
- Effect.Fade(this.element.identify(), {
- duration: 0.2,
- afterFinish: function(effect) {
- // remove placeholder
- if(effect.element.previous('.block_placeholder') !== undefined) {
- effect.element.previous('.block_placeholder').remove();
- }
-
- // remove element from the DOM
- this.element.remove();
-
- // reset block positions
- WysijaForm.setBlockPositions();
-
- // toggle widgets
- WysijaForm.toggleWidgets();
-
- // optional callback execution after completely removing block
- if(callback !== undefined && typeof(callback) === 'function') {
- callback();
- }
-
- // remove block instance
- delete WysijaForm.instances[this.element.identify()];
- }.bind(this)
- });
- }
-});
-
-/* Invoked on item dropped */
-WysijaForm.Block.create = function(createBlock, target) {
- var block = createBlock;
- if($('form_template_' + block.type) === null) {
- return false;
- }
-
- var body = $(WysijaForm.options.body),
- block_template = Handlebars.compile($('form_template_block').innerHTML),
- template = Handlebars.compile($('form_template_' + block.type).innerHTML),
- output = '';
-
- if(block.type === 'segment') {
- if(block.params.values === undefined) {
- var settings_segments = jQuery('#mailpoet_form_segments').val();
- if(settings_segments !== null && settings_segments.length > 0){
- block.params.values = mailpoet_segments.filter(function(segment) {
- return (settings_segments.indexOf(segment.id) !== -1);
- });
- }
- }
- }
-
- // set block template (depending on the block type)
- block.template = template(block);
- output = block_template(block);
-
- // check if the new block is unique and if there's already an instance
- // of it in the history. If so, remove its former instance from the history
- if(block.unique === 1) {
- WysijaHistory.remove(block.field);
- }
-
- // if the drop target was the bottom placeholder
- var element = null;
- if(target.identify() === 'block_placeholder') {
- // insert block at the bottom
- element = body.insert(output);
- //block = body.childElements().last();
- } else {
- // insert block before the drop target
- element = target.insert({
- before: output
- });
- //block = target.previous('.mailpoet_form_block');
- }
- // refresh sortable items
- WysijaForm.makeSortable();
-
- // refresh block positions
- WysijaForm.setBlockPositions();
-
- // position settings
- WysijaForm.setSettingsPosition();
-};
-
-document.observe('wjfe:item:drop', function(event) {
- info('create block');
- WysijaForm.Block.create(event.memo, event.target);
-
- // hide block controls
- info('hide controls');
- WysijaForm.hideBlockControls();
-
- // toggle widgets
- setTimeout(function() {
- WysijaForm.toggleWidgets();
- }, 1);
-});
-
-/* Form Widget */
-WysijaForm.Widget = Class.create(WysijaForm.Block, {
- initialize: function(element) {
- info('widget -> init');
- this.element = $(element);
- return this;
- },
- setup: function() {
- info('widget -> setup');
- this.setupControls();
- },
- save: function() {
- info('widget -> save');
- var data = this.getData();
-
- if(data.element !== undefined) {
- delete data.element;
- }
-
- return data;
- },
- setData: function(data) {
- var current_data = this.getData(),
- params = $H(current_data.params).merge(data.params).toObject();
-
- // update type if it changed
- if(data.type !== undefined && data.type !== current_data.type) {
- this.element.writeAttribute('wysija_type', data.type);
- }
-
- // update params
- this.element.writeAttribute('wysija_params', JSON.stringify(params));
- },
- getData: function() {
- var data = WysijaForm.getFieldData(this.element);
- // decode params
- if(data.params.length > 0) {
- data.params = JSON.parse(data.params);
- }
- return data;
- },
- getControls: function() {
- return this.element.down('.wysija_controls');
- },
- remove: function() {
- this.removeBlock();
- },
- redraw: function(data) {
- // set parameters
- this.setData(data);
- var options = this.getData();
- // redraw block
- var block_template = Handlebars.compile($('form_template_block').innerHTML),
- template = Handlebars.compile($('form_template_' + options.type).innerHTML),
- data = $H(options).merge({
- template: template(options)
- }).toObject();
- this.element.replace(block_template(data));
-
- WysijaForm.init();
- },
- editSettings: function() {
- MailPoet.Modal.popup({
- title: MailPoet.I18n.t('editFieldSettings'),
- template: jQuery('#form_template_field_settings').html(),
- data: this.getData(),
- onSuccess: function() {
- var data = jQuery('#form_field_settings').serializeObject();
- this.redraw(data);
- }.bind(this)
- });
- },
- getSettings: function() {
- return this.element.down('.wysija_settings');
- }
-});
-
-/* When dom is loaded, initialize WysijaForm */
-document.observe('dom:loaded', WysijaForm.init);
-
-/* LOGGING */
-function info(value) {
- if(WysijaForm.options.debug === false) return;
-
- if(!(window.console && console.log)) {
- (function() {
- var noop = function() {};
- var methods = ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'markTimeline', 'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'];
- var length = methods.length;
- window.console = {};
- var console = {};
- while(length--) {
- console[methods[length]] = noop;
- }
- }());
- }
- try {
- console.log('[DEBUG] ' + value);
- } catch(e) {}
-}
-
-module.exports = WysijaForm;
+/*
+ * name: MailPoet Form Editor
+ * author: Jonathan Labreuille
+ * company: Wysija
+ * framework: prototype 1.7.2
+ */
+'use strict';
+
+Event.cacheDelegated = {};
+Object.extend(document, (function() {
+ var cache = Event.cacheDelegated;
+
+ function getCacheForSelector(selector) {
+ cache[selector] = cache[selector] || {};
+ return cache[selector];
+ }
+
+ function getWrappersForSelector(selector, eventName) {
+ var c = getCacheForSelector(selector);
+ c[eventName] = c[eventName] || [];
+ return c[eventName];
+ }
+
+ function findWrapper(selector, eventName, handler) {
+ var c = getWrappersForSelector(selector, eventName);
+ return c.find(function(wrapper) {
+ return wrapper.handler === handler
+ });
+ }
+
+ function destroyWrapper(selector, eventName, handler) {
+ var c = getCacheForSelector(selector);
+ if(!c[eventName]) return false;
+ var wrapper = findWrapper(selector, eventName, handler)
+ c[eventName] = c[eventName].without(wrapper);
+ return wrapper;
+ }
+
+ function createWrapper(selector, eventName, handler, context) {
+ var wrapper, c = getWrappersForSelector(selector, eventName);
+ if(c.pluck('handler').include(handler)) return false;
+ wrapper = function(event) {
+ var element = event.findElement(selector);
+ if(element) handler.call(context || element, event, element);
+ };
+ wrapper.handler = handler;
+ c.push(wrapper);
+ return wrapper;
+ }
+ return {
+ delegate: function(selector, eventName, handler, context) {
+ var wrapper = createWrapper.apply(null, arguments);
+ if(wrapper) document.observe(eventName, wrapper);
+ return document;
+ },
+ stopDelegating: function(selector, eventName, handler) {
+ var length = arguments.length;
+ switch(length) {
+ case 2:
+ getWrappersForSelector(selector, eventName).each(function(wrapper) {
+ document.stopDelegating(selector, eventName, wrapper.handler);
+ });
+ break;
+ case 1:
+ Object.keys(getCacheForSelector(selector)).each(function(eventName) {
+ document.stopDelegating(selector, eventName);
+ });
+ break;
+ case 0:
+ Object.keys(cache).each(function(selector) {
+ document.stopDelegating(selector);
+ });
+ break;
+ default:
+ var wrapper = destroyWrapper.apply(null, arguments);
+ if(wrapper) document.stopObserving(eventName, wrapper);
+ }
+ return document;
+ }
+ }
+})());
+
+var Observable = (function() {
+ function getEventName(nameA, namespace) {
+ var name = nameA.substring(2);
+ if(namespace) name = namespace + ':' + name;
+ return name.underscore().split('_').join(':');
+ }
+
+ function getHandlers(klass) {
+ var proto = klass.prototype,
+ namespace = proto.namespace;
+ return Object.keys(proto).grep(/^on/).inject($H(), function(handlers, name) {
+ if(name === 'onDomLoaded') return handlers;
+ handlers.set(getEventName(name, namespace), getWrapper(proto[name], klass));
+ return handlers;
+ });
+ }
+
+ function getWrapper(handler, klass) {
+ return function(event) {
+ return handler.call(new klass(this), event, event.memo);
+ }
+ }
+
+ function onDomLoad(selector, klass) {
+ $$(selector).each(function(element) {
+ new klass(element).onDomLoaded();
+ });
+ }
+ return {
+ observe: function(selector) {
+ if(!this.handlers) this.handlers = {};
+ if(this.handlers[selector]) return;
+ var klass = this;
+ if(this.prototype.onDomLoaded) document.loaded ? onDomLoad(selector, klass) : document.observe('dom:loaded', onDomLoad.curry(selector, klass));
+ this.handlers[selector] = getHandlers(klass).each(function(handler) {
+ document.delegate(selector, handler.key, handler.value);
+ });
+ },
+ stopObserving: function(selector) {
+ if(!this.handlers || !this.handlers[selector]) return;
+ this.handlers[selector].each(function(handler) {
+ document.stopDelegating(selector, handler.key, handler.value);
+ });
+ delete this.handlers[selector];
+ }
+ }
+})();
+
+// override droppables
+Object.extend(Droppables, {
+ deactivate: Droppables.deactivate.wrap(function(proceed, drop, draggable) {
+ if(drop.onLeave) drop.onLeave(draggable, drop.element);
+ return proceed(drop);
+ }),
+ activate: Droppables.activate.wrap(function(proceed, drop, draggable) {
+ if(drop.onEnter) drop.onEnter(draggable, drop.element);
+ return proceed(drop);
+ }),
+ show: function(point, element) {
+ if(!this.drops.length) return;
+ var drop, affected = [];
+ this.drops.each(function(drop) {
+ if(Droppables.isAffected(point, element, drop)) affected.push(drop);
+ });
+ if(affected.length > 0) drop = Droppables.findDeepestChild(affected);
+ if(this.last_active && this.last_active !== drop) this.deactivate(this.last_active, element);
+ if(drop) {
+ Position.within(drop.element, point[0], point[1]);
+ if(drop.onHover) drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
+ if(drop !== this.last_active) Droppables.activate(drop, element);
+ }
+ },
+ displayArea: function(draggable) {
+ if(!this.drops.length) return;
+
+ // hide controls when displaying drop areas.
+ WysijaForm.hideBlockControls();
+
+ this.drops.each(function(drop, iterator) {
+ if(drop.element.hasClassName('block_placeholder')) {
+ drop.element.addClassName('active');
+ }
+ });
+ },
+ hideArea: function() {
+ if(!this.drops.length) return;
+ this.drops.each(function(drop, iterator) {
+ if(drop.element.hasClassName('block_placeholder')) {
+ drop.element.removeClassName('active');
+ } else if(drop.element.hasClassName('image_placeholder')) {
+ drop.element.removeClassName('active');
+ drop.element.up().removeClassName('active');
+ } else if(drop.element.hasClassName('text_placeholder')) {
+ drop.element.removeClassName('active');
+ }
+ });
+ },
+ reset: function(draggable) {
+ if(this.last_active) this.deactivate(this.last_active, draggable);
+ }
+});
+
+/*
+ Wysija History handling
+ POTENTIAL FEATURES:
+ - set a maximum number of items to be stored
+
+*/
+var WysijaHistory = {
+ container: 'mailpoet_form_history',
+ size: 30,
+ enqueue: function(element) {
+ // create deep clone (includes child elements) of passed element
+ var clone = element.clone(true);
+
+ // check if the field is unique
+ if(parseInt(clone.readAttribute('wysija_unique'), 10) === 1) {
+ // check if the field is already in the queue
+ $(WysijaHistory.container).select('[wysija_name="' + clone.readAttribute('wysija_name') + '"]').invoke('remove');
+ }
+
+ // check history size
+ if($(WysijaHistory.container).select('> div').length >= WysijaHistory.size) {
+ // remove oldest element (last in the list)
+ $(WysijaHistory.container).select('> div').last().remove();
+ }
+
+ // store block in history
+ $(WysijaHistory.container).insert({
+ top: clone
+ });
+ },
+ dequeue: function() {
+ // pop last block off the history
+ var block = $(WysijaHistory.container).select('div').first();
+
+ if(block !== undefined) {
+ // insert block back into the editor
+ $(WysijaForm.options.body).insert({
+ top: block
+ });
+ }
+ },
+ clear: function() {
+ $(WysijaHistory.container).innerHTML = '';
+ },
+ remove: function(field) {
+ $(WysijaHistory.container).select('[wysija_name="' + field + '"]').invoke('remove');
+ }
+};
+
+/* MailPoet Form */
+var WysijaForm = {
+ version: '0.7',
+ options: {
+ container: 'mailpoet_form_container',
+ editor: 'mailpoet_form_editor',
+ body: 'mailpoet_form_body',
+ toolbar: 'mailpoet_form_toolbar',
+ templates: 'wysija_widget_templates',
+ debug: false
+ },
+ toolbar: {
+ effect: null,
+ x: null,
+ y: null,
+ top: null,
+ left: null
+ },
+ scroll: {
+ top: 0,
+ left: 0
+ },
+ flags: {
+ doSave: false
+ },
+ locks: {
+ dragging: false,
+ selectingColor: false,
+ showingTools: false
+ },
+ encodeHtmlValue: function(str) {
+ return str.replace(/&/g, '&').replace(/>/g, '>').replace(/').replace(/</g, '<').replace(/"/g, '"');
+ // ": fix for FileMerge because the previous line fucks up its syntax coloring
+ },
+ loading: function(is_loading) {
+ if(is_loading) {
+ $(WysijaForm.options.editor).addClassName('loading');
+ $(WysijaForm.options.toolbar).addClassName('loading');
+ } else {
+ $(WysijaForm.options.editor).removeClassName('loading');
+ $(WysijaForm.options.toolbar).removeClassName('loading');
+ }
+ },
+ loadStatic: function(blocks) {
+ $A(blocks).each(function(block) {
+ // create block
+ WysijaForm.Block.create(block, $('block_placeholder'));
+ });
+ },
+ load: function(data) {
+ if(data === undefined) return;
+
+ // load body
+ if(data.body !== undefined) {
+ $A(data.body).each(function(block) {
+ // create block
+ WysijaForm.Block.create(block, $('block_placeholder'));
+ });
+
+ // load settings
+ var settings_elements = $('mailpoet_form_settings').getElements();
+ settings_elements.each(function(setting) {
+ // skip lists
+ if(setting.name === 'segments') {
+ return true;
+ } else if(setting.name === 'on_success') {
+ // if the input value is equal to the one stored in the settings
+ if(setting.value === data.settings[setting.name]) {
+ // check selected value
+ $(setting).checked = true;
+ }
+ } else if(data.settings[setting.name] !== undefined) {
+ if(typeof data.settings[setting.name] === 'string') {
+ setting.setValue(WysijaForm.decodeHtmlValue(data.settings[setting.name]));
+ } else {
+ setting.setValue(data.settings[setting.name]);
+ }
+ }
+ });
+ }
+ },
+ save: function() {
+ var position = 1,
+ data = {
+ name: $F('mailpoet_form_name'),
+ settings: $('mailpoet_form_settings').serialize(true),
+ body: [],
+ styles: (MailPoet.CodeEditor !== undefined) ? MailPoet.CodeEditor.getValue() : null
+ };
+ // body
+ WysijaForm.getBlocks().each(function(b) {
+ var block_data = (typeof(b.block['save']) === 'function') ? b.block.save() : null;
+
+ if(block_data !== null) {
+ // set block position
+ block_data['position'] = position;
+
+ // increment position
+ position++;
+
+ // add block data to body
+ data['body'].push(block_data);
+ }
+ });
+
+ return data;
+ },
+ init: function() {
+ // set document scroll
+ info('init -> set scroll offsets');
+ WysijaForm.setScrollOffsets();
+
+ // position toolbar
+ info('init -> set toolbar position');
+ WysijaForm.setToolbarPosition();
+
+ // enable droppable targets
+ info('init -> make droppable');
+ WysijaForm.makeDroppable();
+
+ // enable sortable
+ info('init -> make sortable');
+ WysijaForm.makeSortable();
+
+ // hide controls
+ info('init -> hide controls');
+ WysijaForm.hideControls();
+
+ // hide settings
+ info('init -> hide settings');
+ WysijaForm.hideSettings();
+
+ // set settings buttons position
+ info('init -> init settings');
+ WysijaForm.setSettingsPosition();
+
+ // toggle widgets
+ info('init -> toggle widgets');
+ WysijaForm.toggleWidgets();
+ },
+ getFieldData: function(element) {
+ // get basic field data
+ var data = {
+ type: element.readAttribute('wysija_type'),
+ name: element.readAttribute('wysija_name'),
+ id: element.readAttribute('wysija_id'),
+ unique: parseInt(element.readAttribute('wysija_unique') || 0, 10),
+ static: parseInt(element.readAttribute('wysija_static') || 0, 10),
+ element: element,
+ params: ''
+ };
+
+ // get params (may be empty)
+ if(element.readAttribute('wysija_params') !== null && element.readAttribute('wysija_params').length > 0) {
+ data.params = JSON.parse(element.readAttribute('wysija_params'));
+ }
+ return data;
+ },
+ toggleWidgets: function() {
+ $$('a[wysija_unique="1"]').invoke('removeClassName', 'disabled');
+
+ // loop through each unique field already inserted in the editor and disable its toolbar equivalent
+ $$('#' + WysijaForm.options.editor + ' [wysija_unique="1"]').map(function(element) {
+ var field = $$('#' + WysijaForm.options.toolbar + ' [wysija_id="' + element.readAttribute('wysija_id') + '"]');
+ if(field.length > 0) {
+ field.first().addClassName('disabled');
+ }
+ });
+
+ var hasSegmentSelection = WysijaForm.hasSegmentSelection();
+
+ if(hasSegmentSelection) {
+ $('mailpoet_form_segments').writeAttribute('required', false).disable();
+ $('mailpoet_settings_segment_selection').hide();
+ } else {
+ $('mailpoet_form_segments').writeAttribute('required', true).enable();
+ $('mailpoet_settings_segment_selection').show();
+ }
+ },
+ hasSegmentSelection: function() {
+ return ($$('#' + WysijaForm.options.editor + ' [wysija_id="segments"]').length > 0);
+ },
+ isSegmentSelectionValid: function() {
+ var segment_selection = $$('#' + WysijaForm.options.editor + ' [wysija_id="segments"]')[0];
+ if(segment_selection !== undefined) {
+ var block = WysijaForm.get(segment_selection).block.getData();
+ return (
+ (block.params.values !== undefined)
+ &&
+ (block.params.values.length > 0)
+ );
+ }
+ return false;
+ },
+ setBlockPositions: function(event, target) {
+ // release dragging lock
+ WysijaForm.locks.dragging = false;
+
+ var index = 1;
+ WysijaForm.getBlocks().each(function(container) {
+ container.setPosition(index++);
+ // remove z-index value to avoid issues when resizing images
+ if(container['block'] !== undefined) {
+ container.block.element.setStyle({
+ zIndex: ''
+ });
+ }
+ });
+
+ if(target !== undefined) {
+ // get placeholders (previous placeholder matches the placeholder linked to the next block)
+ var block_placeholder = $(target.element.readAttribute('wysija_placeholder')),
+ previous_placeholder = target.element.previous('.block_placeholder');
+
+ if(block_placeholder !== null) {
+ // put block placeholder before the current block
+ target.element.insert({
+ before: block_placeholder
+ });
+
+ // if the next block is a wysija_block, insert previous placeholder
+ if(target.element.next() !== undefined && target.element.next().hasClassName('mailpoet_form_block') && previous_placeholder !== undefined) {
+ target.element.insert({
+ after: previous_placeholder
+ });
+ }
+ }
+ }
+ },
+ setScrollOffsets: function() {
+ WysijaForm.scroll = document.viewport.getScrollOffsets();
+ },
+ hideSettings: function() {
+ $(WysijaForm.options.container).select('.wysija_settings').invoke('hide');
+ },
+ setSettingsPosition: function() {
+ // get viewport offsets and dimensions
+ var viewportHeight = document.viewport.getHeight(),
+ blockPadding = 5;
+
+ $(WysijaForm.options.container).select('.wysija_settings').each(function(element) {
+ // get parent dimensions and position
+ var parentDim = element.up('.mailpoet_form_block').getDimensions(),
+ parentPos = element.up('.mailpoet_form_block').cumulativeOffset(),
+ is_visible = (parentPos.top <= (WysijaForm.scroll.top + viewportHeight)) ? true : false,
+ buttonMargin = 5,
+ relativeTop = buttonMargin;
+
+ if(is_visible) {
+ // desired position is set to center of viewport
+ var absoluteTop = parseInt(WysijaForm.scroll.top + ((viewportHeight / 2) - (element.getHeight() / 2)), 10),
+ parentTop = parseInt(parentPos.top - blockPadding, 10),
+ parentBottom = parseInt(parentPos.top + parentDim.height - blockPadding, 10);
+
+ // always center
+ relativeTop = parseInt((parentDim.height / 2) - (element.getHeight() / 2), 10);
+ }
+ // set position for button
+ $(element).setStyle({
+ left: parseInt((parentDim.width / 2) - (element.getWidth() / 2)) + 'px',
+ top: relativeTop + 'px'
+ });
+ });
+ },
+ initToolbarPosition: function() {
+ if(WysijaForm.toolbar.top === null) WysijaForm.toolbar.top = parseInt($(WysijaForm.options.container).positionedOffset().top);
+ if(WysijaForm.toolbar.y === null) WysijaForm.toolbar.y = parseInt(WysijaForm.toolbar.top);
+
+ if(isRtl) {
+ if(WysijaForm.toolbar.left === null) WysijaForm.toolbar.left = 0;
+ } else {
+ if(WysijaForm.toolbar.left === null) WysijaForm.toolbar.left = parseInt($(WysijaForm.options.container).positionedOffset().left);
+ }
+ if(WysijaForm.toolbar.x === null) WysijaForm.toolbar.x = parseInt(WysijaForm.toolbar.left + $(WysijaForm.options.container).getDimensions().width + 15);
+
+ },
+ setToolbarPosition: function() {
+ WysijaForm.initToolbarPosition();
+
+ var position = {
+ top: WysijaForm.toolbar.y + 'px',
+ visibility: 'visible'
+ };
+
+ if(isRtl) {
+ position.right = WysijaForm.toolbar.x + 'px';
+ } else {
+ position.left = WysijaForm.toolbar.x + 'px';
+ }
+
+ $(WysijaForm.options.toolbar).setStyle(position);
+ },
+ updateToolbarPosition: function() {
+ // init toolbar position (updates scroll and toolbar y)
+ WysijaForm.initToolbarPosition();
+
+ // cancel previous effect
+ if(WysijaForm.toolbar.effect !== null) WysijaForm.toolbar.effect.cancel();
+
+ if(WysijaForm.scroll.top >= (WysijaForm.toolbar.top - 20)) {
+ WysijaForm.toolbar.y = parseInt(20 + WysijaForm.scroll.top);
+ // start effect
+ WysijaForm.toolbar.effect = new Effect.Move(WysijaForm.options.toolbar, {
+ x: WysijaForm.toolbar.x,
+ y: WysijaForm.toolbar.y,
+ mode: 'absolute',
+ duration: 0.2
+ });
+ } else {
+ $(WysijaForm.options.toolbar).setStyle({
+ left: WysijaForm.toolbar.x + 'px',
+ top: WysijaForm.toolbar.top + 'px'
+ });
+ }
+ },
+ blockDropOptions: {
+ accept: $w('mailpoet_form_field'), // acceptable items (classes array)
+ onEnter: function(draggable, droppable) {
+ $(droppable).addClassName('hover');
+ },
+ onLeave: function(draggable, droppable) {
+ $(droppable).removeClassName('hover');
+ },
+ onDrop: function(draggable, droppable) {
+ // custom data for images
+ droppable.fire('wjfe:item:drop', WysijaForm.getFieldData(draggable));
+ $(droppable).removeClassName('hover');
+ }
+ },
+ hideControls: function() {
+ try {
+ return WysijaForm.getBlocks().invoke('hideControls');
+ } catch(e) {
+ return;
+ }
+ },
+ hideTools: function() {
+ $$('.wysija_tools').invoke('hide');
+ WysijaForm.locks.showingTools = false;
+ },
+ instances: {},
+ get: function(element, typ) {
+ var type = typ;
+ if(type === undefined) type = 'block';
+ // identify element
+ var id = element.identify();
+ var instance = WysijaForm.instances[id] || new WysijaForm[type.capitalize().camelize()](id);
+
+ WysijaForm.instances[id] = instance;
+ return instance;
+ },
+ makeDroppable: function() {
+ Droppables.add('block_placeholder', WysijaForm.blockDropOptions);
+ },
+ makeSortable: function() {
+ var body = $(WysijaForm.options.body);
+ Sortable.create(body, {
+ tag: 'div',
+ only: 'mailpoet_form_block',
+ scroll: window,
+ handle: 'handle',
+ constraint: 'vertical'
+
+ });
+ Draggables.removeObserver(body);
+ Draggables.addObserver({
+ element: body,
+ onStart: WysijaForm.startBlockPositions,
+ onEnd: WysijaForm.setBlockPositions
+ });
+ },
+ hideBlockControls: function() {
+ $$('.wysija_controls').invoke('hide');
+ this.getBlockElements().invoke('removeClassName', 'hover');
+ },
+ getBlocks: function() {
+ return WysijaForm.getBlockElements().map(function(element) {
+ return WysijaForm.get(element);
+ });
+ },
+ getBlockElements: function() {
+ return $(WysijaForm.options.container).select('.mailpoet_form_block');
+ },
+ startBlockPositions: function(event, target) {
+ if(target.element.hasClassName('mailpoet_form_block')) {
+ // store block placeholder id for the block that is being repositionned
+ if(target.element.previous('.block_placeholder') !== undefined) {
+ target.element.writeAttribute('wysija_placeholder', target.element.previous('.block_placeholder').identify());
+ }
+ }
+ WysijaForm.locks.dragging = true;
+ },
+ encodeURIComponent: function(str) {
+ // check if it's a url and if so, prevent encoding of protocol
+ var regexp = new RegExp(/^http[s]?:\/\//),
+ protocol = regexp.exec(str);
+
+ if(protocol === null) {
+ // this is not a url so encode the whole thing
+ return encodeURIComponent(str).replace(/[!'()*]/g, escape);
+ } else if(protocol.length === 1) {
+ // this is a url, so do not encode the protocol
+ return encodeURI(str).replace(/[!'()*]/g, escape);
+ }
+ },
+ updateBlock: function(field) {
+ var hasUpdated = false;
+ WysijaForm.getBlocks().each(function(b) {
+ if(b.block.getData().id === field.id) {
+ hasUpdated = true;
+ b.block.redraw(field);
+ }
+ });
+
+ return hasUpdated;
+ },
+ removeBlock: function(field, callback) {
+ var hasRemoved = false;
+ WysijaForm.getBlocks().each(function(b) {
+ if(b.block.getData().id === field.id) {
+ hasRemoved = true;
+ b.block.removeBlock(callback);
+ }
+ });
+
+ return hasRemoved;
+ }
+};
+
+WysijaForm.DraggableItem = Class.create({
+ initialize: function(element) {
+ this.elementType = $(element).readAttribute('wysija_type');
+ this.element = $(element).down() || $(element);
+ this.clone = this.cloneElement();
+ this.insert();
+ },
+ STYLES: new Template('position: absolute; top: #{top}px; left: #{left}px;'),
+ cloneElement: function() {
+ var clone = this.element.clone(),
+ offset = this.element.cumulativeOffset(),
+ list = this.getList(),
+ styles = this.STYLES.evaluate({
+ top: offset.top - list.scrollTop,
+ left: offset.left - list.scrollLeft
+ });
+ clone.setStyle(styles);
+
+ clone.addClassName('mailpoet_form_widget');
+ clone.addClassName(this.elementType);
+ clone.innerHTML = this.element.innerHTML;
+ return clone;
+ },
+ getOffset: function() {
+ return this.element.offsetTop - this.getList().scrollTop;
+ },
+ getList: function() {
+ return this.element.up('ul');
+ },
+ insert: function() {
+ $$('body')[0].insert(this.clone);
+ },
+ onMousedown: function(event) {
+ var draggable = new Draggable(this.clone, {
+ scroll: window,
+ onStart: function() {
+ Droppables.displayArea(draggable);
+ },
+ onEnd: function(drag) {
+ drag.destroy();
+ drag.element.remove();
+ Droppables.hideArea();
+ },
+ starteffect: function(element) {
+ new Effect.Opacity(element, {
+ duration: 0.2,
+ from: element.getOpacity(),
+ to: 0.7
+ });
+ },
+ endeffect: Prototype.emptyFunction
+ });
+ draggable.initDrag(event);
+ draggable.startDrag(event);
+ return draggable;
+ }
+});
+Object.extend(WysijaForm.DraggableItem, Observable).observe('a[class="mailpoet_form_field"]');
+
+
+WysijaForm.Block = Class.create({
+ /* Invoked on load */
+ initialize: function(element) {
+ info('block -> init');
+
+ this.element = $(element);
+ this.block = new WysijaForm.Widget(this.element);
+
+ // enable block placeholder
+ this.block.makeBlockDroppable();
+
+ // setup events
+ if(this.block['setup'] !== undefined) {
+ this.block.setup();
+ }
+ return this;
+ },
+ setPosition: function(position) {
+ this.element.writeAttribute('wysija_position', position);
+ },
+ hideControls: function() {
+ if(this['getControls']) {
+ this.element.removeClassName('hover');
+ this.getControls().hide();
+ }
+ },
+ showControls: function() {
+ if(this['getControls']) {
+ this.element.addClassName('hover');
+ try {
+ this.getControls().show();
+ } catch(e) {;
+ }
+ }
+ },
+ makeBlockDroppable: function() {
+ if(this.isBlockDroppableEnabled() === false) {
+ var block_placeholder = this.getBlockDroppable();
+ Droppables.add(block_placeholder.identify(), WysijaForm.blockDropOptions);
+ block_placeholder.addClassName('enabled');
+ }
+ },
+ removeBlockDroppable: function() {
+ if(this.isBlockDroppableEnabled()) {
+ var block_placeholder = this.getBlockDroppable();
+ Droppables.remove(block_placeholder.identify());
+ block_placeholder.removeClassName('enabled');
+ }
+ },
+ isBlockDroppableEnabled: function() {
+ // if the block_placeholder does not exist, create it
+ var block_placeholder = this.getBlockDroppable();
+ if(block_placeholder === null) {
+ return this.createBlockDroppable().hasClassName('enabled');
+ } else {
+ return block_placeholder.hasClassName('enabled');
+ }
+ },
+ createBlockDroppable: function() {
+ info('block -> createBlockDroppable');
+ this.element.insert({
+ before: '' + $('block_placeholder').innerHTML + '
'
+ });
+ return this.element.previous('.block_placeholder');
+ },
+ getBlockDroppable: function() {
+ if(this.element.previous() === undefined || this.element.previous().hasClassName('block_placeholder') === false) {
+ return null;
+ } else {
+ return this.element.previous();
+ }
+ },
+ getControls: function() {
+ return this.element.down('.wysija_controls');
+ },
+ setupControls: function() {
+ // enable controls
+ this.controls = this.getControls();
+
+ if(this.controls) {
+ // setup events for block controls
+ this.element.observe('mouseover', function() {
+ // special cases where controls shouldn't be displayed
+ if(WysijaForm.locks.dragging === true || WysijaForm.locks.selectingColor === true || WysijaForm.locks.showingTools === true) return;
+
+ // set block flag
+ this.element.addClassName('hover');
+
+ // show controls
+ this.showControls();
+
+ // show settings if present
+ if(this.element.down('.wysija_settings') !== undefined) {
+ this.element.down('.wysija_settings').show();
+ }
+ }.bind(this));
+
+ this.element.observe('mouseout', function() {
+ // special cases where controls shouldn't hide
+ if(WysijaForm.locks.dragging === true || WysijaForm.locks.selectingColor === true) return;
+
+ // hide controls
+ this.hideControls();
+
+ // hide settings if present
+ if(this.element.down('.wysija_settings') !== undefined) {
+ this.element.down('.wysija_settings').hide();
+ }
+ }.bind(this));
+
+
+ // setup click event for remove button
+ this.removeButton = this.controls.down('.remove') || null;
+ if(this.removeButton !== null) {
+ this.removeButton.observe('click', function() {
+ this.removeBlock();
+ this.removeButton.stopObserving('click');
+ }.bind(this));
+ }
+
+ // setup click event for settings button
+ this.settingsButton = this.element.down('.settings') || null;
+
+ if(this.settingsButton !== null) {
+ this.settingsButton.observe('click', function(event) {
+ // TODO: refactor
+ var block = $(event.target).up('.mailpoet_form_block') || null;
+ if(block !== null) {
+ var field = WysijaForm.getFieldData(block);
+ this.editSettings();
+ }
+ }.bind(this));
+ }
+ }
+ return this;
+ },
+ removeBlock: function(callback) {
+ info('block -> removeBlock');
+
+ // save block in history
+ WysijaHistory.enqueue(this.element);
+
+ Effect.Fade(this.element.identify(), {
+ duration: 0.2,
+ afterFinish: function(effect) {
+ // remove placeholder
+ if(effect.element.previous('.block_placeholder') !== undefined) {
+ effect.element.previous('.block_placeholder').remove();
+ }
+
+ // remove element from the DOM
+ this.element.remove();
+
+ // reset block positions
+ WysijaForm.setBlockPositions();
+
+ // toggle widgets
+ WysijaForm.toggleWidgets();
+
+ // optional callback execution after completely removing block
+ if(callback !== undefined && typeof(callback) === 'function') {
+ callback();
+ }
+
+ // remove block instance
+ delete WysijaForm.instances[this.element.identify()];
+ }.bind(this)
+ });
+ }
+});
+
+/* Invoked on item dropped */
+WysijaForm.Block.create = function(createBlock, target) {
+ var block = createBlock;
+ if($('form_template_' + block.type) === null) {
+ return false;
+ }
+
+ var body = $(WysijaForm.options.body),
+ block_template = Handlebars.compile($('form_template_block').innerHTML),
+ template = Handlebars.compile($('form_template_' + block.type).innerHTML),
+ output = '';
+
+ if(block.type === 'segment') {
+ if(block.params.values === undefined) {
+ var settings_segments = jQuery('#mailpoet_form_segments').val();
+ if(settings_segments !== null && settings_segments.length > 0){
+ block.params.values = mailpoet_segments.filter(function(segment) {
+ return (settings_segments.indexOf(segment.id) !== -1);
+ });
+ }
+ }
+ }
+
+ // set block template (depending on the block type)
+ block.template = template(block);
+ output = block_template(block);
+
+ // check if the new block is unique and if there's already an instance
+ // of it in the history. If so, remove its former instance from the history
+ if(block.unique === 1) {
+ WysijaHistory.remove(block.field);
+ }
+
+ // if the drop target was the bottom placeholder
+ var element = null;
+ if(target.identify() === 'block_placeholder') {
+ // insert block at the bottom
+ element = body.insert(output);
+ //block = body.childElements().last();
+ } else {
+ // insert block before the drop target
+ element = target.insert({
+ before: output
+ });
+ //block = target.previous('.mailpoet_form_block');
+ }
+ // refresh sortable items
+ WysijaForm.makeSortable();
+
+ // refresh block positions
+ WysijaForm.setBlockPositions();
+
+ // position settings
+ WysijaForm.setSettingsPosition();
+};
+
+document.observe('wjfe:item:drop', function(event) {
+ info('create block');
+ WysijaForm.Block.create(event.memo, event.target);
+
+ // hide block controls
+ info('hide controls');
+ WysijaForm.hideBlockControls();
+
+ // toggle widgets
+ setTimeout(function() {
+ WysijaForm.toggleWidgets();
+ }, 1);
+});
+
+/* Form Widget */
+WysijaForm.Widget = Class.create(WysijaForm.Block, {
+ initialize: function(element) {
+ info('widget -> init');
+ this.element = $(element);
+ return this;
+ },
+ setup: function() {
+ info('widget -> setup');
+ this.setupControls();
+ },
+ save: function() {
+ info('widget -> save');
+ var data = this.getData();
+
+ if(data.element !== undefined) {
+ delete data.element;
+ }
+
+ return data;
+ },
+ setData: function(data) {
+ var current_data = this.getData(),
+ params = $H(current_data.params).merge(data.params).toObject();
+
+ // update type if it changed
+ if(data.type !== undefined && data.type !== current_data.type) {
+ this.element.writeAttribute('wysija_type', data.type);
+ }
+
+ // update params
+ this.element.writeAttribute('wysija_params', JSON.stringify(params));
+ },
+ getData: function() {
+ var data = WysijaForm.getFieldData(this.element);
+ // decode params
+ if(data.params.length > 0) {
+ data.params = JSON.parse(data.params);
+ }
+ return data;
+ },
+ getControls: function() {
+ return this.element.down('.wysija_controls');
+ },
+ remove: function() {
+ this.removeBlock();
+ },
+ redraw: function(data) {
+ // set parameters
+ this.setData(data);
+ var options = this.getData();
+ // redraw block
+ var block_template = Handlebars.compile($('form_template_block').innerHTML),
+ template = Handlebars.compile($('form_template_' + options.type).innerHTML),
+ data = $H(options).merge({
+ template: template(options)
+ }).toObject();
+ this.element.replace(block_template(data));
+
+ WysijaForm.init();
+ },
+ editSettings: function() {
+ MailPoet.Modal.popup({
+ title: MailPoet.I18n.t('editFieldSettings'),
+ template: jQuery('#form_template_field_settings').html(),
+ data: this.getData(),
+ onSuccess: function() {
+ var data = jQuery('#form_field_settings').serializeObject();
+ this.redraw(data);
+ }.bind(this)
+ });
+ },
+ getSettings: function() {
+ return this.element.down('.wysija_settings');
+ }
+});
+
+/* When dom is loaded, initialize WysijaForm */
+document.observe('dom:loaded', WysijaForm.init);
+
+/* LOGGING */
+function info(value) {
+ if(WysijaForm.options.debug === false) return;
+
+ if(!(window.console && console.log)) {
+ (function() {
+ var noop = function() {};
+ var methods = ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'markTimeline', 'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'];
+ var length = methods.length;
+ window.console = {};
+ var console = {};
+ while(length--) {
+ console[methods[length]] = noop;
+ }
+ }());
+ }
+ try {
+ console.log('[DEBUG] ' + value);
+ } catch(e) {}
+}
+
+module.exports = WysijaForm;
diff --git a/assets/js/src/segments/form.jsx b/assets/js/src/segments/form.jsx
index 00038e4411..64556fbd7a 100644
--- a/assets/js/src/segments/form.jsx
+++ b/assets/js/src/segments/form.jsx
@@ -32,6 +32,9 @@ define(
},
onCreate: function () {
MailPoet.Notice.success(MailPoet.I18n.t('segmentAdded'));
+ MailPoet.trackEvent('Lists > Add new', {
+ 'MailPoet Free version': window.mailpoet_version,
+ });
},
};
diff --git a/assets/js/src/subscribers/form.jsx b/assets/js/src/subscribers/form.jsx
index 9e0cc42475..44373d120c 100644
--- a/assets/js/src/subscribers/form.jsx
+++ b/assets/js/src/subscribers/form.jsx
@@ -144,6 +144,9 @@ define(
},
onCreate: function () {
MailPoet.Notice.success(MailPoet.I18n.t('subscriberAdded'));
+ MailPoet.trackEvent('Subscribers > Add new', {
+ 'MailPoet Free version': window.mailpoet_version,
+ });
},
};
diff --git a/assets/js/src/subscribers/importExport/export.js b/assets/js/src/subscribers/importExport/export.js
index 88def65bb0..3f1f0924d7 100644
--- a/assets/js/src/subscribers/importExport/export.js
+++ b/assets/js/src/subscribers/importExport/export.js
@@ -157,6 +157,11 @@ define(
.replace('[/link]', '');
jQuery('#export_result_notice').html('' + resultMessage + '
').show();
window.location.href = response.data.exportFileURL;
+ MailPoet.trackEvent('Subscribers export completed', {
+ 'Total exported': response.data.totalExported,
+ 'Only confirmed?': exportData.exportConfirmedOption,
+ 'MailPoet Free version': window.mailpoet_version
+ });
}).fail(function(response) {
if (response.errors.length > 0) {
MailPoet.Notice.error(
diff --git a/assets/js/src/subscribers/importExport/import.js b/assets/js/src/subscribers/importExport/import.js
index 71f155b446..aae5586c21 100644
--- a/assets/js/src/subscribers/importExport/import.js
+++ b/assets/js/src/subscribers/importExport/import.js
@@ -141,7 +141,7 @@ define(
// delay loading indicator for 10ms or else it's just too fast :)
MailPoet.Modal.loading(true);
setTimeout(function () {
- Papa.parse(pasteInputElement.val(), parseCSV());
+ Papa.parse(pasteInputElement.val(), parseCSV(false));
}, 10);
});
@@ -168,7 +168,7 @@ define(
MailPoet.Modal.loading(true);
setTimeout(function () {
uploadElement.parse({
- config: parseCSV()
+ config: parseCSV(true)
})
}, 10);
}
@@ -238,6 +238,10 @@ define(
MailPoet.Modal.loading(false);
}).done(function(response) {
importData.step1 = response.data;
+ MailPoet.trackEvent('Subscribers import started', {
+ source: 'MailChimp',
+ 'MailPoet Free version': window.mailpoet_version
+ });
router.navigate('step2', {trigger: true});
}).fail(function(response) {
if (response.errors.length > 0) {
@@ -289,7 +293,7 @@ define(
element.closest('table a').addClass(disabled);
}
- function parseCSV() {
+ function parseCSV(isFile) {
var processedSubscribers = [],
parsedEmails = [],
duplicateEmails = [],
@@ -415,6 +419,10 @@ define(
duplicate: duplicateEmails,
invalid: invalidEmails
};
+ MailPoet.trackEvent('Subscribers import started', {
+ source: isFile ? 'file upload' : 'pasted data',
+ 'MailPoet Free version': window.mailpoet_version
+ });
router.navigate('step2', {trigger: true});
}
else {
@@ -1070,6 +1078,12 @@ define(
MailPoet.Notice.error(_.flatten(importData.step2.errors));
}
+ MailPoet.trackEvent('Subscribers import finished', {
+ 'Subscribers created': importData.step2.created,
+ 'Subscribers updated': importData.step2.updated,
+ 'MailPoet Free version': window.mailpoet_version
+ });
+
// display statistics
var subscribersDataImportResultsTemplate =
Handlebars
@@ -1118,4 +1132,4 @@ define(
Backbone.history.start();
}
});
- });
\ No newline at end of file
+ });
diff --git a/views/form/editor.html b/views/form/editor.html
index 83c43def67..709977548f 100644
--- a/views/form/editor.html
+++ b/views/form/editor.html
@@ -513,6 +513,10 @@
});
}
+ MailPoet.trackEvent('Forms > Add New', {
+ 'MailPoet Free version': window.mailpoet_version
+ });
+
// if there is a callback, call it!
if(callback !== undefined) {
callback();
@@ -566,8 +570,13 @@
mailpoet_form_export();
$(document).on('click', '.mailpoet_form_export_toggle', function() {
+ var type = $(this).data('type');
$('.mailpoet_form_export_output').hide();
- $('#mailpoet_form_export_'+$(this).data('type')).show();
+ $('#mailpoet_form_export_' + type).show();
+ MailPoet.trackEvent('Forms > Embed', {
+ 'Embed type': type,
+ 'MailPoet Free version': window.mailpoet_version
+ });
return false;
});
@@ -614,6 +623,7 @@
var id = $(this).data('id');
var item = $(this).parent();
var name = $(this).siblings('.mailpoet_form_field').attr('wysija_name');
+ var type = $(this).siblings('.mailpoet_form_field').attr('wysija_type');
if(window.confirm(
"<%= __('This field will be deleted for all your subscribers. Are you sure?') %>"
@@ -636,6 +646,12 @@
MailPoet.Notice.success(
"<%= __('Removed custom field %$1s') | escape('js') %>".replace('%$1s', '"' + name + '"')
);
+
+ MailPoet.trackEvent('Forms > Delete custom field', {
+ 'Field type': type,
+ 'MailPoet Free version': window.mailpoet_version
+ });
+
});
}
});
diff --git a/views/form/templates/settings/field_form.hbs b/views/form/templates/settings/field_form.hbs
index f61633c87c..39bd648805 100644
--- a/views/form/templates/settings/field_form.hbs
+++ b/views/form/templates/settings/field_form.hbs
@@ -82,6 +82,11 @@
// close popup
MailPoet.Modal.close();
+ MailPoet.trackEvent('Forms > Add new custom field', {
+ 'Field type': data.type,
+ 'MailPoet Free version': window.mailpoet_version
+ });
+
if(WysijaForm.updateBlock(response.data) === true) {
// trigger save, if a block has been updated
mailpoet_form_save(false);
diff --git a/views/forms.html b/views/forms.html
index e03b785c4e..8e51940fa2 100644
--- a/views/forms.html
+++ b/views/forms.html
@@ -6,7 +6,7 @@
<%= __('Tip: we have a [link]list of plugins[/link] that work with MailPoet if you need fancier forms.')
- |replaceLinkTags('http://beta.docs.mailpoet.com/article/198-list-of-forms-plugins-that-work-with-mailpoet?utm_source=plugin&utm_medium=settings&utm_campaign=helpdocs', {'target' : '_blank'})
+ |replaceLinkTags('http://beta.docs.mailpoet.com/article/198-list-of-forms-plugins-that-work-with-mailpoet?utm_source=plugin&utm_medium=settings&utm_campaign=helpdocs', {'target' : '_blank', id: 'mailpoet_helper_link'})
|raw
%>
@@ -68,3 +68,13 @@
'new': __('Add New'),
}) %>
<% endblock %>
+
+<% block after_javascript %>
+
+<% endblock %>
diff --git a/views/premium.html b/views/premium.html
index 9cc4bea4e4..1bd8936025 100644
--- a/views/premium.html
+++ b/views/premium.html
@@ -148,3 +148,11 @@
<% endblock %>
+
+<% block after_javascript %>
+
+<% endblock %>