summaryrefslogtreecommitdiff
path: root/addons/website/static/src/js
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2019-09-20 17:33:22 +0200
committerChristophe Simonis <chs@odoo.com>2019-09-20 17:34:45 +0200
commit64e43808b79badb5869a8d73cc1cc3f3b3aa8e12 (patch)
tree9a22d5f6c03073a4d10faedea8df23a5211e8b8f /addons/website/static/src/js
parent944891ced081cda3b8b3db5faf3b7ac23b6b4ce8 (diff)
parent58a83d12228fbbd4e9dde542e133d264204ee0f3 (diff)
[MERGE] forward port branch saas-12.5 up to 58a83d12228
Diffstat (limited to 'addons/website/static/src/js')
-rw-r--r--addons/website/static/src/js/content/snippets.animation.js109
-rw-r--r--addons/website/static/src/js/editor/snippets.options.js113
-rw-r--r--addons/website/static/src/js/editor/wysiwyg_multizone.js27
-rw-r--r--addons/website/static/src/js/set_view_track.js89
4 files changed, 322 insertions, 16 deletions
diff --git a/addons/website/static/src/js/content/snippets.animation.js b/addons/website/static/src/js/content/snippets.animation.js
index 681f6719354..7acb36d284b 100644
--- a/addons/website/static/src/js/content/snippets.animation.js
+++ b/addons/website/static/src/js/content/snippets.animation.js
@@ -6,9 +6,9 @@ odoo.define('website.content.snippets.animation', function (require) {
*/
var Class = require('web.Class');
+var config = require('web.config');
var core = require('web.core');
var mixins = require('web.mixins');
-var utils = require('web.utils');
var publicWidget = require('web.public.widget');
var utils = require('web.utils');
@@ -681,6 +681,113 @@ registry.mediaVideo = publicWidget.Widget.extend({
},
});
+registry.backgroundVideo = publicWidget.Widget.extend({
+ selector: '.o_background_video',
+ xmlDependencies: ['/website/static/src/xml/website.background.video.xml'],
+ disabledInEditableMode: false,
+
+ /**
+ * @override
+ */
+ start: function () {
+ var proms = [this._super(...arguments)];
+
+ this.videoSrc = this.el.dataset.bgVideoSrc;
+ this.iframeID = _.uniqueId('o_bg_video_iframe_');
+
+ this.isYoutubeVideo = this.videoSrc.indexOf('youtube') >= 0;
+ this.isMobileEnv = config.device.size_class <= config.device.SIZES.LG && config.device.touch;
+ if (this.isYoutubeVideo && this.isMobileEnv) {
+ this.videoSrc = this.videoSrc + "&enablejsapi=1";
+
+ if (!window.YT) {
+ proms.push(new Promise(resolve => {
+ window.onYouTubeIframeAPIReady = () => resolve();
+ }));
+ $('<script/>', {
+ src: 'https://www.youtube.com/iframe_api',
+ }).appendTo('head');
+ }
+ }
+
+ $(window).on('resize.' + this.iframeID, _.throttle(() => this._adjustIframe(), 50));
+
+ return Promise.all(proms).then(() => this._appendBgVideo());
+ },
+ /**
+ * @override
+ */
+ destroy: function () {
+ this._super.apply(this, arguments);
+
+ $(window).off('resize.' + this.iframeID);
+
+ if (this.$bgVideoContainer) {
+ this.$bgVideoContainer.remove();
+ }
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * Adjusts iframe sizes and position so that it fills the container and so
+ * that it is centered in it.
+ *
+ * @private
+ */
+ _adjustIframe: function () {
+ // Adjust the iframe
+ var wrapperWidth = this.$target.innerWidth();
+ var wrapperHeight = this.$target.innerHeight();
+ var relativeRatio = (wrapperWidth / wrapperHeight) / (16 / 9);
+ var style = {};
+ if (relativeRatio >= 1.0) {
+ style['width'] = '100%';
+ style['height'] = (relativeRatio * 100) + '%';
+ style['left'] = '0';
+ style['top'] = (-(relativeRatio - 1.0) / 2 * 100) + '%';
+ } else {
+ style['width'] = ((1 / relativeRatio) * 100) + '%';
+ style['height'] = '100%';
+ style['left'] = (-((1 / relativeRatio) - 1.0) / 2 * 100) + '%';
+ style['top'] = '0';
+ }
+ this.$iframe.css(style);
+ },
+ /**
+ * Append background video related elements to the target.
+ *
+ * @private
+ */
+ _appendBgVideo: function () {
+ var $oldContainer = this.$bgVideoContainer || this.$('> .o_bg_video_container');
+ this.$bgVideoContainer = $(qweb.render('website.background.video', {
+ videoSrc: this.videoSrc,
+ iframeID: this.iframeID,
+ }));
+ this.$iframe = this.$bgVideoContainer.find('.o_bg_video_iframe');
+ this.$iframe.one('load', () => {
+ this.$bgVideoContainer.find('.o_bg_video_loading').remove();
+ });
+ this.$bgVideoContainer.prependTo(this.$target);
+ $oldContainer.remove();
+
+ this._adjustIframe();
+
+ // YouTube does not allow to auto-play video in mobile devices, so we
+ // have to play the video manually.
+ if (this.isMobileEnv && this.isYoutubeVideo) {
+ new window.YT.Player(this.iframeID, {
+ events: {
+ onReady: ev => ev.target.playVideo(),
+ }
+ });
+ }
+ },
+});
+
registry.ul = publicWidget.Widget.extend({
selector: 'ul.o_ul_folded, ol.o_ul_folded',
events: {
diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js
index baa1d8c5a7c..7f60a976a35 100644
--- a/addons/website/static/src/js/editor/snippets.options.js
+++ b/addons/website/static/src/js/editor/snippets.options.js
@@ -29,6 +29,102 @@ options.Class.include({
},
});
+options.registry.background.include({
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ _getEditableMedia: function () {
+ if (!this._hasBgvideo()) {
+ return this._super(...arguments);
+ }
+ return this.$('.o_bg_video_iframe')[0];
+ },
+ /**
+ * @override
+ */
+ _getMediaDialogOptions: function () {
+ return _.extend(this._super(...arguments), {
+ // For now, disable the possibility to have a parallax video bg
+ noVideos: this.$target.is('.parallax, .s_parallax_bg'),
+ isForBgVideo: true,
+ });
+ },
+ /**
+ * @override
+ */
+ _setActive: function () {
+ this._super(...arguments);
+ if (this._hasBgvideo()) {
+ this.$el.find('[data-choose-image]').addClass('active');
+ }
+ },
+ /**
+ * Updates the background video used by the snippet.
+ *
+ * @private
+ * @see this.selectClass for parameters
+ */
+ _setBgVideo: function (previewMode, value) {
+ this.$('> .o_bg_video_container').toggleClass('d-none', previewMode === true);
+
+ if (previewMode !== false) {
+ return;
+ }
+
+ var target = this.$target[0];
+ target.classList.toggle('o_background_video', !!(value && value.length));
+ if (value && value.length) {
+ target.dataset.bgVideoSrc = value;
+ } else {
+ delete target.dataset.bgVideoSrc;
+ }
+ this._refreshPublicWidgets();
+ this._setActive();
+ },
+ /**
+ * Returns whether the current target has a background video or not.
+ *
+ * @private
+ * @returns {boolean}
+ */
+ _hasBgvideo: function () {
+ return this.$target[0].classList.contains('o_background_video');
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ _onBackgroundColorUpdate: function (ev, previewMode) {
+ var ret = this._super(...arguments);
+ if (ret) {
+ this._setBgVideo(previewMode);
+ }
+ return ret;
+ },
+ /**
+ * @override
+ */
+ _onSaveMediaDialog: function (data) {
+ if (!data.bgVideoSrc) {
+ this._setBgVideo(false);
+ this._super(...arguments);
+ return;
+ }
+ // if the user chose a video, only add the video without removing the
+ // background
+ this._setBgVideo(false, data.bgVideoSrc);
+ },
+});
+
options.registry.menu_data = options.Class.extend({
xmlDependencies: ['/website/static/src/xml/website.editor.xml'],
@@ -1014,6 +1110,7 @@ options.registry.gallery = options.Class.extend({
}
self._reset();
self.trigger_up('cover_update');
+ this._setActive();
});
dialog.open();
},
@@ -1170,11 +1267,12 @@ options.registry.gallery = options.Class.extend({
var urls = _.map(this._getImages(), function (img) {
return $(img).attr('src');
});
+ var currentInterval = this.$target.find('.carousel:first').attr('data-interval');
var params = {
srcs : urls,
index: 0,
title: "",
- interval : this.$target.data('interval') || false,
+ interval : currentInterval || this.$target.data('interval') || 0,
id: 'slideshow_' + new Date().getTime(),
userStyle: imgStyle,
},
@@ -1312,7 +1410,7 @@ options.registry.gallery = options.Class.extend({
.data('mode');
var carousel = this.$target[0].querySelector('.carousel');
- var activeInterval = carousel ? carousel.dataset.interval : undefined;
+ var activeInterval = carousel ? (carousel.dataset.interval || 0) : undefined;
var $intervalOptions = this.$el.find('[data-interval]');
$intervalOptions.removeClass('active')
.filter('[data-interval="' + activeInterval + '"]')
@@ -1334,14 +1432,19 @@ options.registry.gallery = options.Class.extend({
var $stylingOptions = this.$el.find('[data-styling]');
$stylingOptions.removeClass('active');
var img = this.$target[0].querySelector('img');
+ var activeStyleSelectors = [];
if (img) {
- var activeStyleSelectors = [];
for (const className of img.classList) {
activeStyleSelectors.push('[data-styling="' + className + '"]');
}
- $stylingOptions.filter(activeStyleSelectors.join(', '))
- .addClass('active');
}
+ var $toEnable = activeStyleSelectors.length
+ ? $stylingOptions.filter(activeStyleSelectors.join(', '))
+ : null;
+ if (!$toEnable || !$toEnable.length) {
+ $toEnable = $stylingOptions.first();
+ }
+ $toEnable.addClass('active');
},
});
diff --git a/addons/website/static/src/js/editor/wysiwyg_multizone.js b/addons/website/static/src/js/editor/wysiwyg_multizone.js
index 9ed31d3afe5..8c7fbfb2e0c 100644
--- a/addons/website/static/src/js/editor/wysiwyg_multizone.js
+++ b/addons/website/static/src/js/editor/wysiwyg_multizone.js
@@ -124,17 +124,23 @@ var WysiwygMultizone = Wysiwyg.extend({
*/
_saveElement: function (outerHTML, recordInfo, editable) {
var promises = [];
+
var $el = $(editable);
- promises.push(this._rpc({
- model: 'ir.ui.view',
- method: 'save',
- args: [
- $el.data('oe-id'),
- outerHTML,
- $el.data('oe-xpath') || null,
- ],
- context: recordInfo.context,
- }));
+
+ var viewID = $el.data('oe-id');
+ if (viewID) {
+ promises.push(this._rpc({
+ model: 'ir.ui.view',
+ method: 'save',
+ args: [
+ viewID,
+ outerHTML,
+ $el.data('oe-xpath') || null,
+ ],
+ context: recordInfo.context,
+ }));
+ }
+
if ($el.data('oe-field') === 'mega_menu_content') {
// On top of saving the mega menu content like any other field
// content, we must save the custom classes that were set on the
@@ -153,6 +159,7 @@ var WysiwygMultizone = Wysiwyg.extend({
],
}));
}
+
return Promise.all(promises);
},
/**
diff --git a/addons/website/static/src/js/set_view_track.js b/addons/website/static/src/js/set_view_track.js
new file mode 100644
index 00000000000..d94fcddfffd
--- /dev/null
+++ b/addons/website/static/src/js/set_view_track.js
@@ -0,0 +1,89 @@
+odoo.define('website.set_view_track', function (require) {
+"use strict";
+
+var CustomizeMenu = require('website.customizeMenu');
+var Widget = require('web.Widget');
+
+var TrackPage = Widget.extend({
+ template: 'website.track_page',
+ xmlDependencies: ['/website/static/src/xml/track_page.xml'],
+ events: {
+ 'change #switch-track-page': '_onTrackChange',
+ },
+
+ /**
+ * @override
+ */
+ start: function () {
+ this.$input = this.$('#switch-track-page');
+ this._isTracked().then((data) => {
+ if (data[0]['track']) {
+ this.track = true;
+ this.$input.attr('checked', 'checked');
+ } else {
+ this.track = false;
+ }
+ });
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ _isTracked: function (val) {
+ var viewid = $('html').data('viewid');
+ if (!viewid) {
+ return Promise.reject();
+ } else {
+ return this._rpc({
+ model: 'ir.ui.view',
+ method: 'read',
+ args: [[viewid], ['track']],
+ });
+ }
+ },
+ /**
+ * @private
+ */
+ _onTrackChange: function (ev) {
+ var checkboxValue = this.$input.is(':checked');
+ if (checkboxValue !== this.track) {
+ this.track = checkboxValue;
+ this._trackPage(checkboxValue);
+ }
+ },
+ /**
+ * @private
+ */
+ _trackPage: function (val) {
+ var viewid = $('html').data('viewid');
+ if (!viewid) {
+ return Promise.reject();
+ } else {
+ return this._rpc({
+ model: 'ir.ui.view',
+ method: 'write',
+ args: [[viewid], {track: val}],
+ });
+ }
+ },
+});
+
+CustomizeMenu.include({
+ _loadCustomizeOptions: function () {
+ var self = this;
+ var def = this._super.apply(this, arguments);
+ return def.then(function () {
+ if (!self.__trackpageLoaded) {
+ self.__trackpageLoaded = true;
+ self.trackPage = new TrackPage(self);
+ self.trackPage.appendTo(self.$el.children('.dropdown-menu'));
+ }
+ });
+ },
+});
+
+});