From 80c5ea93e4c10cf15f8c710c8814802204cfef2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Bu=CC=88nemann?= Date: Sat, 2 Dec 2017 13:21:30 +0100 Subject: [PATCH] Prevent scroll to top after FastBoot rehydration If the page was rendered by FastBoot and then rehydrated on the client, we should not jump to the top, because the user might have already scrolled down on the prerendered page while rehydration was running. --- addon/mixins/scroll-operator.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/addon/mixins/scroll-operator.js b/addon/mixins/scroll-operator.js index 30cedb6..2308567 100644 --- a/addon/mixins/scroll-operator.js +++ b/addon/mixins/scroll-operator.js @@ -48,13 +48,19 @@ export default Mixin.create({ * now to resume watching scroll position. */ setupController(...args) { - const [ controller ] = args; + const [ controller, , transition ] = args; this._super(...args); if (controller && (!this.get('fastboot') || !this.get('fastboot.isFastBoot'))) { run.schedule('afterRender', null, () => { - $(window).scrollTop(controller.getWithDefault('currentPosition', 0)); + /* + * The first transition for FastBoot sites should not scroll to top + * to prevent an unwanted jump back to top after DOM rehydration. + */ + if (!this._isFirstFastBootTransition(transition)) { + $(window).scrollTop(controller.getWithDefault('currentPosition', 0)); + } this._attachEvents(); }); } @@ -86,6 +92,13 @@ export default Mixin.create({ return transition && transition.sequence > 1 && transition.hasOwnProperty('urlMethod'); }, + /** + * Determine if transition is entry transition in FastBoot client side environment. + */ + _isFirstFastBootTransition(transition) { + return transition && !transition.sequence && this.get('fastboot') && !this.get('fastboot.isFastBoot'); + }, + /** * Set currentPosition to $(window).scrollTop value. */