From a1521c2a9ac16ace9d5a23407edc548597b6b72f Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Thu, 26 Sep 2019 08:15:26 +0200 Subject: [PATCH] Add scrollIntoView to the component view --- src/canvas/index.js | 21 +++++++-------- src/dom_components/view/ComponentView.js | 34 +++++++++++++++++++++++- src/navigator/view/ItemView.js | 2 +- 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/canvas/index.js b/src/canvas/index.js index ef3c38838..2ba393213 100644 --- a/src/canvas/index.js +++ b/src/canvas/index.js @@ -30,7 +30,14 @@ * @module Canvas */ -import { on, off, hasDnd, getElement, getPointerEvent } from 'utils/mixins'; +import { + on, + off, + hasDnd, + getElement, + getPointerEvent, + getViewEl +} from 'utils/mixins'; import Droppable from 'utils/Droppable'; import defaults from './config/config'; import Canvas from './model/Canvas'; @@ -481,16 +488,8 @@ export default () => { */ scrollTo(el, opts = {}) { const elem = getElement(el); - const cv = this.getCanvasView(); - if (!elem) return; - - if (!cv.isElInViewport(elem) || opts.force) { - const opt = - typeof opts === 'object' - ? opts - : { behavior: 'smooth', block: 'nearest' }; - elem.scrollIntoView(opt); - } + const view = elem && getViewEl(elem); + view && view.scrollIntoView(opts); }, /** diff --git a/src/dom_components/view/ComponentView.js b/src/dom_components/view/ComponentView.js index 706a4aa8e..f038a2f04 100644 --- a/src/dom_components/view/ComponentView.js +++ b/src/dom_components/view/ComponentView.js @@ -4,7 +4,7 @@ import Components from '../model/Components'; import ComponentsView from './ComponentsView'; import Selectors from 'selector_manager/model/Selectors'; import { replaceWith } from 'utils/dom'; -import { setViewEl } from 'utils/mixins'; +import { setViewEl, getElRect } from 'utils/mixins'; export default Backbone.View.extend({ className() { @@ -371,6 +371,38 @@ export default Backbone.View.extend({ return container; }, + isInViewport() { + const { el } = this; + const elDoc = el.ownerDocument; + const { body } = elDoc; + const { frameElement } = elDoc.defaultView; + const { top, left } = getElRect(el); + + return ( + top >= 0 && + left >= 0 && + top <= frameElement.offsetHeight + body.scrollTop && + left <= frameElement.offsetWidth + body.scrollLeft + ); + }, + + scrollIntoView(opts = {}) { + if (!this.isInViewport() || opts.force) { + const { el } = this; + + // PATCH: scrollIntoView won't work with multiple requests from iframes + if (opts.behavior !== 'smooth') { + el.ownerDocument.defaultView.scrollTo(0, el.offsetTop); + } else { + el.scrollIntoView({ + behavior: 'smooth', + block: 'nearest', + ...opts + }); + } + } + }, + /** * Recreate the element of the view */ diff --git a/src/navigator/view/ItemView.js b/src/navigator/view/ItemView.js index 7afc1aec6..6078106e8 100644 --- a/src/navigator/view/ItemView.js +++ b/src/navigator/view/ItemView.js @@ -223,7 +223,7 @@ export default Backbone.View.extend({ const model = this.model; em.setSelected(model, { fromLayers: 1 }); const scroll = config.scrollCanvas; - scroll && em.get('Canvas').scrollTo(model, scroll); + scroll && model.views.forEach(view => view.scrollIntoView(scroll)); } },