From e60ddf0b0ab668201997b06c64b94577673622a6 Mon Sep 17 00:00:00 2001 From: yaisog Date: Thu, 30 Nov 2023 19:26:26 +0100 Subject: [PATCH] Handle switching the bound tiddler (#7868) --- core/modules/widgets/scrollable.js | 53 ++++++++++++++++++------------ 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/core/modules/widgets/scrollable.js b/core/modules/widgets/scrollable.js index b77d6a12b..f6cb5e67b 100644 --- a/core/modules/widgets/scrollable.js +++ b/core/modules/widgets/scrollable.js @@ -177,28 +177,28 @@ ScrollableWidget.prototype.render = function(parent,nextSibling) { if(this.scrollableBind) { // After a delay for rendering, scroll to the bound position setTimeout(this.updateScrollPositionFromBoundTiddler.bind(this),50); - // Save scroll position on DOM scroll event - var timeout; - this.outerDomNode.addEventListener("scroll",function(event) { - if(timeout) { - clearTimeout(timeout); - timeout = null; - } - timeout = setTimeout(function() { - var existingTiddler = self.wiki.getTiddler(self.scrollableBind), - newTiddlerFields = { - title: self.scrollableBind, - "scroll-left": self.outerDomNode.scrollLeft.toString(), - "scroll-top": self.outerDomNode.scrollTop.toString() - }; - if(!existingTiddler || (existingTiddler.fields["title"] !== newTiddlerFields["title"]) || (existingTiddler.fields["scroll-left"] !== newTiddlerFields["scroll-left"] || existingTiddler.fields["scroll-top"] !== newTiddlerFields["scroll-top"])) { - self.wiki.addTiddler(new $tw.Tiddler(existingTiddler,newTiddlerFields)); - } - },DEBOUNCE_INTERVAL); - }); + // Set up event listener + this.currentListener = this.listenerFunction.bind(this); + this.outerDomNode.addEventListener("scroll", this.currentListener); } }; +ScrollableWidget.prototype.listenerFunction = function(event) { + self = this; + clearTimeout(this.timeout); + this.timeout = setTimeout(function() { + var existingTiddler = self.wiki.getTiddler(self.scrollableBind), + newTiddlerFields = { + title: self.scrollableBind, + "scroll-left": self.outerDomNode.scrollLeft.toString(), + "scroll-top": self.outerDomNode.scrollTop.toString() + }; + if(!existingTiddler || (existingTiddler.fields["title"] !== newTiddlerFields["title"]) || (existingTiddler.fields["scroll-left"] !== newTiddlerFields["scroll-left"] || existingTiddler.fields["scroll-top"] !== newTiddlerFields["scroll-top"])) { + self.wiki.addTiddler(new $tw.Tiddler(existingTiddler,newTiddlerFields)); + } + }, DEBOUNCE_INTERVAL); +} + ScrollableWidget.prototype.updateScrollPositionFromBoundTiddler = function() { // Bail if we're running on the fakedom if(!this.outerDomNode.scrollTo) { @@ -243,8 +243,19 @@ ScrollableWidget.prototype.refresh = function(changedTiddlers) { this.refreshSelf(); return true; } - if(changedAttributes.bind || changedTiddlers[this.getAttribute("bind")]) { - this.updateScrollPositionFromBoundTiddler(); + // If the bound tiddler has changed, update the eventListener and update scroll position + if(changedAttributes["bind"]) { + if(this.currentListener) { + this.outerDomNode.removeEventListener("scroll", this.currentListener, false); + } + this.scrollableBind = this.getAttribute("bind"); + this.currentListener = this.listenerFunction.bind(this); + this.outerDomNode.addEventListener("scroll", this.currentListener); + setTimeout(this.updateScrollPositionFromBoundTiddler.bind(this),50); + } + // If a new scroll position was written into the tiddler, update scroll position + if(changedTiddlers[this.getAttribute("bind")]) { + setTimeout(this.updateScrollPositionFromBoundTiddler.bind(this),50); } return this.refreshChildren(changedTiddlers); };