[REF] website, web_editor: refactor (quotes) carousel snippets

Previously, the carousel and quotes carousel snippets were the only ones
that were not enclosed in section blocks. This had a number of
undesirable side effects, such as editing the anchor on the carousel
breaking the carousel functionality, and the inability to separately
choose a background for the carousel itself and individual slides.

I also used this opportunity to move controls relative to the entire
carousel onto the carousel itself rather than the individual slides. The
sizing_y (vertical padding) will however keep targeting individual
slides, as the carousel uses the height of its tallest slide, and also
because padding on the carousel will not get covered by slide
backgrounds and saty blank, which is unwanted.

Lastly, most of the snippet options for the carousel were rewritten, as
they were quite broken. There was some compatibility code for saas-3
left, some useless events were bound to the controls, even though they
were already handled through event-delegation at the document level.
Finally, most of the edition features were broken on duplicated
carousels since the onClone method wasn't reassigning most of the things
it needed to.

Part of https://github.com/odoo/odoo/pull/38997
task-2090180
This commit is contained in:
Samuel Degueldre
2019-11-06 12:26:27 +00:00
committed by qsm-odoo
parent aa62e95718
commit 958c850f9f
4 changed files with 212 additions and 241 deletions
@@ -593,6 +593,7 @@ registry.sizing = SnippetOption.extend({
var direction = $handle.hasClass('n') ? 'top': 'bottom';
$handle.height(self.$target.css('padding-' + direction));
});
this.$target.trigger('content_changed');
},
});
@@ -430,18 +430,17 @@ registry.slider = publicWidget.Widget.extend({
selector: '.carousel',
disabledInEditableMode: false,
edit_events: {
'slid.bs.carousel': '_onEditionSlide',
'content_changed': '_onContentChanged',
},
/**
* @override
*/
start: function () {
if (!this.editableMode) {
this.$('img').on('load.slider', this._onImageLoaded.bind(this));
this._computeHeights();
}
this.$target.carousel();
this.$('img').on('load.slider', () => this._computeHeights());
this._computeHeights();
// Initialize carousel and pause if in edit mode.
this.$target.carousel(this.editableMode ? 'pause' : undefined);
return this._super.apply(this, arguments);
},
/**
@@ -467,6 +466,7 @@ registry.slider = publicWidget.Widget.extend({
_computeHeights: function () {
var maxHeight = 0;
var $items = this.$('.carousel-item');
$items.css('min-height', '');
_.each($items, function (el) {
var $item = $(el);
var isActive = $item.hasClass('active');
@@ -477,9 +477,7 @@ registry.slider = publicWidget.Widget.extend({
}
$item.toggleClass('active', isActive);
});
_.each($items, function (el) {
$(el).css('min-height', maxHeight);
});
$items.css('min-height', maxHeight);
},
//--------------------------------------------------------------------------
@@ -489,13 +487,7 @@ registry.slider = publicWidget.Widget.extend({
/**
* @private
*/
_onEditionSlide: function () {
this._computeHeights();
},
/**
* @private
*/
_onImageLoaded: function () {
_onContentChanged: function (ev) {
this._computeHeights();
},
});
@@ -225,69 +225,46 @@ options.registry.carousel = options.Class.extend({
* @override
*/
start: function () {
var self = this;
this.$target.carousel({interval: false});
this.id = this.$target.attr('id');
this.$inner = this.$target.find('.carousel-inner');
this.$indicators = this.$target.find('.carousel-indicators');
this.$target.carousel('pause');
this._rebindEvents();
this.$indicators = this.$target.find('.carousel-indicators');
this.$controls = this.$target.find('.carousel-control-prev, .carousel-control-next, .carousel-indicators');
this.$items = this.$target.find('.carousel-item');
this.$target.on('slid.bs.carousel.carousel_option', () => this._retargetEdition());
var def = this._super.apply(this, arguments);
// set background and prepare to clean for save
this.$target.on('slid.bs.carousel', function () {
self.$target.carousel('pause');
self.trigger_up('option_update', {
optionNames: ['background', 'background_position', 'colorpicker', 'sizing_y'],
name: 'target',
data: self.$target.find('.carousel-item.active'),
});
});
return def;
return this._super.apply(this, arguments);
},
/**
* @override
*/
destroy: function () {
this._super.apply(this, arguments);
this.$target.off('.carousel_option');
},
/**
* Associates unique ID on slider elements.
*
* @override
*/
onBuilt: function () {
this.id = 'myCarousel' + new Date().getTime();
this.$target.attr('id', this.id);
this.$target.find('[data-target]').attr('data-target', '#' + this.id);
this._rebindEvents();
this._assignUniqueID();
},
/**
* @override
*/
onClone: function () {
this._assignUniqueID();
},
/**
* @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.
*
* @override
*/
onClone: function () {
var id = 'myCarousel' + new Date().getTime();
this.$target.attr('id', id);
this.$target.find('[data-slide]').attr('href', '#' + id);
this.$target.find('[data-slide-to]').attr('data-target', '#' + id);
this._retargetEdition();
},
/**
* @override
*/
cleanForSave: function () {
this._super.apply(this, arguments);
this.$target.find('.carousel-item').removeClass('next prev left right active')
.first().addClass('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', '');
this.$items.removeClass('next prev left right active').first().addClass('active');
this.$indicators.find('li').removeClass('active').empty().first().addClass('active');
},
//--------------------------------------------------------------------------
@@ -300,18 +277,18 @@ options.registry.carousel = options.Class.extend({
* @see this.selectClass for parameters
*/
addSlide: function (previewMode) {
var self = this;
var cycle = this.$inner.find('.carousel-item').length;
var $active = this.$inner.find('.carousel-item.active, .carousel-item.prev, .carousel-item.next').first();
var index = $active.index();
this.$('.carousel-control-prev, .carousel-control-next, .carousel-indicators').removeClass('d-none');
this.$indicators.append('<li data-target="#' + this.id + '" data-slide-to="' + cycle + '"></li>');
var $clone = $active.clone(true);
$clone.removeClass('active').insertAfter($active);
_.defer(function () {
self.$target.carousel().carousel(++index);
self._rebindEvents();
});
this.$controls.removeClass('d-none');
this.$indicators.append($('<li>', {
'data-target': '#' + this.$target.attr('id'),
'data-slide-to': this.$items.length,
}));
// Need to remove editor data from the clone so it gets its own.
const $active = this.$items.filter('.active');
$active.clone(false)
.removeClass('active')
.insertAfter($active);
this.$items = this.$target.find('.carousel-item');
this.$target.carousel('next');
},
/**
* Removes the current slide.
@@ -319,33 +296,19 @@ options.registry.carousel = options.Class.extend({
* @see this.selectClass for parameters.
*/
removeSlide: function (previewMode) {
if (this.remove_process) {
return;
}
var self = this;
var $items = this.$inner.find('.carousel-item');
var cycle = $items.length - 1;
var $active = $items.filter('.active');
var index = $active.index();
if (cycle > 0) {
this.remove_process = true;
this.$target.on('slid.bs.carousel.slide_removal', function (event) {
$active.remove();
self.$indicators.find('li:last').remove();
self.$target.off('slid.bs.carousel.slide_removal');
self._rebindEvents();
self.remove_process = false;
if (cycle === 1) {
self.$target.find('.carousel-control-prev, .carousel-control-next, .carousel-indicators').addClass('d-none');
}
});
_.defer(function () {
self._refreshPublicWidgets();
self.$target.carousel(index > 0 ? --index : cycle);
const newLength = this.$items.length - 1;
if (!this.removing && newLength > 0) {
const $toDelete = this.$items.filter('.active');
this.$target.one('slid.bs.carousel', (event) => {
$toDelete.remove();
this.$indicators.find('li:last').remove();
this.$items = this.$target.find('.carousel-item');
this.$controls.toggleClass('d-none', newLength === 1);
this.$target.find('.carousel').trigger('content_changed');
this.removing = false;
});
this.removing = true;
this.$target.carousel('prev');
}
},
/**
@@ -366,25 +329,33 @@ options.registry.carousel = options.Class.extend({
*/
_setActive: function () {
this._super.apply(this, arguments);
this.$el.find('[data-interval]').removeClass('active')
.filter('[data-interval=' + this.$target.attr('data-interval') + ']').addClass('active');
this.$el.find('[data-interval]')
.removeClass('active')
.filter(`[data-interval=${this.$target.attr('data-interval')}]`)
.addClass('active');
},
/**
* Rebinds carousel events on indicators.
* Activates current slide for edition and vertical padding. Padding on the
* carousel itself would mean the slides' backgrounds don't cover the padding.
*
* @private
*/
_rebindEvents: function () {
var self = this;
this.$target.find('.carousel-control-prev, .carousel-control-next').off('click').on('click', function () {
self.$target.carousel($(this).data('slide'));
_retargetEdition: function () {
this.trigger_up('activate_snippet', {
$snippet: this.$items.filter('.active'),
ifInactiveOptions: true,
});
this.$target.find('.carousel-indicators [data-slide-to]').off('click').on('click', function () {
self.$target.carousel(+$(this).data('slide-to'));
});
/* Fix: backward compatibility saas-3 */
this.$target.find('.item.text_image, .item.image_text, .item.text_only').find('.container > .carousel-caption > div, .container > img.carousel-image').attr('contentEditable', 'true');
},
/**
* Creates a unique ID for the carousel and reassign data-attributes that depend on it.
*
* @private
*/
_assignUniqueID: function () {
const id = 'myCarousel' + Date.now();
this.$target.attr('id', id);
this.$target.find('[data-target]').attr('data-target', '#' + id);
this.$target.find('[data-slide]').attr('href', '#' + id);
},
});
+136 -129
View File
@@ -198,76 +198,78 @@
</template>
<template id="s_carousel" name="Carousel">
<div id="myCarousel" class="s_carousel s_carousel_default carousel slide" data-interval="10000">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"/>
<li data-target="#myCarousel" data-slide-to="1"/>
<li data-target="#myCarousel" data-slide-to="2"/>
</ol>
<!-- Content -->
<div class="carousel-inner">
<!-- #01 -->
<div class="carousel-item active oe_custom_bg oe_img_bg pt152 pb152" style="background-image: url('/web/image/website.s_carousel_default_image_1');" data-name="Slide">
<div class="container">
<div class="row content">
<div class="carousel-content col-lg-7">
<div class="s_title pb8" data-name="Title">
<h2 class="s_title_default"><font style="font-size: 62px;">Slide Title</font></h2>
<section class="s_carousel_wrapper">
<div id="myCarousel" class="s_carousel s_carousel_default carousel slide" data-interval="10000">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"/>
<li data-target="#myCarousel" data-slide-to="1"/>
<li data-target="#myCarousel" data-slide-to="2"/>
</ol>
<!-- Content -->
<div class="carousel-inner">
<!-- #01 -->
<div class="carousel-item active oe_custom_bg oe_img_bg pt152 pb152" style="background-image: url('/web/image/website.s_carousel_default_image_1');" data-name="Slide">
<div class="container">
<div class="row content">
<div class="carousel-content col-lg-7">
<div class="s_title pb8" data-name="Title">
<h2 class="s_title_default"><font style="font-size: 62px;">Slide Title</font></h2>
</div>
<p class="lead">Use this snippet to presents your content in a slideshow-like format.<br/> Don't write about products or services here, write about solutions.</p>
<div class="s_btn text-left pt16 pb16" data-name="Buttons">
<a href="/aboutus" class="btn btn-secondary flat">About us</a>
<a href="/contactus" class="btn btn-primary flat">Contact us</a>
</div>
</div>
<p class="lead">Use this snippet to presents your content in a slideshow-like format.<br/> Don't write about products or services here, write about solutions.</p>
<div class="s_btn text-left pt16 pb16" data-name="Buttons">
<a href="/aboutus" class="btn btn-secondary flat">About us</a>
<a href="/contactus" class="btn btn-primary flat">Contact us</a>
</div>
</div>
</div>
<!-- #02 -->
<div class="carousel-item oe_custom_bg oe_img_bg pt96 pb96" style="background-image: url('/web/image/website.s_carousel_default_image_2');" data-name="Slide">
<div class="container">
<div class="row content">
<div class="carousel-content col-lg-8 offset-lg-2 bg-black-50 text-center pt48 pb40">
<h2 style="font-size: 62px;">Clever Slogan</h2>
<div class="s_hr pt8 pb32">
<hr class="s_hr_5px s_hr_dotted border-600 w-25 border-epsilon mx-auto text-center"/>
</div>
<p class="lead">Storytelling is powerful.<br/> It draws readers in and engages them.</p>
<div class="s_btn text-center pt16 pb16" data-name="Buttons">
<a href="/" class="btn btn-epsilon rounded-circle">Start your journey</a>
</div>
</div>
</div>
</div>
</div>
<!-- #03 -->
<div class="carousel-item oe_custom_bg oe_img_bg pt128 pb128" style="background-image: url('/web/image/website.s_carousel_default_image_3');" data-name="Slide">
<div class="container">
<div class="row content">
<div class="carousel-content col-lg-6 offset-lg-6">
<h2><font style="font-size: 62px; background-color: rgb(255, 255, 255);">Edit this title</font></h2>
<h4><font style="background-color: rgb(255, 255, 255);">Good writing is simple, but not simplistic.</font></h4>
<p class="mt24">Good copy starts with understanding how your product or service helps your customers. Simple words communicate better than big words and pompous language.</p>
<t t-call="website.s_share">
<t t-set="_classes" t-value="'text-left pt16 pb16'"/>
<t t-set="_no_title" t-value="True"/>
</t>
</div>
</div>
</div>
</div>
</div>
<!-- #02 -->
<div class="carousel-item oe_custom_bg oe_img_bg pt96 pb96" style="background-image: url('/web/image/website.s_carousel_default_image_2');" data-name="Slide">
<div class="container">
<div class="row content">
<div class="carousel-content col-lg-8 offset-lg-2 bg-black-50 text-center pt48 pb40">
<h2 style="font-size: 62px;">Clever Slogan</h2>
<div class="s_hr pt8 pb32">
<hr class="s_hr_5px s_hr_dotted border-600 w-25 border-epsilon mx-auto text-center"/>
</div>
<p class="lead">Storytelling is powerful.<br/> It draws readers in and engages them.</p>
<div class="s_btn text-center pt16 pb16" data-name="Buttons">
<a href="/" class="btn btn-epsilon rounded-circle">Start your journey</a>
</div>
</div>
</div>
</div>
</div>
<!-- #03 -->
<div class="carousel-item oe_custom_bg oe_img_bg pt128 pb128" style="background-image: url('/web/image/website.s_carousel_default_image_3');" data-name="Slide">
<div class="container">
<div class="row content">
<div class="carousel-content col-lg-6 offset-lg-6">
<h2><font style="font-size: 62px; background-color: rgb(255, 255, 255);">Edit this title</font></h2>
<h4><font style="background-color: rgb(255, 255, 255);">Good writing is simple, but not simplistic.</font></h4>
<p class="mt24">Good copy starts with understanding how your product or service helps your customers. Simple words communicate better than big words and pompous language.</p>
<t t-call="website.s_share">
<t t-set="_classes" t-value="'text-left pt16 pb16'"/>
<t t-set="_no_title" t-value="True"/>
</t>
</div>
</div>
</div>
</div>
<!-- Controls -->
<a class="carousel-control-prev" href="#myCarousel" data-slide="prev" role="img" aria-label="Previous" title="Previous">
<span class="carousel-control-prev-icon"/>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#myCarousel" data-slide="next" role="img" aria-label="Next" title="Next">
<span class="carousel-control-next-icon"/>
<span class="sr-only">Next</span>
</a>
</div>
<!-- Controls -->
<div class="carousel-control-prev" data-target="#myCarousel" data-slide="prev" role="img" aria-label="Previous" title="Previous">
<span class="carousel-control-prev-icon"/>
<span class="sr-only">Previous</span>
</div>
<div class="carousel-control-next" data-target="#myCarousel" data-slide="next" role="img" aria-label="Next" title="Next">
<span class="carousel-control-next-icon"/>
<span class="sr-only">Next</span>
</div>
</div>
</section>
</template>
<template id="s_alert" name="Alert">
@@ -750,69 +752,71 @@
</template>
<template id="s_quotes_carousel" name="Quotes">
<div id="myQuoteCarousel" class="s_quotes_carousel s_carousel_default carousel slide" data-interval="10000">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#myQuoteCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myQuoteCarousel" data-slide-to="1"></li>
<li data-target="#myQuoteCarousel" data-slide-to="2"></li>
</ol>
<!-- Content -->
<div class="carousel-inner">
<!-- #01 -->
<div class="carousel-item active bg-200 pt80 pb80" data-name="Slide">
<div class="container">
<div class="row content">
<blockquote class="carousel-content col-lg-6 bg-white offset-lg-3">
<i class="fa fa-1x fa-quote-left rounded-0 bg-secondary s_quotes_carousel_icon"/>
<p>Write a quote here from one of your customers. Quotes are a great way to build confidence in your products or services.</p>
<footer>
<img class="img" src="/web/image/website.s_quotes_carousel_demo_image_3" alt=""/>
<span>— Jane DOE, CEO of <b>MyCompany</b></span>
</footer>
</blockquote>
<section class="s_quotes_carousel_wrapper">
<div id="myQuoteCarousel" class="s_quotes_carousel s_carousel_default carousel slide" data-interval="10000">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#myQuoteCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myQuoteCarousel" data-slide-to="1"></li>
<li data-target="#myQuoteCarousel" data-slide-to="2"></li>
</ol>
<!-- Content -->
<div class="carousel-inner">
<!-- #01 -->
<div class="carousel-item active bg-200 pt80 pb80" data-name="Slide">
<div class="container">
<div class="row content">
<blockquote class="carousel-content col-lg-6 bg-white offset-lg-3">
<i class="fa fa-1x fa-quote-left rounded-0 bg-secondary s_quotes_carousel_icon"/>
<p>Write a quote here from one of your customers. Quotes are a great way to build confidence in your products or services.</p>
<footer>
<img class="img" src="/web/image/website.s_quotes_carousel_demo_image_3" alt=""/>
<span>— Jane DOE, CEO of <b>MyCompany</b></span>
</footer>
</blockquote>
</div>
</div>
</div>
<!-- #02 -->
<div class="carousel-item oe_img_bg pt80 pb80" style="background-image: url('/web/image/website.s_quotes_carousel_demo_image_1'); background-position: 50% 50%;" data-name="Slide">
<div class="container">
<div class="row content">
<blockquote class="col-lg-6 bg-white">
<p>Odoo provides essential platform for our project management. Things are better organized and more visible with it.</p>
<footer>
<img class="img" src="/web/image/website.s_quotes_carousel_demo_image_4" alt=""/>
<span>— John DOE, CEO of <b>MyCompany</b></span>
</footer>
</blockquote>
</div>
</div>
</div>
<!-- #03 -->
<div class="carousel-item oe_img_bg pt80 pb80" style="background-image: url('/web/image/website.s_quotes_carousel_demo_image_2'); background-position: 50% 50%;" data-name="Slide">
<div class="container">
<div class="row content">
<blockquote class="col-lg-6 offset-lg-6 bg-white">
<p>Odoo provides essential platform for our project management. Things are better organized and more visible with it.</p>
<footer class="blockquote-footer">
<img class="img" src="/web/image/website.s_quotes_carousel_demo_image_5" alt=""/>
<span>— Jane DOE, CEO of <b>MyCompany</b></span>
</footer>
</blockquote>
</div>
</div>
</div>
</div>
<!-- #02 -->
<div class="carousel-item oe_img_bg pt80 pb80" style="background-image: url('/web/image/website.s_quotes_carousel_demo_image_1'); background-position: 50% 50%;" data-name="Slide">
<div class="container">
<div class="row content">
<blockquote class="col-lg-6 bg-white">
<p>Odoo provides essential platform for our project management. Things are better organized and more visible with it.</p>
<footer>
<img class="img" src="/web/image/website.s_quotes_carousel_demo_image_4" alt=""/>
<span>— John DOE, CEO of <b>MyCompany</b></span>
</footer>
</blockquote>
</div>
</div>
<!-- Controls -->
<div class="carousel-control-prev" data-target="#myQuoteCarousel" data-slide="prev" role="img" aria-label="Previous" title="Previous">
<span class="carousel-control-prev-icon"/>
<span class="sr-only">Previous</span>
</div>
<!-- #03 -->
<div class="carousel-item oe_img_bg pt80 pb80" style="background-image: url('/web/image/website.s_quotes_carousel_demo_image_2'); background-position: 50% 50%;" data-name="Slide">
<div class="container">
<div class="row content">
<blockquote class="col-lg-6 offset-lg-6 bg-white">
<p>Odoo provides essential platform for our project management. Things are better organized and more visible with it.</p>
<footer class="blockquote-footer">
<img class="img" src="/web/image/website.s_quotes_carousel_demo_image_5" alt=""/>
<span>— Jane DOE, CEO of <b>MyCompany</b></span>
</footer>
</blockquote>
</div>
</div>
<div class="carousel-control-next" data-target="#myQuoteCarousel" data-slide="next" role="img" aria-label="Next" title="Next">
<span class="carousel-control-next-icon"/>
<span class="sr-only">Next</span>
</div>
</div>
<!-- Controls -->
<div class="carousel-control-prev" data-target="#myQuoteCarousel" data-slide="prev" role="img" aria-label="Previous" title="Previous">
<span class="carousel-control-prev-icon"/>
<span class="sr-only">Previous</span>
</div>
<div class="carousel-control-next" data-target="#myQuoteCarousel" data-slide="next" role="img" aria-label="Next" title="Next">
<span class="carousel-control-next-icon"/>
<span class="sr-only">Next</span>
</div>
</div>
</section>
</template>
<!-- Mega menu snippets -->
@@ -1147,7 +1151,8 @@
<!-- Carousel | .s_carousel | .s_quotes_carousel -->
<div data-js="carousel"
data-selector=":not(.o_gallery > .container) > .carousel">
data-selector="section"
data-target="> .carousel">
<we-button data-add-slide="true" data-no-preview="true">
<i class="fa fa-fw fa-plus-circle"/> Add Slide
</we-button>
@@ -1310,9 +1315,9 @@
</div>
<!-- Background Image -->
<div data-js="background"
data-selector="section, .parallax, :not(.o_gallery > .container) > .carousel"
data-exclude=".s_hr, .s_image_gallery">
<div data-js="background" string="Background"
data-selector="section, .parallax, .carousel-item"
data-exclude=".s_hr, .s_image_gallery, .o_gallery .carousel-item">
<we-button data-choose-image="true" data-no-preview="true">
<i class="fa fa-fw fa-picture-o"/> Background
</we-button>
@@ -1320,7 +1325,8 @@
<!-- Background Image -->
<div data-js="background_position"
data-selector="section, .parallax, :not(.o_gallery > .container) > .carousel">
data-selector="section, .parallax, .carousel-item"
data-exclude=".o_gallery .carousel-item">
<we-button data-background-position="true" data-no-preview="true">
<i class="fa fa-fw fa-arrows"/> Background Image Sizing
</we-button>
@@ -1346,8 +1352,8 @@
<!-- Color | Section -->
<div id="so_main_colorpicker"
data-js="colorpicker"
data-selector="section, :not(.o_gallery > .container) > .carousel"
data-exclude=".parallax">
data-selector="section, .carousel-item"
data-exclude=".parallax, .o_gallery .carousel-item">
<we-collapse-area>
<we-toggler><i class="fa fa-fw fa-eyedropper"/> Background Color</we-toggler>
<we-collapse/>
@@ -1389,7 +1395,8 @@
</div>
<div data-js="sizing_y"
data-selector="section, .row > div, :not(.o_gallery > .container) > .carousel, .parallax, .s_hr, .s_btn"/>
data-selector="section, .row > div, .parallax, .s_hr, .s_btn, .carousel-item"
data-exclude="section:has(> .carousel), .o_gallery .carousel-item"/>
<div data-js="sizing_x"
data-selector=".row > div"
@@ -1397,7 +1404,7 @@
data-exclude=".s_col_no_resize.row > div"/>
<div id="so_snippet_addition"
data-selector="section, :not(.o_gallery > .container) > .carousel, .parallax"
data-selector="section, .parallax"
data-drop-in=":not(p).oe_structure:not(.oe_structure_solo), :not(p)[data-oe-type=html], :not(p).oe_structure.oe_structure_solo:not(:has(> section, > div))"/>
<!-- Main content drop -->