Changeset 0.17.2 (#77)
This commit is contained in:
@@ -693,9 +693,40 @@ async function deleteAdminExtension(id, name) {
|
||||
} catch (e) { UI.toast(e.message, 'error'); }
|
||||
}
|
||||
|
||||
// Track CM6 editor instances per extension edit form
|
||||
var _extEditors = {};
|
||||
|
||||
// Listen for theme changes to update CM6 editors
|
||||
if (typeof Events !== 'undefined') {
|
||||
Events.on('theme.changed', (data) => {
|
||||
const isDark = data.resolved === 'dark';
|
||||
for (const editors of Object.values(_extEditors)) {
|
||||
editors.manifest?.setDarkMode(isDark);
|
||||
editors.script?.setDarkMode(isDark);
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for keymap changes to update CM6 editors in real time
|
||||
Events.on('keymap.changed', (data) => {
|
||||
const mode = data.mode || 'standard';
|
||||
for (const editors of Object.values(_extEditors)) {
|
||||
editors.manifest?.setKeymap(mode);
|
||||
editors.script?.setKeymap(mode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function editAdminExtension(id) {
|
||||
// Close any existing edit form
|
||||
document.querySelectorAll('.ext-edit-form').forEach(el => el.remove());
|
||||
// Close any existing edit form (and destroy CM6 instances)
|
||||
document.querySelectorAll('.ext-edit-form').forEach(el => {
|
||||
const eid = el.dataset.extId;
|
||||
if (_extEditors[eid]) {
|
||||
_extEditors[eid].manifest?.destroy();
|
||||
_extEditors[eid].script?.destroy();
|
||||
delete _extEditors[eid];
|
||||
}
|
||||
el.remove();
|
||||
});
|
||||
|
||||
const ext = (UI._adminExtensions || []).find(e => e.id === id);
|
||||
if (!ext) return UI.toast('Extension not found', 'error');
|
||||
@@ -716,6 +747,15 @@ function editAdminExtension(id) {
|
||||
</div>`
|
||||
: '';
|
||||
|
||||
// Use container divs instead of textareas when CM6 is available
|
||||
const useCM6 = !!window.CM?.codeEditor;
|
||||
const manifestEditor = useCM6
|
||||
? `<div id="extEdit-manifest-${id}" style="width:100%;min-height:180px;border:1px solid var(--border);border-radius:var(--radius,4px);overflow:hidden"></div>`
|
||||
: `<textarea id="extEdit-manifest-${id}" rows="8" style="width:100%;font-family:var(--mono);font-size:12px;tab-size:2">${esc(manifestJSON)}</textarea>`;
|
||||
const scriptEditor = useCM6
|
||||
? `<div id="extEdit-script-${id}" style="width:100%;min-height:320px;border:1px solid var(--border);border-radius:var(--radius,4px);overflow:hidden"></div>`
|
||||
: `<textarea id="extEdit-script-${id}" rows="16" style="width:100%;font-family:var(--mono);font-size:12px;tab-size:2;white-space:pre">${esc(script)}</textarea>`;
|
||||
|
||||
const formHTML = `
|
||||
<div class="ext-edit-form" data-ext-id="${id}" style="border-top:1px solid var(--border);padding:12px 0;margin-top:8px">
|
||||
${systemWarning}
|
||||
@@ -729,14 +769,14 @@ function editAdminExtension(id) {
|
||||
</div>
|
||||
<div class="form-group" style="margin-bottom:8px">
|
||||
<label style="font-size:12px;font-weight:600">Manifest JSON <span class="text-muted">(without _script)</span></label>
|
||||
<textarea id="extEdit-manifest-${id}" rows="8" style="width:100%;font-family:var(--mono);font-size:12px;tab-size:2">${esc(manifestJSON)}</textarea>
|
||||
${manifestEditor}
|
||||
</div>
|
||||
<div class="form-group" style="margin-bottom:8px">
|
||||
<label style="font-size:12px;font-weight:600">Script <span class="text-muted">(${script.length.toLocaleString()} chars)</span></label>
|
||||
<textarea id="extEdit-script-${id}" rows="16" style="width:100%;font-family:var(--mono);font-size:12px;tab-size:2;white-space:pre">${esc(script)}</textarea>
|
||||
${scriptEditor}
|
||||
</div>
|
||||
<div style="display:flex;gap:8px;justify-content:flex-end">
|
||||
<button class="btn-small" onclick="this.closest('.ext-edit-form').remove()">Cancel</button>
|
||||
<button class="btn-small" onclick="_closeExtEditForm('${id}')">Cancel</button>
|
||||
<button class="btn-small btn-primary" onclick="saveAdminExtension('${id}')">Save Changes</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -748,42 +788,80 @@ function editAdminExtension(id) {
|
||||
if (row.querySelector(`[onclick*="editAdminExtension('${id}')"]`)) {
|
||||
row.insertAdjacentHTML('afterend', formHTML);
|
||||
|
||||
// Tab key inserts tab in script textarea
|
||||
const scriptEl = document.getElementById(`extEdit-script-${id}`);
|
||||
if (scriptEl) {
|
||||
scriptEl.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Tab') {
|
||||
e.preventDefault();
|
||||
const start = scriptEl.selectionStart;
|
||||
const end = scriptEl.selectionEnd;
|
||||
scriptEl.value = scriptEl.value.substring(0, start) + ' ' + scriptEl.value.substring(end);
|
||||
scriptEl.selectionStart = scriptEl.selectionEnd = start + 4;
|
||||
}
|
||||
});
|
||||
if (useCM6) {
|
||||
// Get user keybinding preference
|
||||
const prefs = JSON.parse(localStorage.getItem('cs-appearance') || '{}');
|
||||
const keymapMode = prefs.editorKeymap || 'standard';
|
||||
|
||||
// Initialize CM6 editors
|
||||
_extEditors[id] = {
|
||||
manifest: CM.codeEditor(document.getElementById(`extEdit-manifest-${id}`), {
|
||||
language: 'json',
|
||||
value: manifestJSON,
|
||||
lineNumbers: true,
|
||||
keymap: keymapMode,
|
||||
}),
|
||||
script: CM.codeEditor(document.getElementById(`extEdit-script-${id}`), {
|
||||
language: 'javascript',
|
||||
value: script,
|
||||
lineNumbers: true,
|
||||
keymap: keymapMode,
|
||||
}),
|
||||
};
|
||||
} else {
|
||||
// Fallback: Tab key inserts tab in script textarea
|
||||
const scriptEl = document.getElementById(`extEdit-script-${id}`);
|
||||
if (scriptEl) {
|
||||
scriptEl.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Tab') {
|
||||
e.preventDefault();
|
||||
const start = scriptEl.selectionStart;
|
||||
const end = scriptEl.selectionEnd;
|
||||
scriptEl.value = scriptEl.value.substring(0, start) + ' ' + scriptEl.value.substring(end);
|
||||
scriptEl.selectionStart = scriptEl.selectionEnd = start + 4;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _closeExtEditForm(id) {
|
||||
if (_extEditors[id]) {
|
||||
_extEditors[id].manifest?.destroy();
|
||||
_extEditors[id].script?.destroy();
|
||||
delete _extEditors[id];
|
||||
}
|
||||
document.querySelector(`.ext-edit-form[data-ext-id="${id}"]`)?.remove();
|
||||
}
|
||||
|
||||
async function saveAdminExtension(id) {
|
||||
const nameEl = document.getElementById(`extEdit-name-${id}`);
|
||||
const descEl = document.getElementById(`extEdit-desc-${id}`);
|
||||
const manifestEl = document.getElementById(`extEdit-manifest-${id}`);
|
||||
const scriptEl = document.getElementById(`extEdit-script-${id}`);
|
||||
if (!nameEl || !manifestEl || !scriptEl) return;
|
||||
|
||||
// Read from CM6 if available, otherwise from textarea
|
||||
const editors = _extEditors[id];
|
||||
const manifestText = editors?.manifest
|
||||
? editors.manifest.getValue()
|
||||
: document.getElementById(`extEdit-manifest-${id}`)?.value;
|
||||
const scriptText = editors?.script
|
||||
? editors.script.getValue()
|
||||
: document.getElementById(`extEdit-script-${id}`)?.value;
|
||||
|
||||
if (!nameEl || manifestText == null || scriptText == null) return;
|
||||
|
||||
// Parse manifest and merge _script back in
|
||||
let manifest;
|
||||
try {
|
||||
manifest = JSON.parse(manifestEl.value.trim() || '{}');
|
||||
manifest = JSON.parse((manifestText || '').trim() || '{}');
|
||||
} catch (e) {
|
||||
return UI.toast('Invalid manifest JSON: ' + e.message, 'error');
|
||||
}
|
||||
|
||||
const script = scriptEl.value;
|
||||
if (script.trim()) {
|
||||
manifest._script = script;
|
||||
if (scriptText.trim()) {
|
||||
manifest._script = scriptText;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -793,6 +871,7 @@ async function saveAdminExtension(id) {
|
||||
manifest: manifest,
|
||||
});
|
||||
UI.toast('Extension updated — reload page to apply changes');
|
||||
_closeExtEditForm(id);
|
||||
await UI.loadAdminExtensions();
|
||||
} catch (e) {
|
||||
UI.toast(e.message, 'error');
|
||||
|
||||
Reference in New Issue
Block a user