diff --git a/addons/website/static/src/js/content/snippets.animation.js b/addons/website/static/src/js/content/snippets.animation.js
index 48afbe0db65..36852683ad3 100644
--- a/addons/website/static/src/js/content/snippets.animation.js
+++ b/addons/website/static/src/js/content/snippets.animation.js
@@ -441,6 +441,7 @@ registry.slider = publicWidget.Widget.extend({
this._computeHeights();
// Initialize carousel and pause if in edit mode.
this.$target.carousel(this.editableMode ? 'pause' : undefined);
+ $(window).on('resize.slider', _.debounce(() => this._computeHeights(), 250));
return this._super.apply(this, arguments);
},
/**
@@ -454,6 +455,7 @@ registry.slider = publicWidget.Widget.extend({
_.each(this.$('.carousel-item'), function (el) {
$(el).css('min-height', '');
});
+ $(window).off('.slider');
},
//--------------------------------------------------------------------------
diff --git a/addons/website/static/src/snippets/s_image_gallery/000.js b/addons/website/static/src/snippets/s_image_gallery/000.js
index 19e98a7b341..7d1ee4ea386 100644
--- a/addons/website/static/src/snippets/s_image_gallery/000.js
+++ b/addons/website/static/src/snippets/s_image_gallery/000.js
@@ -7,7 +7,7 @@ var publicWidget = require('web.public.widget');
var qweb = core.qweb;
const GalleryWidget = publicWidget.Widget.extend({
- selector: '.o_gallery:not(.o_slideshow)',
+ selector: '.s_image_gallery:not(.o_slideshow)',
xmlDependencies: ['/website/static/src/xml/website.gallery.xml'],
events: {
'click img': '_onClickImg',
@@ -28,9 +28,7 @@ const GalleryWidget = publicWidget.Widget.extend({
var self = this;
var $cur = $(ev.currentTarget);
- var milliseconds = undefined;
- var params = undefined;
- var $images = $cur.closest('.o_gallery').find('img');
+ var $images = $cur.closest('.s_image_gallery').find('img');
var size = 0.8;
var dimensions = {
min_width: Math.round(window.innerWidth * size * 0.9),
@@ -43,7 +41,7 @@ const GalleryWidget = publicWidget.Widget.extend({
var $img = ($cur.is('img') === true) ? $cur : $cur.closest('img');
- milliseconds = $cur.closest('.o_gallery').data('interval') || false;
+ const milliseconds = $cur.closest('.s_image_gallery').data('interval') || false;
var $modal = $(qweb.render('website.gallery.slideshow.lightbox', {
images: $images.get(),
index: $images.index($img),
diff --git a/addons/website/static/src/snippets/s_image_gallery/000.scss b/addons/website/static/src/snippets/s_image_gallery/000.scss
index 9b5274f6673..a99bc86fcd2 100644
--- a/addons/website/static/src/snippets/s_image_gallery/000.scss
+++ b/addons/website/static/src/snippets/s_image_gallery/000.scss
@@ -1,5 +1,5 @@
-.o_gallery {
+.o_gallery:not([data-vcss]) {
&.o_grid, &.o_masonry {
.img {
width: 100%;
@@ -95,14 +95,6 @@
> div:first-child {
height: 100%;
}
- }
- .carousel-inner .item img {
- max-width: none;
- }
-}
-.o_gallery,
-.modal-body {
- &.o_slideshow {
.carousel {
height: 100%;
@@ -154,4 +146,10 @@
}
}
}
+ .carousel-inner .item img {
+ max-width: none;
+ }
}
+
+// Note: the s_gallery_lightbox is always using the right dom and classes of the
+// most recent version of the snippet as it is generated by JS after page load.
diff --git a/addons/website/static/src/snippets/s_image_gallery/001.scss b/addons/website/static/src/snippets/s_image_gallery/001.scss
new file mode 100644
index 00000000000..ef28b5c6d0a
--- /dev/null
+++ b/addons/website/static/src/snippets/s_image_gallery/001.scss
@@ -0,0 +1,245 @@
+
+.s_image_gallery[data-vcss="001"] {
+ &.o_grid, &.o_masonry {
+ .img {
+ width: 100%;
+ }
+ }
+ &.o_grid {
+ &.o_spc-none div.row {
+ margin-bottom: 0px;
+ }
+ &.o_spc-small div.row > div {
+ margin-bottom: $spacer;
+ }
+ &.o_spc-medium div.row > div {
+ margin-bottom: $spacer * 2;
+ }
+ &.o_spc-big div.row > div {
+ margin-bottom: $spacer * 3;
+ }
+ }
+ &.o_masonry {
+ &.o_spc-none div.o_masonry_col {
+ padding: 0;
+ > img {
+ margin: 0 !important;
+ }
+ }
+ &.o_spc-small div.o_masonry_col {
+ padding: 0 ($spacer * .5);
+ > img {
+ margin-bottom: $spacer !important;
+ }
+ }
+ &.o_spc-medium div.o_masonry_col {
+ padding: 0 $spacer;
+ > img {
+ margin-bottom: $spacer * 2 !important;
+ }
+ }
+ &.o_spc-big div.o_masonry_col {
+ padding: 0 ($spacer * 1.5);
+ > img {
+ margin-bottom: $spacer * 3 !important;
+ }
+ }
+ }
+ &.o_nomode {
+ &.o_spc-none .row div {
+ padding-top: 0;
+ padding-bottom: 0;
+ }
+ &.o_spc-small .row div {
+ padding-top: $spacer * .5;
+ padding-bottom: $spacer * .5;
+ }
+ &.o_spc-medium .row div {
+ padding-top: $spacer;
+ padding-bottom: $spacer;
+ }
+ &.o_spc-big .row div {
+ padding-top: $spacer * 1.5;
+ padding-bottom: $spacer * 1.5;
+ }
+ }
+ &:not(.o_slideshow) {
+ img {
+ cursor: pointer;
+ }
+ }
+ &.o_slideshow {
+ .carousel {
+ .carousel-item.active,
+ .carousel-item-next,
+ .carousel-item-prev,
+ .carousel-control-next,
+ .carousel-control-prev {
+ padding-bottom: 64px;
+ }
+ ul.carousel-indicators li {
+ border: 1px solid #aaa;
+ }
+ }
+ ul.carousel-indicators {
+ position: absolute;
+ left: 0%;
+ bottom: 0;
+ width: 100%;
+ height: auto;
+ margin-left: 0;
+ padding: 0;
+ border-width: 0;
+ > * {
+ list-style-image: none;
+ display: inline-block;
+ width: 40px;
+ height: 40px;
+ line-height: 40px;
+ margin: 2.5px 2.5px 2.5px 2.5px;
+ padding: 0;
+ border: 1px solid #aaa;
+ text-indent: initial;
+ background-size: cover;
+ background-color: #fff;
+ background-position: center;
+ border-radius: 0;
+ vertical-align: bottom;
+ flex: 0 0 40px;
+ &:not(.active) {
+ opacity: 0.8;
+ filter: grayscale(1);
+ }
+ }
+ }
+ > .container, > .container-fluid, > .o_container_small {
+ height: 100%;
+ }
+ &.s_image_gallery_cover .carousel-item > img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
+ &:not(.s_image_gallery_show_indicators) .carousel {
+ ul.carousel-indicators {
+ display: none;
+ }
+ .carousel-item.active,
+ .carousel-item-next,
+ .carousel-item-prev,
+ .carousel-control-next,
+ .carousel-control-prev {
+ padding-bottom: 0px;
+ }
+ }
+ &.s_image_gallery_indicators_arrows_boxed, &.s_image_gallery_indicators_arrows_rounded {
+ .carousel {
+ .carousel-control-prev .fa,
+ .carousel-control-next .fa {
+ text-shadow: none;
+ }
+ }
+ }
+ &.s_image_gallery_indicators_arrows_boxed {
+ .carousel {
+ .carousel-control-prev .fa:before {
+ content: "\f104";
+ padding-right: 2px;
+ }
+ .carousel-control-next .fa:before {
+ content: "\f105";
+ padding-left: 2px;
+ }
+ .carousel-control-prev .fa:before,
+ .carousel-control-next .fa:before {
+ display: block;
+ width: 3rem;
+ height: 3rem;
+ line-height: 3rem;
+ color: black;
+ background: white;
+ font-size: 1.25rem;
+ border: 1px solid $gray-500;
+ }
+ }
+ }
+ &.s_image_gallery_indicators_arrows_rounded {
+ .carousel {
+ .carousel-control-prev .fa:before { content: "\f060"; }
+ .carousel-control-next .fa:before { content: "\f061"; }
+ .carousel-control-prev .fa:before,
+ .carousel-control-next .fa:before {
+ color: black;
+ background: white;
+ font-size: 1.25rem;
+ border-radius: 50%;
+ padding: 1.25rem;
+ border: 1px solid $gray-500;
+ }
+ }
+ }
+ &.s_image_gallery_indicators_rounded {
+ .carousel {
+ ul.carousel-indicators li {
+ border-radius: 50%;
+ }
+ }
+ }
+
+ @extend %image-gallery-slideshow-styles;
+ }
+ .carousel-inner .item img {
+ max-width: none;
+ }
+}
+
+.s_gallery_lightbox {
+ .close {
+ font-size: 2rem;
+ }
+ .modal-dialog {
+ height: 100%;
+ background-color: rgba(0,0,0,0.7);
+ }
+ @include media-breakpoint-up(sm) {
+ .modal-dialog {
+ max-width: 100%;
+ padding: 0;
+ }
+ }
+ ul.carousel-indicators {
+ display: none;
+ }
+
+ .modal-body.o_slideshow {
+ @extend %image-gallery-slideshow-styles;
+ }
+}
+
+%image-gallery-slideshow-styles {
+ &:not(.s_image_gallery_cover) .carousel-item > img {
+ max-height: 100%;
+ max-width: 100%;
+ margin: auto;
+ }
+ .carousel {
+ height: 100%;
+
+ .carousel-inner {
+ height: 100%;
+ }
+ .carousel-item.active,
+ .carousel-item-next,
+ .carousel-item-prev,
+ .carousel-control-next,
+ .carousel-control-prev {
+ display: flex;
+ align-items: center;
+ height: 100%;
+ }
+ .carousel-control-next .fa,
+ .carousel-control-prev .fa {
+ text-shadow: 0px 0px 3px $gray-800;
+ }
+ }
+}
diff --git a/addons/website/static/src/snippets/s_image_gallery/options.js b/addons/website/static/src/snippets/s_image_gallery/options.js
index 6ce339b2d77..5a1f0c01d1b 100644
--- a/addons/website/static/src/snippets/s_image_gallery/options.js
+++ b/addons/website/static/src/snippets/s_image_gallery/options.js
@@ -46,7 +46,8 @@ options.registry.gallery = options.Class.extend({
}
});
- if (this.$('> div:first-child > *:not(div)').length) {
+ const $container = this.$('> .container, > .container-fluid, > .o_container_small');
+ if ($container.find('> *:not(div)').length) {
self.mode(null, self.getMode());
}
@@ -56,6 +57,8 @@ options.registry.gallery = options.Class.extend({
* @override
*/
onBuilt: function () {
+ this.addImages(false);
+ // TODO should consider the async parts
this._adaptNavigationIDs();
},
/**
@@ -83,7 +86,8 @@ options.registry.gallery = options.Class.extend({
* @see this.selectClass for parameters
*/
addImages: function (previewMode) {
- var $container = this.$('> div:first-child');
+ const $images = this.$('img');
+ var $container = this.$('> .container, > .container-fluid, > .o_container_small');
var dialog = new weWidgets.MediaDialog(this, {multiImages: true, onlyImages: true, mediaWidth: 1920});
var lastImage = _.last(this._getImages());
var index = lastImage ? this._getIndex(lastImage) : -1;
@@ -91,14 +95,18 @@ options.registry.gallery = options.Class.extend({
dialog.on('save', this, function (attachments) {
for (var i = 0; i < attachments.length; i++) {
$('', {
- class: 'img img-fluid',
+ class: $images.length > 0 ? $images[0].className : 'img img-fluid d-block ',
src: attachments[i].image_src,
'data-index': ++index,
alt: attachments[i].description || '',
+ 'data-name': _t('Image'),
+ style: $images.length > 0 ? $images[0].style.cssText : '',
}).appendTo($container);
}
- this.mode('reset', this.getMode());
- this.trigger_up('cover_update');
+ if (attachments.length > 0) {
+ this.mode('reset', this.getMode());
+ this.trigger_up('cover_update');
+ }
});
dialog.on('closed', this, () => resolve());
dialog.open();
@@ -139,7 +147,7 @@ options.registry.gallery = options.Class.extend({
*/
grid: function () {
var imgs = this._getImages();
- var $row = $('