Skip to content

Commit 67893b9

Browse files
fix: fix memory leaking in CodeEditor (open-webui#22110)
1 parent 2e8c4da commit 67893b9

2 files changed

Lines changed: 36 additions & 28 deletions

File tree

src/lib/components/common/CodeEditor.svelte

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
<script lang="ts">
2+
import '$lib/utils/codemirror';
3+
24
import { basicSetup, EditorView } from 'codemirror';
35
import { keymap, placeholder } from '@codemirror/view';
46
import { Compartment, EditorState } from '@codemirror/state';
57
68
import { acceptCompletion } from '@codemirror/autocomplete';
79
import { indentWithTab } from '@codemirror/commands';
810
9-
import { indentUnit, LanguageDescription } from '@codemirror/language';
11+
import { indentUnit } from '@codemirror/language';
1012
import { languages } from '@codemirror/language-data';
1113
1214
import { oneDark } from '@codemirror/theme-one-dark';
@@ -75,41 +77,16 @@
7577
export let id = '';
7678
export let lang = '';
7779
78-
let codeEditor;
80+
let codeEditor: EditorView | null = null;
7981
8082
export const focus = () => {
81-
codeEditor.focus();
83+
codeEditor?.focus();
8284
};
8385
8486
let isDarkMode = false;
8587
let editorTheme = new Compartment();
8688
let editorLanguage = new Compartment();
8789
88-
languages.push(
89-
LanguageDescription.of({
90-
name: 'HCL',
91-
extensions: ['hcl', 'tf'],
92-
load() {
93-
return import('codemirror-lang-hcl').then((m) => m.hcl());
94-
}
95-
})
96-
);
97-
languages.push(
98-
LanguageDescription.of({
99-
name: 'Elixir',
100-
extensions: ['ex', 'exs'],
101-
load() {
102-
return import('codemirror-lang-elixir').then((m) => m.elixir());
103-
}
104-
})
105-
);
106-
107-
// Add 'matlab' alias to Octave language (MATLAB-compatible syntax)
108-
const octaveLang = languages.find((l) => l.name === 'Octave');
109-
if (octaveLang && !octaveLang.alias.includes('matlab')) {
110-
octaveLang.alias.push('matlab');
111-
}
112-
11390
const getLang = async () => {
11491
const language = languages.find((l) => l.alias.includes(lang));
11592
return await language?.load();
@@ -326,6 +303,11 @@ print("${endTag}")
326303
return () => {
327304
observer.disconnect();
328305
document.removeEventListener('keydown', keydownHandler);
306+
// Must destroy EditorView so CodeMirror releases internal DOMObserver and DOM refs
307+
if (codeEditor) {
308+
codeEditor.destroy();
309+
codeEditor = null;
310+
}
329311
};
330312
});
331313

src/lib/utils/codemirror.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { LanguageDescription } from '@codemirror/language';
2+
import { languages } from '@codemirror/language-data';
3+
4+
const octaveLang = languages.find((l) => l.name === 'Octave');
5+
if (octaveLang) {
6+
(octaveLang.alias as string[]).push('matlab');
7+
}
8+
9+
languages.push(
10+
LanguageDescription.of({
11+
name: 'HCL',
12+
extensions: ['hcl', 'tf'],
13+
load() {
14+
return import('codemirror-lang-hcl').then((m) => m.hcl());
15+
}
16+
})
17+
);
18+
languages.push(
19+
LanguageDescription.of({
20+
name: 'Elixir',
21+
extensions: ['ex', 'exs'],
22+
load() {
23+
return import('codemirror-lang-elixir').then((m) => m.elixir());
24+
}
25+
})
26+
);

0 commit comments

Comments
 (0)