diff options
| author | qsm-odoo <qsm@odoo.com> | 2020-03-04 16:09:47 +0000 |
|---|---|---|
| committer | qsm-odoo <qsm@odoo.com> | 2020-08-10 14:27:00 +0000 |
| commit | 42e1d4ca600b7a5c56d4739a150628310974b1a9 (patch) | |
| tree | 216d23a1211b5b9d94802c57331f8e2643f62b49 /addons/website/static/src | |
| parent | c531cb05916d799b660b2eb6f86dc3b340817905 (diff) | |
[IMP] website, *: enable the parallax option for all snippets
*: web_editor, website_blog
Unfortunately, this feature revealed a new batch of flaws in the
editor widgets system so some hacks were made to make it work. We will
always have the time to improve the pure technical side later.
This commit also separates the notion of color filter from the notion
of parallax. A color filter can now be applied independantly, when
there is either a background image or a background video. Applying a
color filter on top of a background video is actually a new feature.
Applying a color filter on top of a background image is actually now
achievable by two different ways: this new color filter layer or by
applying the color transformation on the image itself via the related
option. Depending on the user case, both could make sense at the same
time, but more importantly: having a CSS color filter is useful for
using those for default Odoo content (e.g. like the current contact us
page where we use a cover banner with an image with a black filter on
top of it: doing that without CSS color filter would mean to alter the
image directly which would not be ok when the user changes the image).
Also, sometimes you want the unfiltered image on a page and the exact
same one but filtered on another (for example: forum images).
Note: this commit also "fixes" an issue: the optimization feature for
images when parallax was enabled was not available before.
Part of https://github.com/odoo/odoo/pull/47313
task-46147
Diffstat (limited to 'addons/website/static/src')
| -rw-r--r-- | addons/website/static/src/js/content/snippets.animation.js | 18 | ||||
| -rw-r--r-- | addons/website/static/src/js/editor/snippets.options.js | 153 | ||||
| -rw-r--r-- | addons/website/static/src/scss/website.scss | 29 |
3 files changed, 146 insertions, 54 deletions
diff --git a/addons/website/static/src/js/content/snippets.animation.js b/addons/website/static/src/js/content/snippets.animation.js index 29781431519..d8bfef91fe9 100644 --- a/addons/website/static/src/js/content/snippets.animation.js +++ b/addons/website/static/src/js/content/snippets.animation.js @@ -494,7 +494,7 @@ registry.slider = publicWidget.Widget.extend({ }, }); -registry.parallax = Animation.extend({ +registry.Parallax = Animation.extend({ selector: '.parallax', disabledInEditableMode: false, effects: [{ @@ -530,27 +530,13 @@ registry.parallax = Animation.extend({ */ _rebuild: function () { // Add/find bg DOM element to hold the parallax bg (support old v10.0 parallax) - if (!this.$bg || !this.$bg.length) { - this.$bg = this.$('> .s_parallax_bg'); - if (!this.$bg.length) { - this.$bg = $('<span/>', { - class: 's_parallax_bg', - }).prependTo(this.$target); - } - } - var urlTarget = this.$target.css('background-image'); - if (urlTarget !== 'none') { - this.$bg.css('background-image', urlTarget); - } - this.$target.css('background-image', 'none'); + this.$bg = this.$('> .s_parallax_bg'); // Get parallax speed this.speed = parseFloat(this.$target.attr('data-scroll-background-ratio') || 0); // Reset offset if parallax effect will not be performed and leave - this.$target.toggleClass('s_parallax_is_fixed', this.speed === 1); var noParallaxSpeed = (this.speed === 0 || this.speed === 1); - this.$target.toggleClass('s_parallax_no_overflow_hidden', noParallaxSpeed); if (noParallaxSpeed) { this.$bg.css({ transform: '', diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js index 380d5f90638..e8be8995e21 100644 --- a/addons/website/static/src/js/editor/snippets.options.js +++ b/addons/website/static/src/js/editor/snippets.options.js @@ -626,6 +626,20 @@ options.Class.include({ }, }); +function _getLastPreFilterLayerElement($el) { + // Make sure parallax and video element are considered to be below the + // color filters / shape + const $bgVideo = $el.find('> .o_bg_video_container'); + if ($bgVideo.length) { + return $bgVideo[0]; + } + const $parallaxEl = $el.find('> .s_parallax_bg'); + if ($parallaxEl.length) { + return $parallaxEl[0]; + } + return null; +} + options.registry.BackgroundToggler.include({ /** * Toggles background video on or off. @@ -658,16 +672,34 @@ options.registry.BackgroundToggler.include({ return this._super(...arguments); }, /** + * TODO an overall better management of background layers is needed + * * @override */ - _computeWidgetVisibility(widgetName, params) { - if (widgetName === 'bg_video_toggler_opt') { - return !this.$target.is('.parallax, .s_parallax_bg'); + _getLastPreFilterLayerElement() { + const el = _getLastPreFilterLayerElement(this.$target); + if (el) { + return el; } return this._super(...arguments); }, }); +options.registry.BackgroundShape.include({ + /** + * TODO need a better management of background layers + * + * @override + */ + _getLastPreShapeLayerElement() { + const el = this._super(...arguments); + if (el) { + return el; + } + return _getLastPreFilterLayerElement(this.$target); + } +}); + options.registry.BackgroundVideo = options.Class.extend({ //-------------------------------------------------------------------------- @@ -1555,16 +1587,22 @@ options.registry.layout_column = options.Class.extend({ }, }); -options.registry.parallax = options.Class.extend({ +options.registry.Parallax = options.Class.extend({ /** * @override */ - onFocus: function () { - this.trigger_up('option_update', { - optionNames: ['BackgroundImage', 'BackgroundPosition'], - name: 'target', - data: this.$target.find('> .s_parallax_bg'), - }); + async start() { + this.parallaxEl = this.$target.find('> .s_parallax_bg')[0] || null; + this._updateBackgroundOptions(); + + this.$target.on('content_changed.ParallaxOption', this._onExternalUpdate.bind(this)); + + return this._super(...arguments); + }, + /** + * @override + */ + onFocus() { // Refresh the parallax animation on focus; at least useful because // there may have been changes in the page that influenced the parallax // rendering (new snippets, ...). @@ -1574,9 +1612,102 @@ options.registry.parallax = options.Class.extend({ /** * @override */ - onMove: function () { + onMove() { this._refreshPublicWidgets(); }, + /** + * @override + */ + destroy() { + this._super(...arguments); + this.$target.off('.ParallaxOption'); + }, + + //-------------------------------------------------------------------------- + // Options + //-------------------------------------------------------------------------- + + /** + * Build/remove parallax. + * + * @see this.selectClass for parameters + */ + async selectDataAttribute(previewMode, widgetValue, params) { + await this._super(...arguments); + if (params.attributeName !== 'scrollBackgroundRatio') { + return; + } + + const isParallax = (widgetValue !== '0'); + this.$target.toggleClass('parallax', isParallax); + this.$target.toggleClass('s_parallax_is_fixed', widgetValue === '1'); + this.$target.toggleClass('s_parallax_no_overflow_hidden', (widgetValue === '0' || widgetValue === '1')); + if (isParallax) { + if (!this.parallaxEl) { + this.parallaxEl = document.createElement('span'); + this.parallaxEl.classList.add('s_parallax_bg'); + this.$target.prepend(this.parallaxEl); + } + } else { + if (this.parallaxEl) { + this.parallaxEl.remove(); + this.parallaxEl = null; + } + } + + this._updateBackgroundOptions(); + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @override + */ + async _computeVisibility() { + return !this.$target.hasClass('o_background_video'); + }, + /** + * Updates external background-related option to work with the parallax + * element instead of the original target when necessary. + * + * @private + */ + _updateBackgroundOptions() { + this.trigger_up('option_update', { + optionNames: ['BackgroundImage', 'BackgroundPosition', 'BackgroundOptimize'], + name: 'target', + data: this.parallaxEl ? $(this.parallaxEl) : this.$target, + }); + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * Called on any snippet update to check if the parallax should still be + * enabled or not. + * + * TODO there is probably a better system to implement to solve this issue. + * + * @private + * @param {Event} ev + */ + _onExternalUpdate(ev) { + if (!this.parallaxEl) { + return; + } + const bgImage = this.parallaxEl.style.backgroundImage; + if (!bgImage || bgImage === 'none' || this.$target.hasClass('o_background_video')) { + // The parallax option was enabled but the background image was + // removed: disable the parallax option. + const widget = this._requestUserValueWidgets('parallax_none_opt')[0]; + widget.$el.click(); + widget.getParent().close(); // FIXME remove this ugly hack asap + } + }, }); options.registry.ul = options.Class.extend({ diff --git a/addons/website/static/src/scss/website.scss b/addons/website/static/src/scss/website.scss index 1e3e98f8fe1..99f5fd9eef0 100644 --- a/addons/website/static/src/scss/website.scss +++ b/addons/website/static/src/scss/website.scss @@ -256,16 +256,8 @@ font[class*='bg-'] { } // Background videos -.o_background_video { - position: relative; - - > * { - position: relative; - } -} .o_bg_video_container { - @include o-position-absolute(0, 0 ,0 ,0); - overflow: hidden; + @extend %o-we-background-layer; } .o_bg_video_iframe { position: relative; @@ -588,31 +580,14 @@ table.table_desc tr td { // Parallax .parallax { - position: relative; - // TODO this introduces a limitation: no dropdown will be able to // overflow. Maybe there is a better way to find. &:not(.s_parallax_no_overflow_hidden) { overflow: hidden; } - > * { - position: relative; - } > .s_parallax_bg { - @include o-position-absolute(0, 0, 0, 0); - display: block; - background-color: inherit; - background-size: cover; - background-attachment: scroll; - pointer-events: none; - - &::after { - content: ""; - @include o-position-absolute(0, 0, 0, 0); - display: block; - background-color: inherit; - } + @extend %o-we-background-layer; } @include media-breakpoint-up(xl) { // Fixed backgrounds are disabled when using a mobile/tablet device, |
