Resize CodeMirror dynamically When you resize a window, CodeMirror will now resize dynamically without needing a page refresh. Video: https://imgur.com/a/VL9Zhax (first vid is before, second is after) Change-Id: Ia6823f9d7daef0cb6693a8768808e64b859d39b3 (cherry picked from commit f6f73e861f8175b43a5c562db2f953e2bb38a5aa)
diff --git a/web/element/codemirror-element.ts b/web/element/codemirror-element.ts index 038bf1d..27c6ef2 100644 --- a/web/element/codemirror-element.ts +++ b/web/element/codemirror-element.ts
@@ -62,6 +62,8 @@ private initialized = false; + private onResize: (() => void) | null = null; + static override get styles() { return [ css` @@ -120,20 +122,12 @@ if (this.initialized) return; this.initialized = true; - const offsetTop = this.getBoundingClientRect().top; - const clientHeight = window.innerHeight ?? document.body.clientHeight; - // We are setting a fixed height, because for large files we want to - // benefit from CodeMirror's virtual scrolling. - // 80px is roughly the size of the bottom margins plus the footer height. - // This ensures the height of the textarea doesn't push out of screen. - const height = clientHeight - offsetTop - 80; - const editor = new EditorView({ state: EditorState.create({ doc: this.fileContent ?? '', extensions: [ ...extensions( - height, + this.calculateHeight(), this.prefs, this.fileType, this.fileContent ?? '', @@ -200,6 +194,17 @@ // Makes sure to show line number and column number on initial // load. this.updateCursorPosition(editor); + + this.onResize = () => this.updateEditorHeight(editor); + window.addEventListener('resize', this.onResize); + } + + override disconnectedCallback() { + super.disconnectedCallback(); + if (this.onResize) { + window.removeEventListener('resize', this.onResize); + this.onResize = null; + } } setCursorToLine(view: EditorView, lineNum: number) { @@ -227,4 +232,21 @@ this.result.textContent = `Line: ${line.number}, Column: ${cursor - line.from + 1}`; } } + + private calculateHeight() { + const offsetTop = this.getBoundingClientRect().top; + const clientHeight = window.innerHeight ?? document.body.clientHeight; + // We take offsetTop twice to ensure the height of the texarea doesn't push + // out of screen. We no longer do a hardcore value which was 80 before. + // offsetTop seems to be what we've been looking for to do it dynamically. + return Math.max(0, clientHeight - offsetTop - offsetTop); + } + + private updateEditorHeight(editor: EditorView) { + const height = this.calculateHeight(); + const editorElement = editor.dom; + if (editorElement) { + editorElement.style.height = `${height}px`; + } + } }