diff --git a/addons/mass_mailing/static/src/js/mass_mailing_editor.js b/addons/mass_mailing/static/src/js/mass_mailing_editor.js index 7705e62fa9e..e88d77864d2 100644 --- a/addons/mass_mailing/static/src/js/mass_mailing_editor.js +++ b/addons/mass_mailing/static/src/js/mass_mailing_editor.js @@ -12,32 +12,35 @@ var $editable_area = $('#editable_area'); var odoo_top = window.top.odoo; // Snippet option for resizing image and column width inline like excel -options.registry["width-x"] = options.Class.extend({ +options.registry.sizing_x = options.Class.extend({ + /** + * @override + */ start: function () { - this.container_width = this.$target.parent().closest("td, table, div").width(); + var def = this._super.apply(this, arguments); + + this.containerWidth = this.$target.parent().closest("td, table, div").width(); var self = this; var offset, sib_offset, target_width, sib_width; - var $body = $(document.body); - this.is_image = false; - this._super.apply(this, arguments); - this.$overlay.find(".oe_handle.e, .oe_handle.w").removeClass("readonly"); - if (this.$target.is("img")) { - this.$overlay.find(".oe_handle.w").addClass("readonly"); + this.$overlay.find(".o_handle.e, .o_handle.w").removeClass("readonly"); + this.isIMG = this.$target.is("img"); + if (this.isIMG) { + this.$overlay.find(".o_handle.w").addClass("readonly"); this.$overlay.find(".oe_snippet_move, .oe_snippet_clone").addClass("hidden"); - this.is_image=true; } - this.$overlay.find(".oe_handle").on('mousedown', function (event) { + var $body = $(document.body); + this.$overlay.find(".o_handle").on('mousedown', function (event) { event.preventDefault(); var $handle = $(this); var compass = false; - _.each(['n', 's', 'e', 'w' ], function (handler) { + _.each(['n', 's', 'e', 'w'], function (handler) { if ($handle.hasClass(handler)) { compass = handler; } }); - if (self.is_image) { compass = "image"; } + if (self.isIMG) { compass = "image"; } $body.on("mousemove.mass_mailing_width_x", function (event) { event.preventDefault(); @@ -59,11 +62,12 @@ options.registry["width-x"] = options.Class.extend({ self.change_width(event, self.$target, target_width, offset, true); } }); - - $body.one("mouseup", function(){ + $body.one("mouseup", function () { $body.off('.mass_mailing_width_x'); }); }); + + return def; }, change_width: function (event, target, target_width, offset, grow) { target.css("width", grow ? (event.pageX - offset) : (offset + target_width - event.pageX)); @@ -73,13 +77,13 @@ options.registry["width-x"] = options.Class.extend({ return parseInt($(el).css("width"), 10); }, get_max_width: function ($el) { - return this.container_width - _.reduce(_.map($el.siblings(), this.get_int_width), function (memo, w) { return memo + w; }); + return this.containerWidth - _.reduce(_.map($el.siblings(), this.get_int_width), function (memo, w) { return memo + w; }); }, onFocus: function () { this._super.apply(this, arguments); if (this.$target.is("td, th")) { - this.$overlay.find(".oe_handle.e, .oe_handle.w").toggleClass("readonly", this.$target.siblings().length === 0); + this.$overlay.find(".o_handle.e, .o_handle.w").toggleClass("readonly", this.$target.siblings().length === 0); } }, }); @@ -407,7 +411,7 @@ if ($editable_area.html().indexOf('on_change_model_and_list') !== -1) { // Adding compatibility for the outlook compliance of mailings. // Commit of such compatibility : a14f89c8663c9cafecb1cc26918055e023ecbe42 options.registry.background.include({ - start: function() { + start: function () { this._super(); var $table_target = this.$target.find('table:first'); if ($table_target) { diff --git a/addons/mass_mailing/static/src/less/themes/theme_default.less b/addons/mass_mailing/static/src/less/themes/theme_default.less index cfd1264e0c7..0c7510928f5 100644 --- a/addons/mass_mailing/static/src/less/themes/theme_default.less +++ b/addons/mass_mailing/static/src/less/themes/theme_default.less @@ -322,31 +322,11 @@ } } -// ===== 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); +// Compatibility: mb/mt classes on elements were interpreted as paddings +// instead of margins before the introduction of pb/pt classes. As thoses mb/mt +// classes may remain on clients' templates, are forced to 0 margin to +// be sure (normally should not consider margin properties but some mail +// clients might make the mistake to do so). +td[class*="mb"], td[class*="mt"] { + margin: 0!important; } -.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(); diff --git a/addons/mass_mailing/views/snippets_themes_options.xml b/addons/mass_mailing/views/snippets_themes_options.xml index 34d973369e8..50c40473f12 100644 --- a/addons/mass_mailing/views/snippets_themes_options.xml +++ b/addons/mass_mailing/views/snippets_themes_options.xml @@ -5,9 +5,8 @@ -
-
+
@@ -32,13 +31,8 @@ data-drop-in="[data-oe-field='body_html']:not(:has(.o_layout)), .oe_structure">
-
-
- -
-
+
'; } else { - a = ''; + a = ''; } companiesList += '
  • ' + a + company[1] + '
  • '; diff --git a/addons/web_editor/static/src/js/editor/snippets.editor.js b/addons/web_editor/static/src/js/editor/snippets.editor.js index d84a7088fd1..999131020bf 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -74,7 +74,7 @@ var SnippetEditor = Widget.extend({ }, helper: function () { var $clone = $(this).clone().css({width: '24px', height: '24px', border: 0}); - $clone.find('.oe_overlay_options >:not(:contains(.oe_snippet_move)), .oe_handle').remove(); + $clone.find('.oe_overlay_options >:not(:contains(.oe_snippet_move)), .o_handle').remove(); $clone.find(':not(.glyphicon)').css({position: 'absolute', top: 0, left: 0}); $clone.appendTo('body').removeClass('hidden'); return $clone; @@ -123,17 +123,16 @@ var SnippetEditor = Widget.extend({ * Makes the editor overlay cover the associated snippet. */ cover: function () { - var mt = parseInt(this.$target.css('margin-top') || 0); var offset = this.$target.offset(); var manipulatorOffset = this.$el.parent().offset(); - offset.top -= (manipulatorOffset.top + mt); + offset.top -= manipulatorOffset.top; offset.left -= manipulatorOffset.left; this.$el.css({ width: this.$target.outerWidth(), left: offset.left, top: offset.top, }); - this.$('.oe_handles').css('height', this.$target.outerHeight(true)); + this.$('.o_handles').css('height', this.$target.outerHeight()); this.$el.toggleClass('o_top_cover', offset.top < 15); }, /** diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js index 554806454e8..f6011be282d 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -355,7 +355,7 @@ var SnippetOption = Widget.extend({ */ var registry = {}; -registry.marginAndResize = SnippetOption.extend({ +registry.sizing = SnippetOption.extend({ preventChildPropagation: true, /** @@ -363,92 +363,64 @@ registry.marginAndResize = SnippetOption.extend({ */ start: function () { var self = this; - this._super(); + var def = this._super.apply(this, arguments); - 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'); + this.$handles = this.$overlay.find('.o_handle'); + var resizeValues = this._getSize(); + _.each(resizeValues, function (value, key) { + self.$handles.filter('.' + key).toggleClass('readonly', !value); + }); - var $auto_size = this.$overlay.find('.oe_handle.size .auto_size'); - var $fixed_size = this.$overlay.find('.oe_handle.size .size'); + this.$handles.on('mousedown', function (ev) { + ev.preventDefault(); - var auto_sized = isNaN(parseInt(self.$target.prop('style').height)); - $fixed_size.toggleClass('active', !auto_sized); - $auto_size.toggleClass('active', auto_sized); + var $handle = $(ev.currentTarget); - $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')) { + } else if ($handle.hasClass('s')) { compass = 's'; XY = 'Y'; - } - else if ($handle.hasClass('e')) { + } else if ($handle.hasClass('e')) { compass = 'e'; XY = 'X'; - } - else if ($handle.hasClass('w')) { + } else if ($handle.hasClass('w')) { compass = 'w'; XY = 'X'; } - else if ($handle.hasClass('size')) { - compass = 'size'; - XY = 'Y'; + + var resize = resizeValues[compass]; + if (!resize) { + return; } - var resize = resize_values[compass]; - if (!resize) return; + var current = 0; + var cssProperty = resize[2]; + var cssPropertyValue = parseInt(self.$target.css(cssProperty)); + _.each(resize[0], function (val, key) { + if (self.$target.hasClass(val)) { + current = key; + } else if (resize[1][key] === cssPropertyValue) { + 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'); - - if (compass === 'size') { - var offset = self.$target.offset().top; - } 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'); - } - - var cursor = $handle.css('cursor')+'-important'; + 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._onResize(compass, null, dy); - self.trigger_up('cover_update'); - return; - } - var dd = event['page'+XY] - xy + resize[1][begin]; - var next = current+1 === resize[1].length ? current : (current+1); + var xy = ev['page' + XY]; + var body_mousemove = function (ev) { + ev.preventDefault(); + + var dd = ev['page' + XY] - xy + resize[1][begin]; + var next = current + (current+1 === resize[1].length ? 0 : 1); var prev = current ? (current-1) : 0; var change = false; @@ -468,56 +440,54 @@ registry.marginAndResize = SnippetOption.extend({ if (change) { self._onResize(compass, beginClass, current); self.trigger_up('cover_update'); - self._adaptMarginsPreviews(); - $handle.addClass('oe_handle_change'); + $handle.addClass('o_active'); } }; - var body_mouseup = function () { - $body.unbind('mousemove', body_mousemove); - $body.unbind('mouseup', body_mouseup); + $body.off('mousemove', body_mousemove); + $body.off('mouseup', body_mouseup); $body.removeClass(cursor); - setTimeout(function () { - if (begin !== current) { - self.trigger_up('request_history_undo_record', { - $target: self.$target, - event: 'resize_' + XY, - }); - } - },0); - $handle.removeClass('oe_handle_change'); + $handle.removeClass('o_active'); - if (compass === 'size') { - $fixed_size.addClass('active'); - $auto_size.removeClass('active'); - } else { - self._highlightMarginsPreviews(); + // Highlights the previews for a while + var $handlers = self.$overlay.find('.o_handle'); + $handlers.addClass('o_active').delay(300).queue(function () { + $handlers.removeClass('o_active').dequeue(); + }); + + if (begin === current) { + return; } + setTimeout(function () { + self.trigger_up('request_history_undo_record', { + $target: self.$target, + event: 'resize_' + XY, + }); + }, 0); }; - $body.mousemove(body_mousemove); - $body.mouseup(body_mouseup); + $body.on('mousemove', body_mousemove); + $body.on('mouseup', body_mouseup); }); - $auto_size.on('click', function () { - self.$target.css('height', ''); - self.$target.css('overflow', ''); - self.trigger_up('request_history_undo_record', { - $target: self.$target, - event: 'resize_Y', - }); - self.trigger_up('cover_update'); - $fixed_size.removeClass('active'); - $auto_size.addClass('active'); - - return false; - }); + return def; }, /** * @override */ - onFocus : function () { - this._updateCursor(); - this._adaptMarginsPreviews(); + onFocus: function () { + this._onResize(); + }, + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * @override + */ + setTarget: function () { + this._super.apply(this, arguments); + this._onResize(); }, //-------------------------------------------------------------------------- @@ -525,98 +495,72 @@ registry.marginAndResize = SnippetOption.extend({ //-------------------------------------------------------------------------- /** - * Adapts the margin handles to fit the left, top and bottom margins. + * Returns an object mapping one or several cardinal direction (n, e, s, w) + * to an Array containing: + * 1) A list of classes to toggle when using this cardinal direction + * 2) A list of values these classes are supposed to set on a given CSS prop + * 3) The mentioned CSS prop * - * @private - */ - _adaptMarginsPreviews: function () { - var self = this; - var ml = this.$target.css('margin-left'); - _.each(this.$overlay.find(".oe_handle.n, .oe_handle.s"), function (handle) { - var $handle = $(handle); - var direction = $handle.hasClass('n') ? 'top': 'bottom'; - $handle.height(self.$target.css('margin-' + direction)); - }); - this.$overlay.find(".oe_handle.w").css({ - width: ml, - left: '-' + ml, - }); - }, - /** - * Returns an object whose keys indicate the different editable dimensions. + * Note: this object must also be saved in this.grid before being returned. * + * @abstract * @private * @returns {Object} */ - _getSize: function () { - this.grid = {}; - return this.grid; - }, - /** - * Highlights the margins previews for a while. - * - * @private - */ - _highlightMarginsPreviews: function () { - var $handlers = this.$overlay.find(".oe_handle.n, .oe_handle.s, .oe_handle.w"); - $handlers.addClass('oe_handle_active').delay(300).queue(function () { - $handlers.removeClass('oe_handle_active').dequeue(); - }); - }, + _getSize: function () {}, /** * Called when the snippet is being resized and its classes changes. * * @private - * @param {string} compass - resize direction ('n', 's', 'e' or 'w') - * @param {?} beginClass - attributes class at the beginning - * @param {?} current - curent increment in this.grid + * @param {string} [compass] - resize direction ('n', 's', 'e' or 'w') + * @param {string} [beginClass] - attributes class at the beginning + * @param {integer} [current] - current increment in this.grid */ _onResize: function (compass, beginClass, current) { - this._updateCursor(); - }, - /** - * Adapts the resize handles according to the classes and dimensions. - * - * @private - */ - _updateCursor : function () { - var _class = this.$target.attr('class') || ''; - var $handle_s = this.$overlay.find('.oe_handle.s'); - var $handle_n = this.$overlay.find('.oe_handle.n'); - var $handle_w = this.$overlay.find('.oe_handle.w'); + var self = this; - var col = _class.match(/col-md-([0-9-]+)/i); - col = col ? +col[1] : 0; + // Adapt the resize handles according to the classes and dimensions + var resizeValues = this._getSize(); + var $handles = this.$overlay.find('.o_handle'); + _.each(resizeValues, function (resizeValue, direction) { + var classes = resizeValue[0]; + var values = resizeValue[1]; + var cssProperty = resizeValue[2]; - var offset = _class.match(/col-md-offset-([0-9-]+)/i); - offset = offset ? +offset[1] : 0; + var $handle = $handles.filter('.' + direction); - 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'; - $handle_w.toggleClass('oe_handle_centered', offset > 0).toggleClass('o_handle_edited', offset >= 1 ); + var current = 0; + var cssPropertyValue = parseInt(self.$target.css(cssProperty)); + _.each(classes, function (className, key) { + if (self.$target.hasClass(className)) { + current = key; + } else if (values[key] === cssPropertyValue) { + current = key; + } + }); - 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'; - $handle_s.toggleClass('oe_handle_centered', mb >= 32).toggleClass('o_handle_edited', mb > 0 ); + $handle.toggleClass('o_handle_start', current === 0); + $handle.toggleClass('o_handle_end', current === classes.length - 1); + }); - 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'; - $handle_n.toggleClass('oe_handle_centered', mt >= 32).toggleClass('o_handle_edited', mt > 0 ); - - this.$overlay.attr('class', overlay_class); + // Adapt the handles to fit the left, top and bottom sizes + var ml = this.$target.css('margin-left'); + this.$overlay.find('.o_handle.w').css({ + width: ml, + left: '-' + ml, + }); + _.each(this.$overlay.find(".o_handle.n, .o_handle.s"), function (handle) { + var $handle = $(handle); + var direction = $handle.hasClass('n') ? 'top': 'bottom'; + $handle.height(self.$target.css('padding-' + direction)); + }); }, }); /** - * Handles the edition of margin-top and margin-bottom. + * Handles the edition of padding-top and padding-bottom. */ -registry['margin-y'] = registry.marginAndResize.extend({ +registry.sizing_y = registry.sizing.extend({ //-------------------------------------------------------------------------- // Private @@ -626,38 +570,30 @@ registry['margin-y'] = registry.marginAndResize.extend({ * @override */ _getSize: function () { - this.grid = this._super(); - var grid = [0,4,8,16,32,48,64,92,128]; + var nClass = 'pt'; + var nProp = 'padding-top'; + var sClass = 'pb'; + var sProp = 'padding-bottom'; + if (this.$target.is('hr')) { + nClass = 'mt'; + nProp = 'margin-top'; + sClass = 'mb'; + sProp = 'margin-bottom'; + } + + var grid = []; + for (var i = 0 ; i <= 256/8 ; i++) { + grid.push(i * 8); + } + grid.splice(1, 0, 4); 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 + n: [_.map(grid, function (v) { return nClass + v; }), grid, nProp], + s: [_.map(grid, function (v) { return sClass + v; }), grid, sProp], }; return this.grid; }, }); -/** - * Handles the edition of snippet's height. - */ -registry.resize = registry.marginAndResize.extend({ - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * @override - */ - _getSize: function () { - this.grid = this._super(); - this.grid.size = 8; - return this.grid; - }, -}); - /** * Handles the edition of snippet's background color classes. */ diff --git a/addons/web_editor/static/src/less/web_editor.common.less b/addons/web_editor/static/src/less/web_editor.common.less index cfa9f683198..99f6a474397 100644 --- a/addons/web_editor/static/src/less/web_editor.common.less +++ b/addons/web_editor/static/src/less/web_editor.common.less @@ -158,57 +158,75 @@ ul.oe_menu_editor { } } -// Generate all margins for all sizes -.o-margins-all(@factor: 1) { - // Unfortunately, the margins sizes are not - // mathematically related by a single function - .o-margins(128, @factor); - .o-margins(96, @factor); - .o-margins(92, @factor); - .o-margins(64, @factor); - .o-margins(48, @factor); - .o-margins(32, @factor); - .o-margins(24, @factor); - .o-margins(16, @factor); - .o-margins(8, @factor); - .o-margins(4, @factor); - .o-margins(0, @factor); +// Generate all spacings for all sizes +.o-spacing-all(@factor: 1) { + // Generate vertical margin/padding classes used by the editor + .o-generate-spacings(256/8); + .o-generate-spacings(@n, @i: 0) when (@i =< @n) { + .o-vspacing(@i * 8); + .o-generate-spacings(@n, @i + 1); + } + .o-vspacing(4, @factor); + + // 92px vertical margin is kept for compatibility + .o-vmargins(92, @factor); + + // Some horizontal margin classes defined for convenience + // (and compatibility) + .o-hmargins(0, @factor); + .o-hmargins(4, @factor); + .o-hmargins(8, @factor); + .o-hmargins(16, @factor); + .o-hmargins(32, @factor); + .o-hmargins(64, @factor); } -// Generate all margins for one size, scalled by a -// given factor (0 <= factor <= 1) -.o-margins(@name, @factor: 1) { - .o-margins-define(@name, @factor * @name); +// Generate all spacings for one size, scalled by a given factor +// (0 <= factor <= 1) +.o-vspacing(@name, @factor: 1) { + .o-vmargins(@name, @factor); + .o-vpaddings(@name, @factor); +} +.o-vmargins(@name, @factor: 1) { + .o-vmargins-define(@name, @factor * @name); +} +.o-vpaddings(@name, @factor: 1) { + .o-vpaddings-define(@name, @factor * @name); +} +.o-hspacing(@name, @factor: 1) { + .o-hmargins(@name, @factor); + .o-hpaddings(@name, @factor); +} +.o-hmargins(@name, @factor: 1) { + .o-hmargins-define(@name, @factor * @name); +} +.o-hpaddings(@name, @factor: 1) { + .o-hpaddings-define(@name, @factor * @name); } -// Generate all margins for one size, given -// the name of the margin and intended size -.o-margins-define(@name, @size: @name) { - .mt@{name} {margin-top: ~"@{size}px"!important;} - .mb@{name} {margin-bottom: ~"@{size}px"!important;} - .ml@{name} {margin-left: ~"@{size}px"!important;} - .mr@{name} {margin-right: ~"@{size}px"!important;} +// Generate all spacings for one size, given the name of the spacing and +// intended size +.o-vmargins-define(@name, @size: @name) { + .mt@{name} { margin-top: unit(@size, px)!important; } + .mb@{name} { margin-bottom: unit(@size, px)!important; } +} +.o-vpaddings-define(@name, @size: @name) { + .pt@{name} { padding-top: unit(@size, px)!important; } + .pb@{name} { padding-bottom: unit(@size, px)!important; } +} +.o-hmargins-define(@name, @size: @name) { + .ml@{name} { margin-left: unit(@size, px)!important; } + .mr@{name} { margin-right: unit(@size, px)!important; } +} +.o-hpaddings-define(@name, @size: @name) { + .pl@{name} { padding-left: unit(@size, px)!important; } + .pr@{name} { padding-right: unit(@size, px)!important; } } // Generate all margins -.o-margins-all(); - -// Possibility to change the margins ratio for small screen sizes, e.g.: -// @media (max-width: 768px) { -// .o-margins-all(0.75); -// } -// Possibility to only redefine single margins for small screen sizes, e.g.: -// @media (max-width: 768px) { -// .o-margins(64, 0.50); -// .o-margins(48, 0.50); -// } -// Possibility to directly redefine the size of single margins instead of refering to a factor for small screen sizes, e.g.: -// @media (max-width: 768px) { -// .o-margins-define(128, 48); -// .o-margins-define(96, 48); -// .o-margins-define(64, 48); -// } +.o-spacing-all(); +// Underline a.o_underline { text-decoration: underline; &:hover { diff --git a/addons/web_editor/static/src/less/web_editor.ui.less b/addons/web_editor/static/src/less/web_editor.ui.less index 1d59c4e2033..e7ba19f332d 100644 --- a/addons/web_editor/static/src/less/web_editor.ui.less +++ b/addons/web_editor/static/src/less/web_editor.ui.less @@ -539,62 +539,43 @@ html[lang] > body.editor_enable [data-oe-translation-state] { } // HANDLES - > .oe_handles { + > .o_handles { @o-handles-offset-to-hide: 10000px; @o-handless-accent-color: #00e2ff; .o-position-absolute(-@o-handles-offset-to-hide, 0, auto, 0); - &:hover > .oe_handle { + &:hover > .o_handle { background-color: fade(@o-handless-accent-color, 5%); } - > .oe_handle { + > .o_handle { @o-handle-btn-size: 18px; - opacity: 0.5; - .o-transition(opacity, 400ms); + + position: relative; border: 0 solid @o-handless-accent-color; + .o-transition(background, 300ms); - // MARGINS PREVIEW - &.n, &.s, &.w { - position: relative; - .o-transition(background, 0.3s); + &:hover, &.o_active { + background-color: fade(@o-handless-accent-color, 20%); - &.oe_handle_change, &.oe_handle_active, &:hover { - background-color: fade(@o-handless-accent-color, 20%); + &:before { + content: ''; + .o-position-absolute(0, @left:50%); + width: 1px; + height: 100%; + margin-left: -1px; + background-color: fade(@o-handless-accent-color, 50%); } - &.o_handle_edited { - opacity: 0.9; - - &:after { - color: white; - border-color: darken(@o-handless-accent-color, 10%); - background-color: darken(@o-handless-accent-color, 20%); - } + &.w:before { + .o-position-absolute(50%, @left: 0); + width: 100%; + height: 1px; } - &.oe_handle_change, &:hover { - opacity: 1; - - &:before { - .o-position-absolute(0, @left:50%); - width: 1px; - height: 100%; - margin-left: -1px; - background-color: fade(@o-handless-accent-color, 50%); - content:''; - } - - &.w:before { - .o-position-absolute(50%,@left: 0); - width: 100%; - height: 1px; - } - - &:after { - border-color: darken(@o-handless-accent-color, 10%); - background-color: darken(@o-handless-accent-color, 20%); - } + &:after { + border-color: darken(@o-handless-accent-color, 10%); + background-color: darken(@o-handless-accent-color, 20%); } } @@ -602,17 +583,13 @@ html[lang] > body.editor_enable [data-oe-translation-state] { display: block; width: @o-handle-btn-size; height: @o-handle-btn-size; - border: solid 1px rgba(0, 0, 0, 0.2); + border: solid 1px darken(@o-handless-accent-color, 10%); line-height: @o-handle-btn-size - 2; font-size: 14px; font-family: FontAwesome; - background-color: @o-we-color-light; - color: @o-we-color-text-light; + background-color: darken(@o-handless-accent-color, 20%); + color: white; } - &:hover { - opacity: 0.9; - } - &.w:after, &.e:after { content: "\f07e"; } @@ -620,107 +597,72 @@ html[lang] > body.editor_enable [data-oe-translation-state] { content: "\f07d"; } + &.o_handle_start { + &.w:after, &.e:after { + content: '\f061'; + } + &.n:after, &.s:after { + content: '\f063'; + } + } + &.o_handle_end { + &.w:after, &.e:after { + content: '\f060'; + } + &.n:after, &.s:after { + content: '\f062'; + } + } + &.w { + .o-position-absolute(@o-handles-offset-to-hide, auto, -@o-handles-offset-to-hide, 0); + width: @odoo-handle-edge-size; border-width: @odoo-handle-border-width; border-right-width: 0; cursor: e-resize; - width: @odoo-handle-edge-size; - .o-position-absolute(@o-handles-offset-to-hide, auto, -@o-handles-offset-to-hide, 0); &:after { - .o-position-absolute(@top: 50%, @left: 50%); + .o-position-absolute(@top: 50%, @left: 40%); margin-top: -@o-handle-btn-size/2; } - &.oe_handle_centered:after { - margin-left: -@o-handle-btn-size/2; - } } &.e { + .o-position-absolute(@o-handles-offset-to-hide, 0, -@o-handles-offset-to-hide, auto); + width: @odoo-handle-edge-size; border-right-width: @odoo-handle-border-width; cursor: w-resize; - width: @odoo-handle-edge-size; - .o-position-absolute(@o-handles-offset-to-hide, 0, -@o-handles-offset-to-hide, auto); &:after { - .o-position-absolute(@top: 50%, @right: -@odoo-handle-border-width); + .o-position-absolute(@top: 50%, @right: 40%); margin-top: -@o-handle-btn-size/2; } } &.n { - border-top-width: @odoo-handle-border-width; .o-position-absolute(@o-handles-offset-to-hide, 0, auto, 0); + border-top-width: @odoo-handle-border-width; + cursor: ns-resize; &:after { - .o-position-absolute(@left: 50%, @top: 50%); + .o-position-absolute(@left: 50%, @top: 40%); margin-left: -@o-handle-btn-size/2; } } &.s { - border-bottom-width: @odoo-handle-border-width; .o-position-absolute(auto, 0, -@o-handles-offset-to-hide, 0); - - &:after { - .o-position-absolute(@left: 50%, @bottom: 50%); - margin-left: -@o-handle-btn-size/2; - } - } - &.n, &.s { + border-bottom-width: @odoo-handle-border-width; cursor: ns-resize; - &.oe_handle_centered:after { - .o-position-absolute(@left: 50%, @top: 50%); - margin-top: -@o-handle-btn-size/2; - } - } - - // SIZE HANDLERS - &.size { - @o-handle-size-height: 15px; - - height: 0; - background: transparent; - .o-position-absolute(@bottom: -@o-handles-offset-to-hide + @o-handle-size-height, @left: 50%); - width: 250px; - margin-left: -125px; - - > .oe_handle_button { - position: relative; - display: block; - width: 100px; - height: @o-handle-size-height; - padding-top: 2px; - font-weight: 600; - font-size: 9px; - text-transform: uppercase; - background-color: @o-we-color-light; - color: @o-we-color-text-light; - &:hover { - background-color: @o-we-color-dark; - color: white; - } - &.auto_size { - cursor: pointer; - float: left; - } - &.size { - cursor: row-resize; - float: right; - } - &.active:before { - content: "\f00c"; - font-family: "FontAwesome"; - color: @odoo-brand-optional; - .o-position-absolute(@top: 0, @left: 3px); - font-size: 11px; - } + &:after { + .o-position-absolute(@left: 50%, @bottom: 40%); + margin-left: -@o-handle-btn-size/2; } } &.readonly { - cursor: auto !important; + cursor: auto!important; - &:after, &.size { - display: none !important; + &:after { + display: none!important; } &:hover { opacity: 0.5; @@ -728,38 +670,6 @@ html[lang] > body.editor_enable [data-oe-translation-state] { } } } - - // HANDLERS ICONS - &.block-w-left .w:after { - content: "" !important; - } - &.block-w-right .w:after { - content: "" !important; - } - &.block-w-left.block-w-right .w:after { - display: none !important; - } - &.block-e-left .e:after { - content: "" !important; - } - &.block-e-right .e:after { - content: "" !important; - } - &.block-e-left.block-e-right .e:after { - display: none !important; - } - &.block-s-bottom .s, &.block-n-top .n { - cursor: n-resize!important; - &:after { - content: "\f062" !important; - } - } - &.block-s-top .s, &.block-n-bottom .n { - cursor: s-resize!important; - &:after { - content: "\f063" !important; - } - } } } @@ -779,17 +689,6 @@ html[lang] > body.editor_enable [data-oe-translation-state] { cursor: move !important; } -.block-s-top .s, -.block-s-bottom .s, -.block-n-top .n, -.block-n-bottom .n, -.block-w-left .w, -.block-e-right .e { - &:before { - font-size: 10px; - } -} - // NOTE EDITOR .note-popover .popover { height: @odoo-navbar-height; diff --git a/addons/web_editor/static/src/xml/snippets.xml b/addons/web_editor/static/src/xml/snippets.xml index ccf56129ad1..594a7615951 100644 --- a/addons/web_editor/static/src/xml/snippets.xml +++ b/addons/web_editor/static/src/xml/snippets.xml @@ -2,15 +2,11 @@
    -
    -
    -
    -
    -
    -
    -
    Auto size
    -
    Fixed size
    -
    +
    +
    +
    +
    +
    diff --git a/addons/website/static/src/js/content/snippets.animation.js b/addons/website/static/src/js/content/snippets.animation.js index 3556ebd8fc7..d7c29359b95 100644 --- a/addons/website/static/src/js/content/snippets.animation.js +++ b/addons/website/static/src/js/content/snippets.animation.js @@ -431,6 +431,23 @@ registry.slider = Animation.extend({ * @override */ start: function () { + if (!this.editableMode) { + var maxHeight = 0; + var $items = this.$('.item'); + _.each($items, function (el) { + var $item = $(el); + var isActive = $item.hasClass('active'); + $item.addClass('active'); + var height = $item.outerHeight(); + if (height > maxHeight) { + maxHeight = height; + } + $item.toggleClass('active', isActive); + }); + _.each($items, function (el) { + $(el).css('min-height', maxHeight); + }); + } this.$target.carousel(); return this._super.apply(this, arguments); }, @@ -441,6 +458,9 @@ registry.slider = Animation.extend({ this._super.apply(this, arguments); this.$target.carousel('pause'); this.$target.removeData('bs.carousel'); + _.each(this.$('.item'), function (el) { + $(el).css('min-height', ''); + }); }, }); diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js index e0dced9caa1..7601dea6b6c 100644 --- a/addons/website/static/src/js/editor/snippets.options.js +++ b/addons/website/static/src/js/editor/snippets.options.js @@ -122,12 +122,11 @@ options.registry.carousel = options.Class.extend({ this.$target.on('slid.bs.carousel', function () { self.$target.carousel('pause'); self.trigger_up('option_update', { - optionNames: ['background', 'background_position', 'colorpicker'], + optionNames: ['background', 'background_position', 'colorpicker', 'sizing_y'], name: 'target', data: self.$target.find('.item.active'), }); }); - this.$target.trigger('slid.bs.carousel'); return def; }, @@ -143,6 +142,14 @@ options.registry.carousel = options.Class.extend({ this.$target.find('[data-target]').attr('data-target', '#' + this.id); this._rebindEvents(); }, + /** + * @override + */ + onFocus: function () { + // Needs to be done on focus, not on start, as all other options are + // maybe not all initialized in start + this.$target.trigger('slid.bs.carousel'); + }, /** * Associates unique ID on cloned slider elements. * @@ -161,7 +168,7 @@ options.registry.carousel = options.Class.extend({ this._super.apply(this, arguments); this.$target.find('.item').removeClass('next prev left right active') .first().addClass('active'); - this.$target.find('.carousel-indicators').find('li').removeClass('active') + this.$target.find('.carousel-indicators').find('li').removeClass('active').html('') .first().addClass('active'); this.$target.removeClass('oe_img_bg ' + this._class).css('background-image', ''); }, @@ -262,9 +269,7 @@ options.registry.carousel = options.Class.extend({ }, }); -options.registry['margin-x'] = options.registry.marginAndResize.extend({ - preventChildPropagation: true, - +options.registry.sizing_x = options.registry.sizing.extend({ /** * @override */ @@ -286,15 +291,13 @@ options.registry['margin-x'] = options.registry.marginAndResize.extend({ * @override */ _getSize: function () { - this.grid = this._super(); - var width = this.$target.parents('.row:first').first().outerWidth(); - - var grid = [1,2,3,4,5,6,7,8,9,10,11,12]; - this.grid.e = [_.map(grid, function (v) {return 'col-md-'+v;}), _.map(grid, function (v) {return width/12*v;})]; - - grid = [-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11]; - this.grid.w = [_.map(grid, function (v) {return 'col-md-offset-'+v;}), _.map(grid, function (v) {return width/12*v;}), 12]; - + var width = this.$target.closest('.row').width(); + var gridE = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; + var gridW = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; + this.grid = { + e: [_.map(gridE, function (v) { return 'col-md-' + v; }), _.map(gridE, function (v) { return width/12*v; }), 'width'], + w: [_.map(gridW, function (v) { return 'col-md-offset-' + v; }), _.map(gridW, function (v) { return width/12*v; }), 'margin-left'], + }; return this.grid; }, /** @@ -321,7 +324,7 @@ options.registry['margin-x'] = options.registry.marginAndResize.extend({ this.$target.addClass('col-md-offset-' + offset); } } - this._super(compass, beginClass, current); + this._super.apply(this, arguments); }, }); diff --git a/addons/website/static/src/less/website.snippets.less b/addons/website/static/src/less/website.snippets.less index 59cbc47b9dc..388a7180d96 100644 --- a/addons/website/static/src/less/website.snippets.less +++ b/addons/website/static/src/less/website.snippets.less @@ -436,9 +436,6 @@ div.carousel { background-attachment: fixed; } } -.s_parallax { - min-height: 200px; -} // Company Team diff --git a/addons/website/views/snippets.xml b/addons/website/views/snippets.xml index 6867b32ae2c..54c0c6a047c 100644 --- a/addons/website/views/snippets.xml +++ b/addons/website/views/snippets.xml @@ -1,10 +1,10 @@