summaryrefslogtreecommitdiff
path: root/addons/website
diff options
context:
space:
mode:
authorqsm-odoo <qsm@odoo.com>2020-09-17 10:41:10 +0000
committerqsm-odoo <qsm@odoo.com>2020-09-22 08:29:11 +0000
commit4e7be69825163c0a0ff41c882a196fc7f3158fb3 (patch)
tree517a928cddbfa019033af95f2f284cab4e82496d /addons/website
parent416b125803d043badef8e4b022c100e33d1dba04 (diff)
[IMP] website, *: move page scrollbar to #wrapwrap
*: web, web_editor, portal, account, website_blog, website_forum This is probably not ideal to move the scrolling behavior out of the html element but this will be needed for the editor to not have a double scrollbar on the right. This is actually also useful for the scrollbar to appear under the purple odoo menu instead of its right. This commit, if to be reverted in the future, however contains many improvements to make the transition easier that should be kept: jQuery and Odoo functions to be able to scrollTo a specific element, get the top scrollable element, check if an element is scrollable, etc. Also, some magic was done: if some code tries to scroll to a specific scroll position via jQuery's scrollTop or animate functions on the html/body element, those will still work as intended (obviously, using the new utils to do that is however recommended). This commit also reviews our scroll behaviors to make them more robust and share the code. Part of https://github.com/odoo/odoo/pull/57975 task-2344227
Diffstat (limited to 'addons/website')
-rw-r--r--addons/website/static/src/js/content/menu.js12
-rw-r--r--addons/website/static/src/js/content/snippets.animation.js41
-rw-r--r--addons/website/static/src/js/editor/snippets.editor.js1
-rw-r--r--addons/website/static/src/js/editor/snippets.options.js12
-rw-r--r--addons/website/static/src/snippets/s_table_of_content/000.js36
-rw-r--r--addons/website/views/website_navbar_templates.xml2
6 files changed, 41 insertions, 63 deletions
diff --git a/addons/website/static/src/js/content/menu.js b/addons/website/static/src/js/content/menu.js
index 27000cfd48d..bcf9ebbaf78 100644
--- a/addons/website/static/src/js/content/menu.js
+++ b/addons/website/static/src/js/content/menu.js
@@ -76,10 +76,8 @@ const BaseAnimatedHeader = animations.Animation.extend({
this._updateMainPaddingTop();
this.el.classList.toggle('o_top_fixed_element', this.fixedHeader && this._isShown());
- const bottom = this.el.getBoundingClientRect().bottom
- || (this.el.nextElementSibling.getBoundingClientRect().top + window.scrollY);
for (const callback of extraMenuUpdateCallbacks) {
- callback(bottom);
+ callback();
}
},
/**
@@ -130,6 +128,14 @@ const BaseAnimatedHeader = animations.Animation.extend({
_toggleFixedHeader: function (useFixed = true) {
this.fixedHeader = useFixed;
this.el.classList.toggle('o_header_affixed', useFixed);
+ // Compensate scrollbar
+ if (useFixed) {
+ const scrollableEl = this.$el.parent().closestScrollable()[0];
+ const style = window.getComputedStyle(this.el);
+ this.el.style.setProperty('right', `${parseInt(style['right']) + scrollableEl.offsetWidth - scrollableEl.clientWidth}px`, 'important');
+ } else {
+ this.el.style.removeProperty('right');
+ }
this._adaptToHeaderChange();
},
/**
diff --git a/addons/website/static/src/js/content/snippets.animation.js b/addons/website/static/src/js/content/snippets.animation.js
index 81640cde197..368be2e810b 100644
--- a/addons/website/static/src/js/content/snippets.animation.js
+++ b/addons/website/static/src/js/content/snippets.animation.js
@@ -8,6 +8,7 @@ odoo.define('website.content.snippets.animation', function (require) {
var Class = require('web.Class');
var config = require('web.config');
var core = require('web.core');
+const dom = require('web.dom');
var mixins = require('web.mixins');
var publicWidget = require('web.public.widget');
var utils = require('web.utils');
@@ -123,12 +124,13 @@ var AnimationEffect = Class.extend(mixins.ParentedMixin, {
// Initialize the animation startEvents, startTarget, endEvents, endTarget and callbacks
this._updateCallback = updateCallback;
this.startEvents = startEvents || 'scroll';
- this.$startTarget = $($startTarget || window);
+ this.$startTarget = $($startTarget ? $startTarget : this.startEvents === 'scroll' ? $().getScrollingElement()[0] : window);
if (options.getStateCallback) {
this._getStateCallback = options.getStateCallback;
- } else if (this.startEvents === 'scroll' && this.$startTarget[0] === window) {
+ } else if (this.startEvents === 'scroll' && this.$startTarget[0] === $().getScrollingElement()[0]) {
+ const $scrollable = this.$startTarget;
this._getStateCallback = function () {
- return window.pageYOffset;
+ return $scrollable.scrollTop();
};
} else if (this.startEvents === 'resize' && this.$startTarget[0] === window) {
this._getStateCallback = function () {
@@ -898,38 +900,19 @@ registry.anchorSlide = publicWidget.Widget.extend({
* @private
* @param {jQuery} $el the element to scroll to.
* @param {string} [scrollValue='true'] scroll value
+ * @returns {Promise}
*/
- _scrollTo: function ($el, scrollValue = 'true', forcedDelay = undefined) {
- const _computeScrollTo = () => {
- const headerHeight = this._computeHeaderHeight();
- const offset = $el.css('position') !== 'fixed' ? $el.offset().top : $el.position().top;
- return offset - headerHeight;
- };
- const originalScrollTo = _computeScrollTo();
- return new Promise(resolve => {
- $('html, body').animate({
- scrollTop: originalScrollTo,
- }, {
- duration: forcedDelay || (scrollValue === 'true' ? 500 : 0),
- progress: (a, b, remainingMs) => {
- const scrollTo = _computeScrollTo();
- if (Math.abs(scrollTo - originalScrollTo) >= 1.0) {
- $('html, body').stop();
- this._scrollTo($el, scrollValue, remainingMs).then(() => resolve());
- }
- },
- complete: () => resolve(),
- });
+ async _scrollTo($el, scrollValue = 'true') {
+ return dom.scrollTo($el[0], {
+ duration: scrollValue === 'true' ? 500 : 0,
+ extraOffset: this._computeExtraOffset(),
});
},
/**
* @private
*/
- _computeHeaderHeight: function () {
- let headerHeight = 0;
- const $navbarFixed = $('.o_top_fixed_element');
- _.each($navbarFixed, el => headerHeight += $(el).outerHeight());
- return headerHeight;
+ _computeExtraOffset() {
+ return 0;
},
//--------------------------------------------------------------------------
diff --git a/addons/website/static/src/js/editor/snippets.editor.js b/addons/website/static/src/js/editor/snippets.editor.js
index e226fd70543..40f999f836c 100644
--- a/addons/website/static/src/js/editor/snippets.editor.js
+++ b/addons/website/static/src/js/editor/snippets.editor.js
@@ -100,6 +100,7 @@ weSnippetEditor.Class.include({
if (!options.offsetElements || !options.offsetElements.$top) {
const $header = $('#top');
if ($header.length) {
+ finalOptions.offsetElements = finalOptions.offsetElements || {};
finalOptions.offsetElements.$top = $header;
}
}
diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js
index 5819402c93a..3b53a594bd7 100644
--- a/addons/website/static/src/js/editor/snippets.options.js
+++ b/addons/website/static/src/js/editor/snippets.options.js
@@ -5,6 +5,7 @@ const {ColorpickerWidget} = require('web.Colorpicker');
const config = require('web.config');
var core = require('web.core');
var Dialog = require('web.Dialog');
+const dom = require('web.dom');
const weUtils = require('web_editor.utils');
var options = require('web_editor.snippets.options');
const wUtils = require('website.utils');
@@ -2504,13 +2505,10 @@ options.registry.SnippetMove = options.Class.extend({
break;
}
if (params.name === 'move_up_opt' || params.name === 'move_down_opt') {
- $('html, body').animate(
- {
- scrollTop: this.$target.offset().top - $(window).height() / 2,
- },
- 500,
- 'linear',
- );
+ dom.scrollTo(this.$target[0], {
+ extraOffset: 50,
+ easing: 'linear',
+ });
}
},
});
diff --git a/addons/website/static/src/snippets/s_table_of_content/000.js b/addons/website/static/src/snippets/s_table_of_content/000.js
index ac610304e48..68250bc88fa 100644
--- a/addons/website/static/src/snippets/s_table_of_content/000.js
+++ b/addons/website/static/src/snippets/s_table_of_content/000.js
@@ -11,18 +11,18 @@ const TableOfContent = publicWidget.Widget.extend({
/**
* @override
*/
- start: function () {
- this._initializeNavbarTopPosition();
+ async start() {
+ await this._super(...arguments);
+ this._updateTableOfContentNavbarPosition();
extraMenuUpdateCallbacks.push(this._updateTableOfContentNavbarPosition.bind(this));
- return this._super.apply(this, arguments);
},
/**
* @override
*/
- destroy: function () {
+ destroy() {
this.$target.css('top', '');
this.$target.find('.s_table_of_content_navbar').css('top', '');
- this._super.apply(this, arguments);
+ this._super(...arguments);
},
//--------------------------------------------------------------------------
@@ -30,26 +30,16 @@ const TableOfContent = publicWidget.Widget.extend({
//--------------------------------------------------------------------------
/**
- * Initialize the top position of the snippet navbar according to the height
- * of the headers of the page.
- *
* @private
*/
- _initializeNavbarTopPosition: function () {
- let headerHeight = 0;
+ _updateTableOfContentNavbarPosition() {
+ let position = 0;
const $fixedElements = $('.o_top_fixed_element');
- _.each($fixedElements, el => headerHeight += $(el).outerHeight());
- this._updateTableOfContentNavbarPosition(headerHeight);
- },
- /**
- * @private
- * @param {number} position
- */
- _updateTableOfContentNavbarPosition: function (position) {
+ _.each($fixedElements, el => position += $(el).outerHeight());
const isHorizontalNavbar = this.$target.hasClass('s_table_of_content_horizontal_navbar');
this.$target.css('top', isHorizontalNavbar ? position : '');
this.$target.find('.s_table_of_content_navbar').css('top', isHorizontalNavbar ? '' : position + 20);
- $('body').scrollspy({target: '.s_table_of_content_navbar', offset: position + 100});
+ $().getScrollingElement().scrollspy({target: '.s_table_of_content_navbar', method: 'offset', offset: position + 100});
},
});
@@ -66,15 +56,15 @@ publicWidget.registry.anchorSlide.include({
* @override
* @private
*/
- _computeHeaderHeight: function () {
- let headerHeight = this._super(...arguments);
+ _computeExtraOffset() {
+ let extraOffset = this._super(...arguments);
if (this.$el.hasClass('table_of_content_link')) {
const tableOfContentNavbarEl = this.$el.closest('.s_table_of_content_navbar_sticky.s_table_of_content_horizontal_navbar');
if (tableOfContentNavbarEl.length > 0) {
- headerHeight += $(tableOfContentNavbarEl).outerHeight();
+ extraOffset += $(tableOfContentNavbarEl).outerHeight();
}
}
- return headerHeight;
+ return extraOffset;
},
});
diff --git a/addons/website/views/website_navbar_templates.xml b/addons/website/views/website_navbar_templates.xml
index 6537ed5e646..1126a8aaf5a 100644
--- a/addons/website/views/website_navbar_templates.xml
+++ b/addons/website/views/website_navbar_templates.xml
@@ -20,7 +20,7 @@
<t t-set="body_classname" t-value="(body_classname if body_classname else '') + (' o_connected_user' if env['ir.ui.view'].user_has_groups('base.group_user') else '')"/>
</xpath>
<xpath expr="//div[@id='wrapwrap']" position="before">
- <nav groups="base.group_user" t-if="website" id="oe_main_menu_navbar" class="o_main_navbar o_top_fixed_element">
+ <nav groups="base.group_user" t-if="website" id="oe_main_menu_navbar" class="o_main_navbar">
<ul id="oe_applications">
<li class="dropdown active">
<a class="dropdown-toggle full" data-toggle="dropdown" href="#" accesskey="h">