-
Notifications
You must be signed in to change notification settings - Fork 0
/
editor.js
138 lines (120 loc) · 4.76 KB
/
editor.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// editor.js
(async () => {
// Load Monaco Editor
await loadMonacoEditor();
// Import themes and languages
const { customThemes } = await import('./themes/index.js');
const { languages } = await import('./languages.js');
// Initialize the editor
initializeEditor(customThemes, languages);
})().catch(error => {
console.error('Error initializing the editor:', error);
});
/**
* Dynamically loads the Monaco Editor's loader script.
*/
function loadMonacoEditor() {
return new Promise((resolve, reject) => {
const loaderScript = document.createElement('script');
loaderScript.src = './monaco-editor/min/vs/loader.js';
loaderScript.onload = resolve;
loaderScript.onerror = reject;
document.head.appendChild(loaderScript);
});
}
/**
* Initializes the Monaco Editor with themes and languages.
* @param {Array} customThemes - Array of custom themes.
* @param {Array} languages - Array of available languages.
*/
function initializeEditor(customThemes = [], languages = []) {
require.config({
baseUrl: './monaco-editor/min',
paths: { 'vs': 'vs' },
});
require(['vs/editor/editor.main'], () => {
const themeSelect = document.getElementById('theme-select');
const languageSelect = document.getElementById('language-select');
// Define custom themes
customThemes.forEach(theme => {
monaco.editor.defineTheme(theme.name, theme.data);
});
// Built-in themes
const themes = [
{ value: 'vs', text: 'Visual Studio' },
{ value: 'vs-dark', text: 'Visual Studio Dark' },
{ value: 'hc-black', text: 'High Contrast Dark' },
// Add custom themes
...customThemes.map(theme => ({
value: theme.name,
text: theme.displayName || theme.name.replace(/-/g, ' '),
})),
];
// Populate theme options
populateSelect(themeSelect, themes, 'editorTheme', 'vs-dark');
// Populate language options
populateSelect(languageSelect, languages, 'editorLanguage', 'markdown');
// Create the editor instance
const editor = monaco.editor.create(document.getElementById('editor-container'), {
value: getInitialEditorContent(),
language: localStorage.getItem('editorLanguage') || 'markdown',
theme: localStorage.getItem('editorTheme') || 'vs-dark',
padding: { top: 20 },
automaticLayout: true,
fontFamily: 'JetBrains Mono, monospace',
fontSize: 14,
lineHeight: 20,
});
// Save content on every change
const saveStatus = document.getElementById('save-status');
let saveTimeout;
editor.onDidChangeModelContent(() => {
const editorContent = editor.getValue();
localStorage.setItem('editorContent', editorContent);
// Update save status
saveStatus.textContent = 'Saving...';
clearTimeout(saveTimeout);
saveTimeout = setTimeout(() => {
saveStatus.textContent = 'Saved';
}, 500);
});
// Event listeners for theme and language changes
themeSelect.addEventListener('change', event => {
const selectedTheme = event.target.value;
monaco.editor.setTheme(selectedTheme);
localStorage.setItem('editorTheme', selectedTheme);
});
languageSelect.addEventListener('change', event => {
const selectedLanguage = event.target.value;
monaco.editor.setModelLanguage(editor.getModel(), selectedLanguage);
localStorage.setItem('editorLanguage', selectedLanguage);
});
});
}
/**
* Populates a select element with options and handles persistence.
* @param {HTMLElement} selectElement - The select element to populate.
* @param {Array} options - The options to populate.
* @param {string} storageKey - The localStorage key for persistence.
* @param {string} defaultValue - The default value if none is stored.
*/
function populateSelect(selectElement, options, storageKey, defaultValue) {
const storedValue = localStorage.getItem(storageKey) || defaultValue;
options.forEach(option => {
const opt = document.createElement('option');
opt.value = option.value;
opt.textContent = option.text;
if (option.value === storedValue) {
opt.selected = true;
}
selectElement.appendChild(opt);
});
localStorage.setItem(storageKey, storedValue);
}
/**
* Retrieves the initial content for the editor.
* @returns {string} - The initial content.
*/
function getInitialEditorContent() {
return localStorage.getItem('editorContent') || '# Start Writing here\n';
}