From 9fce8153dfdd5e2378f1827425c5b1ebbd265df1 Mon Sep 17 00:00:00 2001 From: Saq Imtiaz Date: Mon, 24 Jan 2022 10:44:04 +0100 Subject: [PATCH] Add support to tm-scroll message for scrolling without animating (#6410) * feat: add support for animationDuration attribute of paramObject for tm-scroll message * docs: added docs for animationDuration attribute of tm-scroll message * fix: use .utils.hop instead of Object.hasOwnProperty() * fix: do not check if object before calling utils.hop() * fix: syntax --- core/modules/utils/dom/scroller.js | 18 +++++++++++------- core/modules/widgets/scrollable.js | 18 +++++++++++------- .../messages/WidgetMessage_ tm-scroll.tid | 3 +++ 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/core/modules/utils/dom/scroller.js b/core/modules/utils/dom/scroller.js index 8e49a1f1d..73be0f0a8 100644 --- a/core/modules/utils/dom/scroller.js +++ b/core/modules/utils/dom/scroller.js @@ -49,10 +49,14 @@ Handle an event */ PageScroller.prototype.handleEvent = function(event) { if(event.type === "tm-scroll") { + var options = {}; + if($tw.utils.hop(event.paramObject,"animationDuration")) { + options.animationDuration = event.paramObject.animationDuration; + } if(event.paramObject && event.paramObject.selector) { - this.scrollSelectorIntoView(null,event.paramObject.selector); + this.scrollSelectorIntoView(null,event.paramObject.selector,null,options); } else { - this.scrollIntoView(event.target); + this.scrollIntoView(event.target,null,options); } return false; // Event was handled } @@ -62,10 +66,10 @@ PageScroller.prototype.handleEvent = function(event) { /* Handle a scroll event hitting the page document */ -PageScroller.prototype.scrollIntoView = function(element,callback) { +PageScroller.prototype.scrollIntoView = function(element,callback,options) { var self = this, - duration = $tw.utils.getAnimationDuration(), - srcWindow = element ? element.ownerDocument.defaultView : window; + duration = $tw.utils.hop(options,"animationDuration") ? parseInt(options.animationDuration) : $tw.utils.getAnimationDuration(), + srcWindow = element ? element.ownerDocument.defaultView : window; // Now get ready to scroll the body this.cancelScroll(srcWindow); this.startTime = Date.now(); @@ -122,11 +126,11 @@ PageScroller.prototype.scrollIntoView = function(element,callback) { drawFrame(); }; -PageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) { +PageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) { baseElement = baseElement || document.body; var element = baseElement.querySelector(selector); if(element) { - this.scrollIntoView(element,callback); + this.scrollIntoView(element,callback,options); } }; diff --git a/core/modules/widgets/scrollable.js b/core/modules/widgets/scrollable.js index ddce42351..aadc040df 100644 --- a/core/modules/widgets/scrollable.js +++ b/core/modules/widgets/scrollable.js @@ -38,10 +38,14 @@ ScrollableWidget.prototype.handleScrollEvent = function(event) { if(this.outerDomNode.scrollWidth <= this.outerDomNode.offsetWidth && this.outerDomNode.scrollHeight <= this.outerDomNode.offsetHeight && this.fallthrough === "yes") { return true; } + var options = {}; + if($tw.utils.hop(event.paramObject,"animationDuration")) { + options.animationDuration = event.paramObject.animationDuration; + } if(event.paramObject && event.paramObject.selector) { - this.scrollSelectorIntoView(null,event.paramObject.selector); + this.scrollSelectorIntoView(null,event.paramObject.selector,null,options); } else { - this.scrollIntoView(event.target); + this.scrollIntoView(event.target,null,options); } return false; // Handled event }; @@ -49,9 +53,9 @@ ScrollableWidget.prototype.handleScrollEvent = function(event) { /* Scroll an element into view */ -ScrollableWidget.prototype.scrollIntoView = function(element) { - var duration = $tw.utils.getAnimationDuration(), - srcWindow = element ? element.ownerDocument.defaultView : window; +ScrollableWidget.prototype.scrollIntoView = function(element,callback,options) { + var duration = $tw.utils.hop(options,"animationDuration") ? parseInt(options.animationDuration) : $tw.utils.getAnimationDuration(), + srcWindow = element ? element.ownerDocument.defaultView : window; this.cancelScroll(); this.startTime = Date.now(); var scrollPosition = { @@ -114,11 +118,11 @@ ScrollableWidget.prototype.scrollIntoView = function(element) { } }; -ScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) { +ScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) { baseElement = baseElement || document.body; var element = baseElement.querySelector(selector); if(element) { - this.scrollIntoView(element,callback); + this.scrollIntoView(element,callback,options); } }; diff --git a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-scroll.tid b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-scroll.tid index 99b613422..047b7e45f 100644 --- a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-scroll.tid +++ b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-scroll.tid @@ -10,3 +10,6 @@ The `tm-scroll` message causes the surrounding scrollable container to scroll to |!Name |!Description | |target |Target DOM node the scrollable container should scroll to (note that this parameter can only be set via JavaScript code) | |selector |<<.from-version "5.1.23">> Optional string [[CSS selector|https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors]] as an alternate means of identifying the target DOM node | +|animationDuration |<<.from-version "5.2.2">> Optional number specifying the animation duration in milliseconds for the scrolling. Defaults to the [[global animation duration|$:/config/AnimationDuration]]. | + +<<.tip "Set `animationDuration` to `0` to scroll without animation">>