blob: 3a5f269152a25778fe82f8522fc5b33a19a3ea58 (
plain)
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
|
class EditorModule {
constructor() {
this.commands = {};
this.terminal = null;
this._vfsPath = null;
}
requirements() {
return { met: true, missing: [] };
}
getHelpInfo() {
return {
'edit': 'Open the code editor for a VFS file (usage: edit <path>)',
};
}
registerCommands() {
this.commands['edit'] = (args) => this.edit(args);
}
edit(args) {
if (!args[0]) return this.terminal.print('Usage: edit <path>', 'warning');
const path = args.join(' ');
const modal = document.getElementById('code-editor');
const title = document.getElementById('code-editor-title');
const textarea = document.getElementById('code-editor-textarea');
if (!modal || !textarea) return this.terminal.print('Editor modal not found', 'error');
// Read existing file content or use empty for new files
const content = this.terminal.fs.readFile(path);
const fileContent = (content !== null && content !== false) ? content : '';
// Set up modal
this._vfsPath = path;
title.textContent = '📝 Editing: ' + path;
textarea.value = fileContent;
modal.style.display = 'flex';
textarea.focus();
// Override save button to write back to VFS
const saveBtn = modal.querySelector('.modal-footer .btn:last-child');
const cancelBtn = modal.querySelector('.modal-footer .btn-danger');
if (saveBtn) {
saveBtn._origOnclick = saveBtn.onclick;
saveBtn.onclick = async () => {
const code = textarea.value;
const ok = this.terminal.fs.writeFile(this._vfsPath, code);
if (ok) {
this.terminal.print('✅ Saved to ' + this._vfsPath, 'success');
// Mirror to _mods/ for test_module compatibility
const modMatch = this._vfsPath.match(/(?:^|\/)(\w+)\.js$/);
if (modMatch) {
const modName = modMatch[1];
this.terminal.fs.mkdirRecursive('_mods');
this.terminal.fs.writeFile('_mods/' + modName + '.js', code);
if (!this.terminal.fs.readFile('_mods/' + modName + '.orig.js')) {
this.terminal.fs.writeFile('_mods/' + modName + '.orig.js', 'placeholder');
}
this.terminal.print('📋 Mirrored to _mods/' + modName + '.js for live testing', 'info');
}
// Notify tutorial module for quest 4 (edit + save)
if (this.terminal.tutorialModule) {
this.terminal.tutorialModule.onFileSaved(this._vfsPath);
}
} else {
this.terminal.print('❌ Failed to save ' + this._vfsPath, 'error');
}
modal.style.display = 'none';
this._vfsPath = null;
// Restore original onclick handler
if (saveBtn._origOnclick) saveBtn.onclick = saveBtn._origOnclick;
delete saveBtn._origOnclick;
};
}
if (cancelBtn) {
cancelBtn._origOnclick = cancelBtn.onclick;
cancelBtn.onclick = () => {
modal.style.display = 'none';
this._vfsPath = null;
if (cancelBtn._origOnclick) cancelBtn.onclick = cancelBtn._origOnclick;
delete cancelBtn._origOnclick;
};
}
}
}
if (typeof window.webx11 !== 'undefined' && window.webx11) {
webx11.moduleManager.registerModule(new EditorModule(), 'https://webx11.duckdns.org/spaces/newos4/modules/ext/editor.js');
}
|