[IMP] website, web_editor, mass_mailing: move margin and size options
website -> web_editor so that they are available for mass_mailing. To allow setting margins on td elements: As the above mentionned option allows to control the mt and mb classes on the mass mailing items, the problem is that we would ideally want it to be functionnal on td element as they are the main part of a mail. As they don't support margins, there were many options to fix the problem: - Add more JS to place the mt and mb classes on children of td element - Place the option on children of td element and not td element itself but in that case, the width control of td would imply a lot of parent option hierarchy, or the width control had also to be adapted to control children - Control padding instead of margin. This forces to add lots of css rules like pt4 pt8, ... (or td.mt4, td.mt8, ...). The last solution has been chosen. Padding is more supported than margins in mail client anyway and the css rules will be isolated in the mail editor anyway. Using td.mt4 instead of pt4 had the advantage to not require any JS modification.
This commit is contained in:
@@ -282,3 +282,32 @@
|
||||
width: 100%!important;
|
||||
}
|
||||
}
|
||||
|
||||
// ===== Margins on td (replaced by paddings) =====
|
||||
.o-paddings-all(@factor: 1) {
|
||||
.o-paddings(128, @factor);
|
||||
.o-paddings(96, @factor);
|
||||
.o-paddings(92, @factor);
|
||||
.o-paddings(64, @factor);
|
||||
.o-paddings(48, @factor);
|
||||
.o-paddings(32, @factor);
|
||||
.o-paddings(24, @factor);
|
||||
.o-paddings(16, @factor);
|
||||
.o-paddings(8, @factor);
|
||||
.o-paddings(4, @factor);
|
||||
.o-paddings(0, @factor);
|
||||
}
|
||||
.o-paddings(@name, @factor: 1) {
|
||||
.o-paddings-define(@name, @factor * @name);
|
||||
}
|
||||
.o-paddings-define(@name, @size: @name) {
|
||||
td.mt@{name} {
|
||||
margin-top: auto!important;
|
||||
padding-top: ~"@{size}px"!important;
|
||||
}
|
||||
td.mb@{name} {
|
||||
margin-bottom: auto!important;
|
||||
padding-bottom: ~"@{size}px"!important;
|
||||
}
|
||||
}
|
||||
.o-paddings-all();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<odoo>
|
||||
|
||||
<template id="snippet_options">
|
||||
<t t-call="web_editor.snippet_options"/>
|
||||
<t t-raw="0"/>
|
||||
|
||||
<div data-js="width-x"
|
||||
@@ -29,6 +30,14 @@
|
||||
data-drop-in="[data-oe-field='body_html']:not(:has(.o_layout)), .oe_structure">
|
||||
</div>
|
||||
|
||||
<div data-js="resize"
|
||||
data-selector="[data-oe-field='body_html'] > div:not(.o_layout), [data-oe-field='body_html'] .oe_structure > div">
|
||||
</div>
|
||||
|
||||
<div data-js="margin-y"
|
||||
data-selector="[data-oe-field='body_html'] > div:not(.o_layout), [data-oe-field='body_html'] .oe_structure > div, td, th">
|
||||
</div>
|
||||
|
||||
<div data-js="colorpicker"
|
||||
data-selector="
|
||||
[data-oe-field='body_html'] > div:not(.o_layout):not(.o_mail_block_event):not(.o_mail_block_steps),
|
||||
|
||||
@@ -214,6 +214,231 @@ odoo.define('web_editor.snippets.options', function (require) {
|
||||
|
||||
/* ----- default options ---- */
|
||||
|
||||
registry.marginAndResize = SnippetOption.extend({
|
||||
preventChildPropagation: true,
|
||||
|
||||
start: function () {
|
||||
var self = this;
|
||||
this._super();
|
||||
|
||||
var resize_values = this.getSize();
|
||||
if (resize_values.n) this.$overlay.find(".oe_handle.n").removeClass("readonly");
|
||||
if (resize_values.s) this.$overlay.find(".oe_handle.s").removeClass("readonly");
|
||||
if (resize_values.e) this.$overlay.find(".oe_handle.e").removeClass("readonly");
|
||||
if (resize_values.w) this.$overlay.find(".oe_handle.w").removeClass("readonly");
|
||||
if (resize_values.size) this.$overlay.find(".oe_handle.size").removeClass("readonly");
|
||||
|
||||
var $auto_size = this.$overlay.find(".oe_handle.size .auto_size");
|
||||
var $fixed_size = this.$overlay.find(".oe_handle.size .size");
|
||||
|
||||
var auto_sized = isNaN(parseInt(self.$target.prop("style").height));
|
||||
$fixed_size.toggleClass("active", !auto_sized);
|
||||
$auto_size.toggleClass("active", auto_sized);
|
||||
|
||||
$fixed_size.add(this.$overlay.find(".oe_handle:not(.size)")).on('mousedown', function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
var $handle = $(this);
|
||||
|
||||
var resize_values = self.getSize();
|
||||
var compass = false;
|
||||
var XY = false;
|
||||
if ($handle.hasClass('n')) {
|
||||
compass = 'n';
|
||||
XY = 'Y';
|
||||
}
|
||||
else if ($handle.hasClass('s')) {
|
||||
compass = 's';
|
||||
XY = 'Y';
|
||||
}
|
||||
else if ($handle.hasClass('e')) {
|
||||
compass = 'e';
|
||||
XY = 'X';
|
||||
}
|
||||
else if ($handle.hasClass('w')) {
|
||||
compass = 'w';
|
||||
XY = 'X';
|
||||
}
|
||||
else if ($handle.hasClass('size')) {
|
||||
compass = 'size';
|
||||
XY = 'Y';
|
||||
}
|
||||
|
||||
var resize = resize_values[compass];
|
||||
if (!resize) return;
|
||||
|
||||
|
||||
if (compass === 'size') {
|
||||
var offset = self.$target.offset().top;
|
||||
if (self.$target.css("background").match(/rgba\(0, 0, 0, 0\)/)) {
|
||||
self.$target.addClass("resize_editor_busy");
|
||||
}
|
||||
} else {
|
||||
var xy = event['page'+XY];
|
||||
var current = resize[2] || 0;
|
||||
var margin_dir = {s:'bottom', n: 'top', w: 'left', e: 'right'}[compass];
|
||||
var real_margin = parseInt(self.$target.css('margin-'+margin_dir));
|
||||
_.each(resize[0], function (val, key) {
|
||||
if (self.$target.hasClass(val)) {
|
||||
current = key;
|
||||
} else if (resize[1][key] === real_margin) {
|
||||
current = key;
|
||||
}
|
||||
});
|
||||
var begin = current;
|
||||
var beginClass = self.$target.attr("class");
|
||||
var regClass = new RegExp("\\s*" + resize[0][begin].replace(/[-]*[0-9]+/, '[-]*[0-9]+'), 'g');
|
||||
}
|
||||
|
||||
self.buildingBlock.editor_busy = true;
|
||||
|
||||
var cursor = $handle.css("cursor")+'-important';
|
||||
var $body = $(document.body);
|
||||
$body.addClass(cursor);
|
||||
|
||||
var body_mousemove = function (event) {
|
||||
event.preventDefault();
|
||||
if (compass === 'size') {
|
||||
var dy = event.pageY-offset;
|
||||
dy = dy - dy%resize;
|
||||
if (dy <= 0) dy = resize;
|
||||
self.$target.css("height", dy+"px");
|
||||
self.$target.css("overflow", "hidden");
|
||||
self.on_resize(compass, null, dy);
|
||||
self.buildingBlock.cover_target(self.$overlay, self.$target);
|
||||
return;
|
||||
}
|
||||
var dd = event['page'+XY] - xy + resize[1][begin];
|
||||
var next = current+1 === resize[1].length ? current : (current+1);
|
||||
var prev = current ? (current-1) : 0;
|
||||
|
||||
var change = false;
|
||||
if (dd > (2*resize[1][next] + resize[1][current])/3) {
|
||||
self.$target.attr("class", (self.$target.attr("class")||'').replace(regClass, ''));
|
||||
self.$target.addClass(resize[0][next]);
|
||||
current = next;
|
||||
change = true;
|
||||
}
|
||||
if (prev !== current && dd < (2*resize[1][prev] + resize[1][current])/3) {
|
||||
self.$target.attr("class", (self.$target.attr("class")||'').replace(regClass, ''));
|
||||
self.$target.addClass(resize[0][prev]);
|
||||
current = prev;
|
||||
change = true;
|
||||
}
|
||||
|
||||
if (change) {
|
||||
self.on_resize(compass, beginClass, current);
|
||||
self.buildingBlock.cover_target(self.$overlay, self.$target);
|
||||
}
|
||||
};
|
||||
|
||||
var body_mouseup = function () {
|
||||
$body.unbind('mousemove', body_mousemove);
|
||||
$body.unbind('mouseup', body_mouseup);
|
||||
$body.removeClass(cursor);
|
||||
setTimeout(function () {
|
||||
self.buildingBlock.editor_busy = false;
|
||||
if (begin !== current) {
|
||||
self.buildingBlock.getParent().rte.historyRecordUndo(self.$target, 'resize_' + XY);
|
||||
}
|
||||
},0);
|
||||
self.$target.removeClass("resize_editor_busy");
|
||||
|
||||
if (compass === "size") {
|
||||
$fixed_size.addClass("active");
|
||||
$auto_size.removeClass("active");
|
||||
}
|
||||
};
|
||||
$body.mousemove(body_mousemove);
|
||||
$body.mouseup(body_mouseup);
|
||||
});
|
||||
$auto_size.on('click', function () {
|
||||
self.$target.css("height", "");
|
||||
self.$target.css("overflow", "");
|
||||
self.buildingBlock.getParent().rte.historyRecordUndo(self.$target, 'resize_Y');
|
||||
self.buildingBlock.cover_target(self.$overlay, self.$target);
|
||||
|
||||
$fixed_size.removeClass("active");
|
||||
$auto_size.addClass("active");
|
||||
|
||||
return false;
|
||||
});
|
||||
},
|
||||
getSize: function () {
|
||||
this.grid = {};
|
||||
return this.grid;
|
||||
},
|
||||
|
||||
on_focus : function () {
|
||||
this._super();
|
||||
this.change_cursor();
|
||||
},
|
||||
|
||||
change_cursor : function () {
|
||||
var _class = this.$target.attr("class") || "";
|
||||
|
||||
var col = _class.match(/col-md-([0-9-]+)/i);
|
||||
col = col ? +col[1] : 0;
|
||||
|
||||
var offset = _class.match(/col-md-offset-([0-9-]+)/i);
|
||||
offset = offset ? +offset[1] : 0;
|
||||
|
||||
var overlay_class = this.$overlay.attr("class").replace(/(^|\s+)block-[^\s]*/gi, '');
|
||||
if (col+offset >= 12) overlay_class+= " block-e-right";
|
||||
if (col === 1) overlay_class+= " block-w-right block-e-left";
|
||||
if (offset === 0) overlay_class+= " block-w-left";
|
||||
|
||||
var mb = _class.match(/mb([0-9-]+)/i);
|
||||
mb = mb ? +mb[1] : parseInt(this.$target.css('margin-bottom'));
|
||||
if (mb >= 128) overlay_class+= " block-s-bottom";
|
||||
else if (!mb) overlay_class+= " block-s-top";
|
||||
|
||||
var mt = _class.match(/mt([0-9-]+)/i);
|
||||
mt = mt ? +mt[1] : parseInt(this.$target.css('margin-top'));
|
||||
if (mt >= 128) overlay_class+= " block-n-top";
|
||||
else if (!mt) overlay_class+= " block-n-bottom";
|
||||
|
||||
this.$overlay.attr("class", overlay_class);
|
||||
},
|
||||
|
||||
/* on_resize
|
||||
* called when the box is resizing and the class change, before the cover_target
|
||||
* @compass: resize direction : 'n', 's', 'e', 'w'
|
||||
* @beginClass: attributes class at the begin
|
||||
* @current: curent increment in this.grid
|
||||
*/
|
||||
on_resize: function () {
|
||||
this.change_cursor();
|
||||
}
|
||||
});
|
||||
|
||||
registry["margin-y"] = registry.marginAndResize.extend({
|
||||
preventChildPropagation: true,
|
||||
|
||||
getSize: function () {
|
||||
this.grid = this._super();
|
||||
var grid = [0,4,8,16,32,48,64,92,128];
|
||||
this.grid = {
|
||||
// list of class (Array), grid (Array), default value (INT)
|
||||
n: [_.map(grid, function (v) {return 'mt'+v;}), grid],
|
||||
s: [_.map(grid, function (v) {return 'mb'+v;}), grid],
|
||||
// INT if the user can resize the snippet (resizing per INT px)
|
||||
size: null
|
||||
};
|
||||
return this.grid;
|
||||
},
|
||||
});
|
||||
|
||||
registry.resize = registry.marginAndResize.extend({
|
||||
preventChildPropagation: true,
|
||||
|
||||
getSize: function () {
|
||||
this.grid = this._super();
|
||||
this.grid.size = 8;
|
||||
return this.grid;
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* The colorpicker option is designed to change the background color class of a snippet. This class change the
|
||||
* default background color and text color of the snippet content.
|
||||
|
||||
@@ -248,221 +248,6 @@ options.registry.carousel = options.registry.slider.extend({
|
||||
},
|
||||
});
|
||||
|
||||
options.registry.marginAndResize = options.Class.extend({
|
||||
preventChildPropagation: true,
|
||||
|
||||
start: function () {
|
||||
var self = this;
|
||||
this._super();
|
||||
|
||||
var resize_values = this.getSize();
|
||||
if (resize_values.n) this.$overlay.find(".oe_handle.n").removeClass("readonly");
|
||||
if (resize_values.s) this.$overlay.find(".oe_handle.s").removeClass("readonly");
|
||||
if (resize_values.e) this.$overlay.find(".oe_handle.e").removeClass("readonly");
|
||||
if (resize_values.w) this.$overlay.find(".oe_handle.w").removeClass("readonly");
|
||||
if (resize_values.size) this.$overlay.find(".oe_handle.size").removeClass("readonly");
|
||||
|
||||
var $auto_size = this.$overlay.find(".oe_handle.size .auto_size");
|
||||
var $fixed_size = this.$overlay.find(".oe_handle.size .size");
|
||||
|
||||
var auto_sized = isNaN(parseInt(self.$target.prop("style").height));
|
||||
$fixed_size.toggleClass("active", !auto_sized);
|
||||
$auto_size.toggleClass("active", auto_sized);
|
||||
|
||||
$fixed_size.add(this.$overlay.find(".oe_handle:not(.size)")).on('mousedown', function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
var $handle = $(this);
|
||||
|
||||
var resize_values = self.getSize();
|
||||
var compass = false;
|
||||
var XY = false;
|
||||
if ($handle.hasClass('n')) {
|
||||
compass = 'n';
|
||||
XY = 'Y';
|
||||
}
|
||||
else if ($handle.hasClass('s')) {
|
||||
compass = 's';
|
||||
XY = 'Y';
|
||||
}
|
||||
else if ($handle.hasClass('e')) {
|
||||
compass = 'e';
|
||||
XY = 'X';
|
||||
}
|
||||
else if ($handle.hasClass('w')) {
|
||||
compass = 'w';
|
||||
XY = 'X';
|
||||
}
|
||||
else if ($handle.hasClass('size')) {
|
||||
compass = 'size';
|
||||
XY = 'Y';
|
||||
}
|
||||
|
||||
var resize = resize_values[compass];
|
||||
if (!resize) return;
|
||||
|
||||
|
||||
if (compass === 'size') {
|
||||
var offset = self.$target.offset().top;
|
||||
if (self.$target.css("background").match(/rgba\(0, 0, 0, 0\)/)) {
|
||||
self.$target.addClass("resize_editor_busy");
|
||||
}
|
||||
} else {
|
||||
var xy = event['page'+XY];
|
||||
var current = resize[2] || 0;
|
||||
var margin_dir = {s:'bottom', n: 'top', w: 'left', e: 'right'}[compass];
|
||||
var real_margin = parseInt(self.$target.css('margin-'+margin_dir));
|
||||
_.each(resize[0], function (val, key) {
|
||||
if (self.$target.hasClass(val)) {
|
||||
current = key;
|
||||
} else if (resize[1][key] === real_margin) {
|
||||
current = key;
|
||||
}
|
||||
});
|
||||
var begin = current;
|
||||
var beginClass = self.$target.attr("class");
|
||||
var regClass = new RegExp("\\s*" + resize[0][begin].replace(/[-]*[0-9]+/, '[-]*[0-9]+'), 'g');
|
||||
}
|
||||
|
||||
self.buildingBlock.editor_busy = true;
|
||||
|
||||
var cursor = $handle.css("cursor")+'-important';
|
||||
var $body = $(document.body);
|
||||
$body.addClass(cursor);
|
||||
|
||||
var body_mousemove = function (event) {
|
||||
event.preventDefault();
|
||||
if (compass === 'size') {
|
||||
var dy = event.pageY-offset;
|
||||
dy = dy - dy%resize;
|
||||
if (dy <= 0) dy = resize;
|
||||
self.$target.css("height", dy+"px");
|
||||
self.$target.css("overflow", "hidden");
|
||||
self.on_resize(compass, null, dy);
|
||||
self.buildingBlock.cover_target(self.$overlay, self.$target);
|
||||
return;
|
||||
}
|
||||
var dd = event['page'+XY] - xy + resize[1][begin];
|
||||
var next = current+1 === resize[1].length ? current : (current+1);
|
||||
var prev = current ? (current-1) : 0;
|
||||
|
||||
var change = false;
|
||||
if (dd > (2*resize[1][next] + resize[1][current])/3) {
|
||||
self.$target.attr("class", (self.$target.attr("class")||'').replace(regClass, ''));
|
||||
self.$target.addClass(resize[0][next]);
|
||||
current = next;
|
||||
change = true;
|
||||
}
|
||||
if (prev !== current && dd < (2*resize[1][prev] + resize[1][current])/3) {
|
||||
self.$target.attr("class", (self.$target.attr("class")||'').replace(regClass, ''));
|
||||
self.$target.addClass(resize[0][prev]);
|
||||
current = prev;
|
||||
change = true;
|
||||
}
|
||||
|
||||
if (change) {
|
||||
self.on_resize(compass, beginClass, current);
|
||||
self.buildingBlock.cover_target(self.$overlay, self.$target);
|
||||
}
|
||||
};
|
||||
|
||||
var body_mouseup = function () {
|
||||
$body.unbind('mousemove', body_mousemove);
|
||||
$body.unbind('mouseup', body_mouseup);
|
||||
$body.removeClass(cursor);
|
||||
setTimeout(function () {
|
||||
self.buildingBlock.editor_busy = false;
|
||||
if (begin !== current) {
|
||||
self.buildingBlock.getParent().rte.historyRecordUndo(self.$target, 'resize_' + XY);
|
||||
}
|
||||
},0);
|
||||
self.$target.removeClass("resize_editor_busy");
|
||||
|
||||
if (compass === "size") {
|
||||
$fixed_size.addClass("active");
|
||||
$auto_size.removeClass("active");
|
||||
}
|
||||
};
|
||||
$body.mousemove(body_mousemove);
|
||||
$body.mouseup(body_mouseup);
|
||||
});
|
||||
$auto_size.on('click', function () {
|
||||
self.$target.css("height", "");
|
||||
self.$target.css("overflow", "");
|
||||
self.buildingBlock.getParent().rte.historyRecordUndo(self.$target, 'resize_Y');
|
||||
self.buildingBlock.cover_target(self.$overlay, self.$target);
|
||||
|
||||
$fixed_size.removeClass("active");
|
||||
$auto_size.addClass("active");
|
||||
|
||||
return false;
|
||||
});
|
||||
},
|
||||
getSize: function () {
|
||||
this.grid = {};
|
||||
return this.grid;
|
||||
},
|
||||
|
||||
on_focus : function () {
|
||||
this._super();
|
||||
this.change_cursor();
|
||||
},
|
||||
|
||||
change_cursor : function () {
|
||||
var _class = this.$target.attr("class") || "";
|
||||
|
||||
var col = _class.match(/col-md-([0-9-]+)/i);
|
||||
col = col ? +col[1] : 0;
|
||||
|
||||
var offset = _class.match(/col-md-offset-([0-9-]+)/i);
|
||||
offset = offset ? +offset[1] : 0;
|
||||
|
||||
var overlay_class = this.$overlay.attr("class").replace(/(^|\s+)block-[^\s]*/gi, '');
|
||||
if (col+offset >= 12) overlay_class+= " block-e-right";
|
||||
if (col === 1) overlay_class+= " block-w-right block-e-left";
|
||||
if (offset === 0) overlay_class+= " block-w-left";
|
||||
|
||||
var mb = _class.match(/mb([0-9-]+)/i);
|
||||
mb = mb ? +mb[1] : parseInt(this.$target.css('margin-bottom'));
|
||||
if (mb >= 128) overlay_class+= " block-s-bottom";
|
||||
else if (!mb) overlay_class+= " block-s-top";
|
||||
|
||||
var mt = _class.match(/mt([0-9-]+)/i);
|
||||
mt = mt ? +mt[1] : parseInt(this.$target.css('margin-top'));
|
||||
if (mt >= 128) overlay_class+= " block-n-top";
|
||||
else if (!mt) overlay_class+= " block-n-bottom";
|
||||
|
||||
this.$overlay.attr("class", overlay_class);
|
||||
},
|
||||
|
||||
/* on_resize
|
||||
* called when the box is resizing and the class change, before the cover_target
|
||||
* @compass: resize direction : 'n', 's', 'e', 'w'
|
||||
* @beginClass: attributes class at the begin
|
||||
* @current: curent increment in this.grid
|
||||
*/
|
||||
on_resize: function () {
|
||||
this.change_cursor();
|
||||
}
|
||||
});
|
||||
|
||||
options.registry["margin-y"] = options.registry.marginAndResize.extend({
|
||||
preventChildPropagation: true,
|
||||
|
||||
getSize: function () {
|
||||
this.grid = this._super();
|
||||
var grid = [0,4,8,16,32,48,64,92,128];
|
||||
this.grid = {
|
||||
// list of class (Array), grid (Array), default value (INT)
|
||||
n: [_.map(grid, function (v) {return 'mt'+v;}), grid],
|
||||
s: [_.map(grid, function (v) {return 'mb'+v;}), grid],
|
||||
// INT if the user can resize the snippet (resizing per INT px)
|
||||
size: null
|
||||
};
|
||||
return this.grid;
|
||||
},
|
||||
});
|
||||
|
||||
options.registry["margin-x"] = options.registry.marginAndResize.extend({
|
||||
preventChildPropagation: true,
|
||||
|
||||
@@ -508,16 +293,6 @@ options.registry["margin-x"] = options.registry.marginAndResize.extend({
|
||||
},
|
||||
});
|
||||
|
||||
options.registry.resize = options.registry.marginAndResize.extend({
|
||||
preventChildPropagation: true,
|
||||
|
||||
getSize: function () {
|
||||
this.grid = this._super();
|
||||
this.grid.size = 8;
|
||||
return this.grid;
|
||||
},
|
||||
});
|
||||
|
||||
options.registry.parallax = options.Class.extend({
|
||||
getSize: function () {
|
||||
this.grid = this._super.apply(this, arguments);
|
||||
|
||||
Reference in New Issue
Block a user