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
diff --git a/web/element/codemirror-element.ts b/web/element/codemirror-element.ts
index 7043344..7b1bf5a 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`;
+ }
+ }
}