@@ -104,13 +104,37 @@ private function injectWebSocketClient(string $html): string
104104 //Read html and inject script before closing body tag
105105 $ injection = <<<'EOT'
106106<script>
107- const socket = new WebSocket(' ws://' + window.location.host + '/ws');
107+ const socket = new WebSocket((window.location.protocol === 'https:' ? 'wss://' : ' ws://') + window.location.host + '/ws');
108108 socket.addEventListener('message', function (event) {
109109 if (event.data === 'update') {
110- console.log('Reloading page due to server change...');
110+ console.log('Reloading page due to server change... Stored scrollPosition: ' + window.scrollY);
111+ sessionStorage.setItem('scrollPosition', window.scrollY);
112+ sessionStorage.setItem('scrollURL', window.location.href);
111113 window.location.reload();
112114 }
113115 });
116+
117+ // Restore scroll position after page loads. Note that sessionStorage is
118+ // browser-tab specific, so multiple instances should not affect each other.
119+ window.addEventListener('load', function() {
120+ const scrollPosition = sessionStorage.getItem('scrollPosition');
121+ const scrollURL = sessionStorage.getItem('scrollURL');
122+
123+ // Only restore if we're on the same URL (hot reload, not navigation)
124+ if (scrollPosition !== null && scrollURL === window.location.href) {
125+ console.log('Prepare to restore scrollPosition to: ' + scrollPosition);
126+
127+ // Use setTimeout to override hash scrolling that happens after load
128+ setTimeout(function() {
129+ console.log('Restoring scrollPosition to: ' + scrollPosition);
130+ window.scrollTo(0, parseInt(scrollPosition));
131+ }, 10);
132+ }
133+
134+ // Ensure local scroll position is reset, so other reloads to not carry state.
135+ sessionStorage.removeItem('scrollPosition');
136+ sessionStorage.removeItem('scrollURL');
137+ });
114138</script>
115139EOT;
116140
0 commit comments