From 4ad779b07ffa5b6e05a45c75b04fff27da3666a1 Mon Sep 17 00:00:00 2001 From: "Laurent Stukkens (LTU)" Date: Thu, 20 Aug 2020 12:09:02 +0000 Subject: [PATCH] [IMP] web, website: prevent auto scroll from left panel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Prior to this commit, when starting to drag a new snippet from the left panel, the auto scroll feature was triggered if the snippet was one of the top or bottom ones. * After this commit, the auto scroll feature will be disabled from the left panel. task-2307404 closes odoo/odoo#57449 X-original-commit: f1f48cdaab3dd7847e8546ad9887f24a9e2ed4c1 Related: odoo/enterprise#13139 Signed-off-by: Jérémy Kersten (jke) --- .../src/js/core/smooth_scroll_on_drag.js | 77 ++++++++++++------- .../static/src/js/editor/snippets.editor.js | 3 + 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/addons/web/static/src/js/core/smooth_scroll_on_drag.js b/addons/web/static/src/js/core/smooth_scroll_on_drag.js index a53323174cf..28a4beff4c4 100644 --- a/addons/web/static/src/js/core/smooth_scroll_on_drag.js +++ b/addons/web/static/src/js/core/smooth_scroll_on_drag.js @@ -66,18 +66,28 @@ const SmoothScrollOnDrag = Class.extend(mixins.ParentedMixin, { * @param {Number} [options.scrollStep=20] (Integer) The step of the scroll. * @param {Number} [options.scrollTimerInterval=5] (Integer) The interval (in ms) the * scrollStep will be applied. + * @param {Object} [options.scrollBoundaries = {}] Specifies whether scroll can still be triggered + * when dragging $element outside of target. + * @param {Object} [options.scrollBoundaries.top = true] Specifies whether scroll can still be triggered + * when dragging $element above the top edge of target. + * @param {Object} [options.scrollBoundaries.right = true] Specifies whether scroll can still be triggered + * when dragging $element after the right edge of target. + * @param {Object} [options.scrollBoundaries.bottom = true] Specifies whether scroll can still be triggered + * when dragging $element bellow the bottom edge of target. + * @param {Object} [options.scrollBoundaries.left = true] Specifies whether scroll can still be triggered + * when dragging $element before the left edge of target. * @param {Object} [options.offsetElements={}] Visible elements in $scrollTarget that - * reduce $scrollTarget drag visible area (scroll will be triggered sooner that - * normally). A selector is passed so that elements such automatically hidden + * reduce $scrollTarget drag visible area (scroll will be triggered sooner than + * normally). A selector is passed so that elements such as automatically hidden * menu can then be correctly handled. - * @param {jQuery} [options.offsetElements.$top={}] Visible top element which height will + * @param {jQuery} [options.offsetElements.$top] Visible top offset element which height will * be taken into account when triggering scroll at the top of the $scrollTarget. - * @param {jQuery} [options.offsetElements.$right={}] Visible right element which width + * @param {jQuery} [options.offsetElements.$right] Visible right offset element which width * will be taken into account when triggering scroll at the right side of the * $scrollTarget. - * @param {jQuery} [options.offsetElements.$bottom={}] Visible bottom element which height + * @param {jQuery} [options.offsetElements.$bottom] Visible bottom offset element which height * will be taken into account when triggering scroll at bottom of the $scrollTarget. - * @param {jQuery} [options.offsetElements.$left={}] Visible right element which width + * @param {jQuery} [options.offsetElements.$left] Visible left offset element which width * will be taken into account when triggering scroll at the left side of the * $scrollTarget. */ @@ -99,6 +109,12 @@ const SmoothScrollOnDrag = Class.extend(mixins.ParentedMixin, { this.options.scrollTimerInterval = this.options.scrollTimerInterval || 5; this.options.offsetElements = this.options.offsetElements || {}; this.options.offsetElementsManager = new OffsetElementsHelper(this.options.offsetElements); + this.options.scrollBoundaries = Object.assign({ + top: true, + right: true, + bottom: true, + left: true + }, this.options.scrollBoundaries); this.autoScrollHandler = null; @@ -255,28 +271,37 @@ const SmoothScrollOnDrag = Class.extend(mixins.ParentedMixin, { horizontal: this.scrollStepDirectionEnum.right, }; - // Manage vertical scroll - if (visibleOffset.bottom <= this.options.scrollOffsetThreshold) { - scrollDecelerator.vertical = Math.max(0, visibleOffset.bottom) - / this.options.scrollOffsetThreshold; - } else if (visibleOffset.top <= this.options.scrollOffsetThreshold) { - scrollDecelerator.vertical = Math.max(0, visibleOffset.top) - / this.options.scrollOffsetThreshold; - scrollStepDirection.vertical = this.scrollStepDirectionEnum.up; + // Prevent scroll if outside of scroll boundaries + if ((!this.options.scrollBoundaries.top && visibleOffset.top < 0) || + (!this.options.scrollBoundaries.right && visibleOffset.right < 0) || + (!this.options.scrollBoundaries.bottom && visibleOffset.bottom < 0) || + (!this.options.scrollBoundaries.left && visibleOffset.left < 0)) { + scrollDecelerator.horizontal = 1; + scrollDecelerator.vertical = 1; } else { - scrollDecelerator.vertical = 1; - } + // Manage vertical scroll + if (visibleOffset.bottom <= this.options.scrollOffsetThreshold) { + scrollDecelerator.vertical = Math.max(0, visibleOffset.bottom) + / this.options.scrollOffsetThreshold; + } else if (visibleOffset.top <= this.options.scrollOffsetThreshold) { + scrollDecelerator.vertical = Math.max(0, visibleOffset.top) + / this.options.scrollOffsetThreshold; + scrollStepDirection.vertical = this.scrollStepDirectionEnum.up; + } else { + scrollDecelerator.vertical = 1; + } - // Manage horizontal scroll - if (visibleOffset.right <= this.options.scrollOffsetThreshold) { - scrollDecelerator.horizontal = Math.max(0, visibleOffset.right) - / this.options.scrollOffsetThreshold; - } else if (visibleOffset.left <= this.options.scrollOffsetThreshold) { - scrollDecelerator.horizontal = Math.max(0, visibleOffset.left) - / this.options.scrollOffsetThreshold; - scrollStepDirection.horizontal = this.scrollStepDirectionEnum.left; - } else { - scrollDecelerator.horizontal = 1; + // Manage horizontal scroll + if (visibleOffset.right <= this.options.scrollOffsetThreshold) { + scrollDecelerator.horizontal = Math.max(0, visibleOffset.right) + / this.options.scrollOffsetThreshold; + } else if (visibleOffset.left <= this.options.scrollOffsetThreshold) { + scrollDecelerator.horizontal = Math.max(0, visibleOffset.left) + / this.options.scrollOffsetThreshold; + scrollStepDirection.horizontal = this.scrollStepDirectionEnum.left; + } else { + scrollDecelerator.horizontal = 1; + } } this.verticalDelta = Math.ceil(scrollStepDirection.vertical * diff --git a/addons/web_editor/static/src/js/editor/snippets.editor.js b/addons/web_editor/static/src/js/editor/snippets.editor.js index 11a21715c9a..bb9438bad9a 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -1791,6 +1791,9 @@ var SnippetsMenu = Widget.extend({ $top: $('#web_editor-top-edit'), // TODO should ideally be retrieved another way $left: this.$el, }, options.offsetElements), + scrollBoundaries: Object.assign({ + left: false, + }, options.scrollBoundaries), jQueryDraggableOptions: Object.assign({ appendTo: this.$body, cursor: 'move',