Preserve the scroll position in CodeMirror on navigation
authorAlexander Ebert <ebert@woltlab.com>
Thu, 23 Jun 2022 13:21:43 +0000 (15:21 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Thu, 23 Jun 2022 13:21:43 +0000 (15:21 +0200)
The previous code stopped working after the update of CodeMirror.

See https://www.woltlab.com/community/thread/296010-nach-css-%C3%A4nderung-nicht-an-selber-stelle/

wcfsetup/install/files/acp/templates/codemirror.tpl

index 1abaf8ffa568defe3f38357d1f706eec38642439..effe606ea39c1b55f0c688f5711c157c5eb904ce 100644 (file)
@@ -42,7 +42,6 @@
                        document.head.appendChild(link);
                }
                
-               var elements = document.querySelectorAll('{@$codemirrorSelector|encodeJS}');
                var config = {
                        {if $codemirrorMode|isset}
                                {if $codemirrorMode === 'smartymixed'}
@@ -62,7 +61,7 @@
                        readOnly: {if !$editable|isset || $editable}false{else}true{/if}
                };
                
-               [].forEach.call(elements, function (element) {
+               document.querySelectorAll('{@$codemirrorSelector|encodeJS}').forEach((element) => {
                        {event name='javascriptInit'}
                        
                        if (element.codemirror) {
                                scrollOffsetStorage = scrollOffsetStorage.nextElementSibling;
                        } while (scrollOffsetStorage && !scrollOffsetStorage.classList.contains('codeMirrorScrollOffset'));
                        if (scrollOffsetStorage) {
-                               element.codemirror.scrollTo(null, scrollOffsetStorage.value);
+                               const offset = scrollOffsetStorage.value
                                element.codemirror.on('scroll', function (cm) {
                                        scrollOffsetStorage.value = cm.getScrollInfo().top;
                                });
+
+                               // Delay the scrolling to the next event cycle to allow
+                               // CodeMirror to fully initialize itself.
+                               setTimeout(() => {
+                                       element.codemirror.scrollTo(null, offset)
+                               }, 0);
                        }
                });
        });