From a8305af1b33eb76d139408c084b7712a6c1c83c1 Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Wed, 18 Dec 2019 03:04:42 +0100 Subject: [REF] move history of xml/js to s_chart files --- .../static/src/js/content/snippets.animation.js | 1061 ------------ .../static/src/js/editor/snippets.options.js | 1772 -------------------- 2 files changed, 2833 deletions(-) delete mode 100644 addons/website/static/src/js/content/snippets.animation.js delete mode 100644 addons/website/static/src/js/editor/snippets.options.js (limited to 'addons/website/static/src/js') diff --git a/addons/website/static/src/js/content/snippets.animation.js b/addons/website/static/src/js/content/snippets.animation.js deleted file mode 100644 index b9ca31ee248..00000000000 --- a/addons/website/static/src/js/content/snippets.animation.js +++ /dev/null @@ -1,1061 +0,0 @@ -odoo.define('website.content.snippets.animation', function (require) { -'use strict'; - -/** - * Provides a way to start JS code for snippets' initialization and animations. - */ - -var Class = require('web.Class'); -const ColorpickerDialog = require('web.ColorpickerDialog'); -var config = require('web.config'); -var core = require('web.core'); -var mixins = require('web.mixins'); -var publicWidget = require('web.public.widget'); -var utils = require('web.utils'); - -var qweb = core.qweb; -const _t = core._t; - -// Initialize fallbacks for the use of requestAnimationFrame, -// cancelAnimationFrame and performance.now() -window.requestAnimationFrame = window.requestAnimationFrame - || window.webkitRequestAnimationFrame - || window.mozRequestAnimationFrame - || window.msRequestAnimationFrame - || window.oRequestAnimationFrame; -window.cancelAnimationFrame = window.cancelAnimationFrame - || window.webkitCancelAnimationFrame - || window.mozCancelAnimationFrame - || window.msCancelAnimationFrame - || window.oCancelAnimationFrame; -if (!window.performance || !window.performance.now) { - window.performance = { - now: function () { - return Date.now(); - } - }; -} - -/** - * Add the notion of edit mode to public widgets. - */ -publicWidget.Widget.include({ - /** - * Indicates if the widget should not be instantiated in edit. The default - * is true, indeed most (all?) defined widgets only want to initialize - * events and states which should not be active in edit mode (this is - * especially true for non-website widgets). - * - * @type {boolean} - */ - disabledInEditableMode: true, - /** - * Acts as @see Widget.events except that the events are only binded if the - * Widget instance is instanciated in edit mode. The property is not - * considered if @see disabledInEditableMode is false. - */ - edit_events: null, - /** - * Acts as @see Widget.events except that the events are only binded if the - * Widget instance is instanciated in readonly mode. The property only - * makes sense if @see disabledInEditableMode is false, you should simply - * use @see Widget.events otherwise. - */ - read_events: null, - - /** - * Initializes the events that will need to be binded according to the - * given mode. - * - * @constructor - * @param {Object} parent - * @param {Object} [options] - * @param {boolean} [options.editableMode=false] - * true if the page is in edition mode - */ - init: function (parent, options) { - this._super.apply(this, arguments); - - this.editableMode = this.options.editableMode || false; - var extraEvents = this.editableMode ? this.edit_events : this.read_events; - if (extraEvents) { - this.events = _.extend({}, this.events || {}, extraEvents); - } - }, -}); - -/** - * In charge of handling one animation loop using the requestAnimationFrame - * feature. This is used by the `Animation` class below and should not be called - * directly by an end developer. - * - * This uses a simple API: it can be started, stopped, played and paused. - */ -var AnimationEffect = Class.extend(mixins.ParentedMixin, { - /** - * @constructor - * @param {Object} parent - * @param {function} updateCallback - the animation update callback - * @param {string} [startEvents=scroll] - * space separated list of events which starts the animation loop - * @param {jQuery|DOMElement} [$startTarget=window] - * the element(s) on which the startEvents are listened - * @param {Object} [options] - * @param {function} [options.getStateCallback] - * a function which returns a value which represents the state of the - * animation, i.e. for two same value, no refreshing of the animation - * is needed. Can be used for optimization. If the $startTarget is - * the window element, this defaults to returning the current - * scoll offset of the window or the size of the window for the - * scroll and resize events respectively. - * @param {string} [options.endEvents] - * space separated list of events which pause the animation loop. If - * not given, the animation is stopped after a while (if no - * startEvents is received again) - * @param {jQuery|DOMElement} [options.$endTarget=$startTarget] - * the element(s) on which the endEvents are listened - */ - init: function (parent, updateCallback, startEvents, $startTarget, options) { - mixins.ParentedMixin.init.call(this); - this.setParent(parent); - - options = options || {}; - this._minFrameTime = 1000 / (options.maxFPS || 100); - - // Initialize the animation startEvents, startTarget, endEvents, endTarget and callbacks - this._updateCallback = updateCallback; - this.startEvents = startEvents || 'scroll'; - this.$startTarget = $($startTarget || window); - if (options.getStateCallback) { - this._getStateCallback = options.getStateCallback; - } else if (this.startEvents === 'scroll' && this.$startTarget[0] === window) { - this._getStateCallback = function () { - return window.pageYOffset; - }; - } else if (this.startEvents === 'resize' && this.$startTarget[0] === window) { - this._getStateCallback = function () { - return { - width: window.innerWidth, - height: window.innerHeight, - }; - }; - } else { - this._getStateCallback = function () { - return undefined; - }; - } - this.endEvents = options.endEvents || false; - this.$endTarget = options.$endTarget ? $(options.$endTarget) : this.$startTarget; - - this._updateCallback = this._updateCallback.bind(parent); - this._getStateCallback = this._getStateCallback.bind(parent); - - // Add a namespace to events using the generated uid - this._uid = '_animationEffect' + _.uniqueId(); - this.startEvents = _processEvents(this.startEvents, this._uid); - if (this.endEvents) { - this.endEvents = _processEvents(this.endEvents, this._uid); - } - - function _processEvents(events, namespace) { - events = events.split(' '); - return _.each(events, function (e, index) { - events[index] += ('.' + namespace); - }).join(' '); - } - }, - /** - * @override - */ - destroy: function () { - mixins.ParentedMixin.destroy.call(this); - this.stop(); - }, - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - /** - * Initializes when the animation must be played and paused and initializes - * the animation first frame. - */ - start: function () { - // Initialize the animation first frame - this._paused = false; - this._rafID = window.requestAnimationFrame((function (t) { - this._update(t); - this._paused = true; - }).bind(this)); - - // Initialize the animation play/pause events - if (this.endEvents) { - /** - * If there are endEvents, the animation should begin playing when - * the startEvents are triggered on the $startTarget and pause when - * the endEvents are triggered on the $endTarget. - */ - this.$startTarget.on(this.startEvents, (function (e) { - if (this._paused) { - _.defer(this.play.bind(this, e)); - } - }).bind(this)); - this.$endTarget.on(this.endEvents, (function () { - if (!this._paused) { - _.defer(this.pause.bind(this)); - } - }).bind(this)); - } else { - /** - * Else, if there is no endEvents, the animation should begin playing - * when the startEvents are *continuously* triggered on the - * $startTarget or fully played once. To achieve this, the animation - * begins playing and is scheduled to pause after 2 seconds. If the - * startEvents are triggered during that time, this is not paused - * for another 2 seconds. This allows to describe an "effect" - * animation (which lasts less than 2 seconds) or an animation which - * must be playing *during* an event (scroll, mousemove, resize, - * repeated clicks, ...). - */ - var pauseTimer = null; - this.$startTarget.on(this.startEvents, _.throttle((function (e) { - this.play(e); - - clearTimeout(pauseTimer); - pauseTimer = _.delay((function () { - this.pause(); - pauseTimer = null; - }).bind(this), 2000); - }).bind(this), 250, {trailing: false})); - } - }, - /** - * Pauses the animation and destroys the attached events which trigger the - * animation to be played or paused. - */ - stop: function () { - this.$startTarget.off(this.startEvents); - if (this.endEvents) { - this.$endTarget.off(this.endEvents); - } - this.pause(); - }, - /** - * Forces the requestAnimationFrame loop to start. - * - * @param {Event} e - the event which triggered the animation to play - */ - play: function (e) { - this._newEvent = e; - if (!this._paused) { - return; - } - this._paused = false; - this._rafID = window.requestAnimationFrame(this._update.bind(this)); - this._lastUpdateTimestamp = undefined; - }, - /** - * Forces the requestAnimationFrame loop to stop. - */ - pause: function () { - if (this._paused) { - return; - } - this._paused = true; - window.cancelAnimationFrame(this._rafID); - this._lastUpdateTimestamp = undefined; - }, - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * Callback which is repeatedly called by the requestAnimationFrame loop. - * It controls the max fps at which the animation is running and initializes - * the values that the update callback needs to describe the animation - * (state, elapsedTime, triggered event). - * - * @private - * @param {DOMHighResTimeStamp} timestamp - */ - _update: function (timestamp) { - if (this._paused) { - return; - } - this._rafID = window.requestAnimationFrame(this._update.bind(this)); - - // Check the elapsed time since the last update callback call. - // Consider it 0 if there is no info of last timestamp and leave this - // _update call if it was called too soon (would overflow the set max FPS). - var elapsedTime = 0; - if (this._lastUpdateTimestamp) { - elapsedTime = timestamp - this._lastUpdateTimestamp; - if (elapsedTime < this._minFrameTime) { - return; - } - } - - // Check the new animation state thanks to the get state callback and - // store its new value. If the state is the same as the previous one, - // leave this _update call, except if there is an event which triggered - // the "play" method again. - var animationState = this._getStateCallback(elapsedTime, this._newEvent); - if (!this._newEvent - && animationState !== undefined - && _.isEqual(animationState, this._animationLastState)) { - return; - } - this._animationLastState = animationState; - - // Call the update callback with frame parameters - this._updateCallback(this._animationLastState, elapsedTime, this._newEvent); - this._lastUpdateTimestamp = timestamp; // Save the timestamp at which the update callback was really called - this._newEvent = undefined; // Forget the event which triggered the last "play" call - }, -}); - -/** - * Also register AnimationEffect automatically (@see effects, _prepareEffects). - */ -var Animation = publicWidget.Widget.extend({ - /** - * The max FPS at which all the automatic animation effects will be - * running by default. - */ - maxFPS: 100, - /** - * @see this._prepareEffects - * - * @type {Object[]} - * @type {string} startEvents - * The names of the events which trigger the effect to begin playing. - * @type {string} [startTarget] - * A selector to find the target where to listen for the start events - * (if no selector, the window target will be used). If the whole - * $target of the animation should be used, use the 'selector' string. - * @type {string} [endEvents] - * The name of the events which trigger the end of the effect (if none - * is defined, the animation will stop after a while - * @see AnimationEffect.start). - * @type {string} [endTarget] - * A selector to find the target where to listen for the end events - * (if no selector, the startTarget will be used). If the whole - * $target of the animation should be used, use the 'selector' string. - * @type {string} update - * A string which refers to a method which will be used as the update - * callback for the effect. It receives 3 arguments: the animation - * state, the elapsedTime since last update and the event which - * triggered the animation (undefined if just a new update call - * without trigger). - * @type {string} [getState] - * The animation state is undefined by default, the scroll offset for - * the particular {startEvents: 'scroll'} effect and an object with - * width and height for the particular {startEvents: 'resize'} effect. - * There is the possibility to define the getState callback of the - * animation effect with this key. This allows to improve performance - * even further in some cases. - */ - effects: [], - - /** - * Initializes the animation. The method should not be called directly as - * called automatically on animation instantiation and on restart. - * - * Also, prepares animation's effects and start them if any. - * - * @override - */ - start: function () { - this._prepareEffects(); - _.each(this._animationEffects, function (effect) { - effect.start(); - }); - return this._super.apply(this, arguments); - }, - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * Registers `AnimationEffect` instances. - * - * This can be done by extending this method and calling the @see _addEffect - * method in it or, better, by filling the @see effects property. - * - * @private - */ - _prepareEffects: function () { - this._animationEffects = []; - - var self = this; - _.each(this.effects, function (desc) { - self._addEffect(self[desc.update], desc.startEvents, _findTarget(desc.startTarget), { - getStateCallback: desc.getState && self[desc.getState], - endEvents: desc.endEvents || undefined, - $endTarget: _findTarget(desc.endTarget), - maxFPS: self.maxFPS, - }); - - // Return the DOM element matching the selector in the form - // described above. - function _findTarget(selector) { - if (selector) { - if (selector === 'selector') { - return self.$target; - } - return self.$(selector); - } - return undefined; - } - }); - }, - /** - * Registers a new `AnimationEffect` according to given parameters. - * - * @private - * @see AnimationEffect.init - */ - _addEffect: function (updateCallback, startEvents, $startTarget, options) { - this._animationEffects.push( - new AnimationEffect(this, updateCallback, startEvents, $startTarget, options) - ); - }, -}); - -//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - -var registry = publicWidget.registry; - -registry.slider = publicWidget.Widget.extend({ - selector: '.carousel', - disabledInEditableMode: false, - edit_events: { - 'content_changed': '_onContentChanged', - }, - - /** - * @override - */ - start: function () { - 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); - }, - /** - * @override - */ - destroy: function () { - this._super.apply(this, arguments); - this.$('img').off('.slider'); - this.$target.carousel('pause'); - this.$target.removeData('bs.carousel'); - _.each(this.$('.carousel-item'), function (el) { - $(el).css('min-height', ''); - }); - }, - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * @private - */ - _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'); - $item.addClass('active'); - var height = $item.outerHeight(); - if (height > maxHeight) { - maxHeight = height; - } - $item.toggleClass('active', isActive); - }); - $items.css('min-height', maxHeight); - }, - - //-------------------------------------------------------------------------- - // Handlers - //-------------------------------------------------------------------------- - - /** - * @private - */ - _onContentChanged: function (ev) { - this._computeHeights(); - }, -}); - -registry.parallax = Animation.extend({ - selector: '.parallax', - disabledInEditableMode: false, - effects: [{ - startEvents: 'scroll', - update: '_onWindowScroll', - }], - - /** - * @override - */ - start: function () { - this._rebuild(); - $(window).on('resize.animation_parallax', _.debounce(this._rebuild.bind(this), 500)); - return this._super.apply(this, arguments); - }, - /** - * @override - */ - destroy: function () { - this._super.apply(this, arguments); - $(window).off('.animation_parallax'); - }, - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * Prepares the background element which will scroll at a different speed - * according to the viewport dimensions and other snippet parameters. - * - * @private - */ - _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 = $('', { - class: 's_parallax_bg' + (this.$target.hasClass('oe_custom_bg') ? ' oe_custom_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'); - - // 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: '', - top: '', - bottom: '', - }); - return; - } - - // Initialize parallax data according to snippet and viewport dimensions - this.viewport = document.body.clientHeight - $('#wrapwrap').position().top; - this.visibleArea = [this.$target.offset().top]; - this.visibleArea.push(this.visibleArea[0] + this.$target.innerHeight() + this.viewport); - this.ratio = this.speed * (this.viewport / 10); - - // Provide a "safe-area" to limit parallax - this.$bg.css({ - top: -this.ratio, - bottom: -this.ratio, - }); - }, - - //-------------------------------------------------------------------------- - // Effects - //-------------------------------------------------------------------------- - - /** - * Describes how to update the snippet when the window scrolls. - * - * @private - * @param {integer} scrollOffset - */ - _onWindowScroll: function (scrollOffset) { - // Speed == 0 is no effect and speed == 1 is handled by CSS only - if (this.speed === 0 || this.speed === 1) { - return; - } - - // Perform translation if the element is visible only - var vpEndOffset = scrollOffset + this.viewport; - if (vpEndOffset >= this.visibleArea[0] - && vpEndOffset <= this.visibleArea[1]) { - this.$bg.css('transform', 'translateY(' + _getNormalizedPosition.call(this, vpEndOffset) + 'px)'); - } - - function _getNormalizedPosition(pos) { - // Normalize scroll in a 1 to 0 range - var r = (pos - this.visibleArea[1]) / (this.visibleArea[0] - this.visibleArea[1]); - // Normalize accordingly to current options - return Math.round(this.ratio * (2 * r - 1)); - } - }, -}); - -registry.mediaVideo = publicWidget.Widget.extend({ - selector: '.media_iframe_video', - - /** - * @override - */ - start: function () { - // TODO: this code should be refactored to make more sense and be better - // integrated with Odoo (this refactoring should be done in master). - - var def = this._super.apply(this, arguments); - if (this.$target.children('iframe').length) { - // There already is an