aboutsummaryrefslogtreecommitdiff
path: root/internal/admin
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-13 19:59:34 -0400
committerhistoria <[not public]>2026-07-13 19:59:34 -0400
commit223d198c95b64d3d803be5d914c5b899dd30c8eb (patch)
tree0ab3824cef83dc33dc2d4409b0e36f6b7d504379 /internal/admin
parent1bedf06969b8ab8e51dd4301a0831200df5c8f59 (diff)
downloadthehouseoficarus-223d198c95b64d3d803be5d914c5b899dd30c8eb.tar.gz
refactor(admin): simplify css and js of card collapsing and side bar directories
Diffstat (limited to 'internal/admin')
-rw-r--r--internal/admin/static/admin.css8
-rw-r--r--internal/admin/static/dropeditor.js28
-rw-r--r--internal/admin/static/editor.js53
-rw-r--r--internal/admin/static/hazardeditor.js48
-rw-r--r--internal/admin/static/itemeditor.js28
-rw-r--r--internal/admin/static/mobeditor.js28
-rw-r--r--internal/admin/static/moduleeditor.js60
-rw-r--r--internal/admin/static/objecteditor.js28
-rw-r--r--internal/admin/static/techeditor.js34
9 files changed, 154 insertions, 161 deletions
diff --git a/internal/admin/static/admin.css b/internal/admin/static/admin.css
index 42e5340..f6072ad 100644
--- a/internal/admin/static/admin.css
+++ b/internal/admin/static/admin.css
@@ -166,6 +166,10 @@ input.search-input{padding-right:24px;background-image:url("data:image/svg+xml,%
.dir-count{font-size:9px;color:#555}
.dir-items{padding-left:10px}
.dir-items .item{font-size:11px}
+details.dir-group summary.dir-header{list-style:none}
+details.dir-group summary.dir-header::-webkit-details-marker{display:none}
+.dir-group:not([open])>.dir-header .dir-arrow::before{content:'\25B6'}
+.dir-group[open]>.dir-header .dir-arrow::before{content:'\25BC'}
.dir-drop-target{background:rgba(15,52,96,.3)!important;outline:1px dashed var(--accent);outline-offset:-2px}
.editor-main pre{background:var(--input-bg);padding:12px;border-radius:4px;font-size:12px;overflow-x:auto;border:1px solid var(--border)}
.form-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:4px 10px}
@@ -266,6 +270,10 @@ g.ud-hover:hover text{font-weight:bold}
.obj-card-expand{width:18px;height:18px;padding:0;display:inline-flex;align-items:center;justify-content:center;font-size:9px;min-width:auto;background:rgba(255,255,255,0.07);color:#888;border:1px solid rgba(255,255,255,0.12);border-radius:3px;cursor:pointer;font-family:monospace;line-height:1;flex-shrink:0}
.obj-card-expand:hover{color:var(--text);border-color:var(--border);background:rgba(255,255,255,0.12)}
.obj-card-body{padding:10px 12px}
+details.obj-card summary.obj-card-header{list-style:none}
+details.obj-card summary.obj-card-header::-webkit-details-marker{display:none}
+.obj-card:not([open])>.obj-card-header .obj-card-arrow::before{content:'\25B6'}
+.obj-card[open]>.obj-card-header .obj-card-arrow::before{content:'\25BC'}
.obj-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:6px 8px}
.obj-field{display:flex;flex-direction:column;gap:2px;font-size:11px}
.obj-field span{color:#888;font-size:9px;text-transform:uppercase;letter-spacing:.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
diff --git a/internal/admin/static/dropeditor.js b/internal/admin/static/dropeditor.js
index e8ade87..029b983 100644
--- a/internal/admin/static/dropeditor.js
+++ b/internal/admin/static/dropeditor.js
@@ -77,6 +77,9 @@ function renderDropEditor(id, data) {
html += '</div>';
$('#editorMain').innerHTML = html;
+ document.querySelectorAll('details.obj-card').forEach(function(d) {
+ d.addEventListener('toggle', function() { expandedCards[d.getAttribute('data-card')] = d.open; });
+ });
setupSearchFields();
setupDropEditorDropView();
}
@@ -88,21 +91,19 @@ function renderCurrent() {
}
function renderCard(sec, data) {
- var collapsed = expandedCards[sec.id] === false;
+ var openAttr = expandedCards[sec.id] === false ? '' : ' open';
var isFull = cardWidths[sec.id] !== undefined ? cardWidths[sec.id] : (sec.fullWidth || false);
var fullClass = isFull ? ' obj-card-full' : '';
- var h = '<div class="obj-card' + fullClass + '" data-card="' + sec.id + '">';
- h += '<div class="obj-card-header" onclick="toggleCard(\'' + sec.id + '\')">';
- h += '<span class="obj-card-arrow">' + (collapsed ? '&#9654;' : '&#9660;') + '</span>';
+ var h = '<details class="obj-card' + fullClass + '" data-card="' + sec.id + '"' + openAttr + '>';
+ h += '<summary class="obj-card-header">';
+ h += '<span class="obj-card-arrow"></span>';
h += '<span class="obj-card-label">' + sec.label + '</span>';
- h += '<button class="btn btn-sm obj-card-expand" onclick="event.stopPropagation();toggleCardWidth(\'' + sec.id + '\')" title="' + (isFull ? 'Half width' : 'Full width') + '">' + (isFull ? '\u2190' : '\u2192') + '</button>';
- h += '</div>';
- if (!collapsed) {
- h += '<div class="obj-card-body">';
- h += renderArraySection(sec, data);
- h += '</div>';
- }
+ h += '<button class="btn btn-sm obj-card-expand" onclick="event.preventDefault();toggleCardWidth(\'' + sec.id + '\')" title="' + (isFull ? 'Half width' : 'Full width') + '">' + (isFull ? '\u2190' : '\u2192') + '</button>';
+ h += '</summary>';
+ h += '<div class="obj-card-body">';
+ h += renderArraySection(sec, data);
h += '</div>';
+ h += '</details>';
return h;
}
@@ -159,11 +160,6 @@ function addDropRow(cardID, kind) {
renderCurrent();
}
-function toggleCard(id) {
- expandedCards[id] = expandedCards[id] === false ? true : false;
- renderCurrent();
-}
-
function toggleCardWidth(id) {
cardWidths[id] = !cardWidths[id];
renderCurrent();
diff --git a/internal/admin/static/editor.js b/internal/admin/static/editor.js
index 593bf7f..7a4fcb1 100644
--- a/internal/admin/static/editor.js
+++ b/internal/admin/static/editor.js
@@ -3,7 +3,7 @@ var editorFields = [];
var currentID = null;
var allIDs = [];
var treeData = { root: [], dirs: {} };
-var collapsedDirs = {};
+var dirOpenState = {};
function initEditor(type, fields) {
editorType = type;
@@ -49,6 +49,12 @@ function renderList(filter) {
}
el.innerHTML = html;
+ el.querySelectorAll('details.dir-group').forEach(function(d) {
+ d.addEventListener('toggle', function() {
+ var n = d.getAttribute('data-name');
+ if (n) dirOpenState[n] = d.open;
+ });
+ });
}
function renderDirGroup(name, ids, filter) {
@@ -59,30 +65,37 @@ function renderDirGroup(name, ids, filter) {
displayIds = ids.filter(function(id) { return String(id).toLowerCase().indexOf(filter) >= 0; });
if (displayIds.length === 0) return '';
}
- var expanded = isFiltering ? true : (collapsedDirs[name] === true);
- var displayName = name || editorType.charAt(0).toUpperCase() + editorType.slice(1);
- var h = '<div class="dir-group">';
- if (name) {
- h += '<div class="dir-header" onclick="toggleDir(\'' + escAttr(name) + '\')" oncontextmenu="showDirContextMenu(event,\'' + escAttr(name) + '\')" ondragover="dirDragOver(event,\'' + escAttr(name) + '\')" ondragleave="dirDragLeave(event)" ondrop="dirDrop(event,\'' + escAttr(name) + '\')">';
- h += '<span class="dir-arrow">' + (expanded ? '&#9660;' : '&#9654;') + '</span>';
- h += '<span class="dir-name">' + esc(displayName) + '</span>';
- h += '<span class="dir-count">' + (isFiltering ? displayIds.length + '/' + ids.length : ids.length) + '</span>';
- h += '</div>';
+
+ function renderItems() {
+ var h = '';
+ displayIds.forEach(function(id) {
+ h += '<div class="item' + (id === currentID ? ' active' : '') + '" onclick="loadItem(\'' + esc(id) + '\')" draggable="true" ondragstart="itemDragStart(event,\'' + escAttr(id) + '\')" oncontextmenu="showItemContextMenu(event,\'' + escAttr(id) + '\')">' + esc(id) + '</div>';
+ });
+ return h;
}
- h += '<div class="dir-items"' + (name && !expanded ? ' style="display:none"' : '') + ' ondragover="dirDragOver(event,\'' + (name || '') + '\')" ondragleave="dirDragLeave(event)" ondrop="dirDrop(event,\'' + (name || '') + '\')">';
- displayIds.forEach(function(id) {
- h += '<div class="item' + (id === currentID ? ' active' : '') + '" onclick="loadItem(\'' + esc(id) + '\')" draggable="true" ondragstart="itemDragStart(event,\'' + escAttr(id) + '\')" oncontextmenu="showItemContextMenu(event,\'' + escAttr(id) + '\')">' + esc(id) + '</div>';
- });
- h += '</div>';
+
+ if (!name) {
+ var fh = '<div class="dir-items" ondragover="dirDragOver(event,\'\')" ondragleave="dirDragLeave(event)" ondrop="dirDrop(event,\'\')">';
+ fh += renderItems();
+ fh += '</div>';
+ return fh;
+ }
+
+ var open = isFiltering || dirOpenState[name] === true;
+ var openAttr = open ? ' open' : '';
+ var h = '<details class="dir-group" data-name="' + escAttr(name) + '"' + openAttr + '>';
+ h += '<summary class="dir-header" oncontextmenu="showDirContextMenu(event,\'' + escAttr(name) + '\')" ondragover="dirDragOver(event,\'' + escAttr(name) + '\')" ondragleave="dirDragLeave(event)" ondrop="dirDrop(event,\'' + escAttr(name) + '\')">';
+ h += '<span class="dir-arrow"></span>';
+ h += '<span class="dir-name">' + esc(name) + '</span>';
+ h += '<span class="dir-count">' + (isFiltering ? displayIds.length + '/' + ids.length : ids.length) + '</span>';
+ h += '</summary>';
+ h += '<div class="dir-items" ondragover="dirDragOver(event,\'' + name + '\')" ondragleave="dirDragLeave(event)" ondrop="dirDrop(event,\'' + name + '\')">';
+ h += renderItems();
h += '</div>';
+ h += '</details>';
return h;
}
-function toggleDir(name) {
- collapsedDirs[name] = collapsedDirs[name] !== true;
- renderList('');
-}
-
function filterList(val) {
renderList(val);
}
diff --git a/internal/admin/static/hazardeditor.js b/internal/admin/static/hazardeditor.js
index 1f5fdf3..f85cde3 100644
--- a/internal/admin/static/hazardeditor.js
+++ b/internal/admin/static/hazardeditor.js
@@ -114,6 +114,9 @@ function renderHazardEditor(id, data) {
html += '</div>';
$('#editorMain').innerHTML = html;
+ document.querySelectorAll('details.obj-card').forEach(function(d) {
+ d.addEventListener('toggle', function() { expandedCards[d.getAttribute('data-card')] = d.open; });
+ });
setupSearchFields();
}
@@ -124,35 +127,33 @@ function renderCurrent() {
}
function renderCard(sec, data) {
- var collapsed = expandedCards[sec.id] === false;
+ var openAttr = expandedCards[sec.id] === false ? '' : ' open';
var isFull = cardWidths[sec.id] !== undefined ? cardWidths[sec.id] : (sec.fullWidth || false);
var fullClass = isFull ? ' obj-card-full' : '';
- var h = '<div class="obj-card' + fullClass + '" data-card="' + sec.id + '">';
- h += '<div class="obj-card-header" onclick="toggleCard(\'' + sec.id + '\')">';
- h += '<span class="obj-card-arrow">' + (collapsed ? '&#9654;' : '&#9660;') + '</span>';
+ var h = '<details class="obj-card' + fullClass + '" data-card="' + sec.id + '"' + openAttr + '>';
+ h += '<summary class="obj-card-header">';
+ h += '<span class="obj-card-arrow"></span>';
h += '<span class="obj-card-label">' + sec.label + '</span>';
- h += '<button class="btn btn-sm obj-card-expand" onclick="event.stopPropagation();toggleCardWidth(\'' + sec.id + '\')" title="' + (isFull ? 'Half width' : 'Full width') + '">' + (isFull ? '\u2190' : '\u2192') + '</button>';
+ h += '<button class="btn btn-sm obj-card-expand" onclick="event.preventDefault();toggleCardWidth(\'' + sec.id + '\')" title="' + (isFull ? 'Half width' : 'Full width') + '">' + (isFull ? '\u2190' : '\u2192') + '</button>';
if (!sec.always) {
- h += '<button class="btn btn-sm btn-danger obj-card-remove" onclick="event.stopPropagation();removeSection(\'' + sec.id + '\')">X</button>';
+ h += '<button class="btn btn-sm btn-danger obj-card-remove" onclick="event.preventDefault();removeSection(\'' + sec.id + '\')">X</button>';
}
- h += '</div>';
- if (!collapsed) {
- h += '<div class="obj-card-body">';
- if (sec.id === 'combat') {
- h += renderHazardCombatCard(data);
- } else {
- h += '<div class="obj-card-grid">';
- sec.fields.forEach(function(f) {
- h += renderField(sec, f, data, -1);
- });
- h += '</div>';
- if (sec.id === 'core') {
- h += ced_renderTagHelp('color');
- }
- }
+ h += '</summary>';
+ h += '<div class="obj-card-body">';
+ if (sec.id === 'combat') {
+ h += renderHazardCombatCard(data);
+ } else {
+ h += '<div class="obj-card-grid">';
+ sec.fields.forEach(function(f) {
+ h += renderField(sec, f, data, -1);
+ });
h += '</div>';
+ if (sec.id === 'core') {
+ h += ced_renderTagHelp('color');
+ }
}
h += '</div>';
+ h += '</details>';
return h;
}
@@ -160,11 +161,6 @@ function renderField(sec, f, data, idx) {
return ced_renderField(sec, f, data, idx, null, null, cardPath, fieldID, getVal);
}
-function toggleCard(id) {
- expandedCards[id] = expandedCards[id] === false ? true : false;
- renderCurrent();
-}
-
function toggleCardWidth(id) {
cardWidths[id] = !cardWidths[id];
renderCurrent();
diff --git a/internal/admin/static/itemeditor.js b/internal/admin/static/itemeditor.js
index 2283c91..4097e64 100644
--- a/internal/admin/static/itemeditor.js
+++ b/internal/admin/static/itemeditor.js
@@ -216,6 +216,9 @@ function renderItemEditor(id, data) {
html += '</div>';
$('#editorMain').innerHTML = html;
+ document.querySelectorAll('details.obj-card').forEach(function(d) {
+ d.addEventListener('toggle', function() { expandedCards[d.getAttribute('data-card')] = d.open; });
+ });
setupSearchFields();
setupCraftTypeChange();
setupEquipTypeChange();
@@ -238,20 +241,19 @@ function renderCurrent() {
// =========================================================================
function renderCard(sec, data) {
- var collapsed = expandedCards[sec.id] === false;
+ var openAttr = expandedCards[sec.id] === false ? '' : ' open';
var isFull = cardWidths[sec.id] !== undefined ? cardWidths[sec.id] : (sec.fullWidth || false);
var fullClass = isFull ? ' obj-card-full' : '';
- var h = '<div class="obj-card' + fullClass + '" data-card="' + sec.id + '">';
- h += '<div class="obj-card-header" onclick="toggleCard(\'' + sec.id + '\')">';
- h += '<span class="obj-card-arrow">' + (collapsed ? '&#9654;' : '&#9660;') + '</span>';
+ var h = '<details class="obj-card' + fullClass + '" data-card="' + sec.id + '"' + openAttr + '>';
+ h += '<summary class="obj-card-header">';
+ h += '<span class="obj-card-arrow"></span>';
h += '<span class="obj-card-label">' + sec.label + '</span>';
- h += '<button class="btn btn-sm obj-card-expand" onclick="event.stopPropagation();toggleCardWidth(\'' + sec.id + '\')" title="' + (isFull ? 'Half width' : 'Full width') + '">' + (isFull ? '\u2190' : '\u2192') + '</button>';
+ h += '<button class="btn btn-sm obj-card-expand" onclick="event.preventDefault();toggleCardWidth(\'' + sec.id + '\')" title="' + (isFull ? 'Half width' : 'Full width') + '">' + (isFull ? '\u2190' : '\u2192') + '</button>';
if (!sec.always) {
- h += '<button class="btn btn-sm btn-danger obj-card-remove" onclick="event.stopPropagation();removeSection(\'' + sec.id + '\')">X</button>';
+ h += '<button class="btn btn-sm btn-danger obj-card-remove" onclick="event.preventDefault();removeSection(\'' + sec.id + '\')">X</button>';
}
- h += '</div>';
- if (!collapsed) {
- h += '<div class="obj-card-body">';
+ h += '</summary>';
+ h += '<div class="obj-card-body">';
if (sec.isArray) {
if (sec.interactionStyle) {
@@ -315,8 +317,7 @@ function renderCard(sec, data) {
}
}
h += '</div>';
- }
- h += '</div>';
+ h += '</details>';
return h;
}
@@ -1031,11 +1032,6 @@ function renderKV(sec, il, data, keyOptions) {
// Card toggle / section add-remove
// =========================================================================
-function toggleCard(id) {
- expandedCards[id] = expandedCards[id] === false ? true : false;
- renderCurrent();
-}
-
function toggleCardWidth(id) {
cardWidths[id] = !cardWidths[id];
renderCurrent();
diff --git a/internal/admin/static/mobeditor.js b/internal/admin/static/mobeditor.js
index 05d33da..2bef881 100644
--- a/internal/admin/static/mobeditor.js
+++ b/internal/admin/static/mobeditor.js
@@ -207,6 +207,9 @@ function renderMobEditor(id, data) {
html += '</div>';
$('#editorMain').innerHTML = html;
+ document.querySelectorAll('details.obj-card').forEach(function(d) {
+ d.addEventListener('toggle', function() { expandedCards[d.getAttribute('data-card')] = d.open; });
+ });
ced_setupSearchFields();
setupMobProtectedToggle();
applyTaskVisibility();
@@ -230,20 +233,19 @@ function renderCurrent() {
// ---- Card rendering ----
function renderMobCard(sec, data) {
- var collapsed = expandedCards[sec.id] === false;
+ var openAttr = expandedCards[sec.id] === false ? '' : ' open';
var isFull = cardWidths[sec.id] !== undefined ? cardWidths[sec.id] : (sec.fullWidth || false);
var fullClass = isFull ? ' obj-card-full' : '';
- var h = '<div class="obj-card' + fullClass + '" data-card="' + sec.id + '">';
- h += '<div class="obj-card-header" onclick="toggleMobCard(\'' + sec.id + '\')">';
- h += '<span class="obj-card-arrow">' + (collapsed ? '&#9654;' : '&#9660;') + '</span>';
+ var h = '<details class="obj-card' + fullClass + '" data-card="' + sec.id + '"' + openAttr + '>';
+ h += '<summary class="obj-card-header">';
+ h += '<span class="obj-card-arrow"></span>';
h += '<span class="obj-card-label">' + sec.label + '</span>';
- h += '<button class="btn btn-sm obj-card-expand" onclick="event.stopPropagation();toggleMobCardWidth(\'' + sec.id + '\')" title="' + (isFull ? 'Half width' : 'Full width') + '">' + (isFull ? '\u2190' : '\u2192') + '</button>';
+ h += '<button class="btn btn-sm obj-card-expand" onclick="event.preventDefault();toggleMobCardWidth(\'' + sec.id + '\')" title="' + (isFull ? 'Half width' : 'Full width') + '">' + (isFull ? '\u2190' : '\u2192') + '</button>';
if (!sec.always) {
- h += '<button class="btn btn-sm btn-danger obj-card-remove" onclick="event.stopPropagation();removeMobSection(\'' + sec.id + '\')">X</button>';
+ h += '<button class="btn btn-sm btn-danger obj-card-remove" onclick="event.preventDefault();removeMobSection(\'' + sec.id + '\')">X</button>';
}
- h += '</div>';
- if (!collapsed) {
- h += '<div class="obj-card-body">';
+ h += '</summary>';
+ h += '<div class="obj-card-body">';
if (sec.id === 'core') {
h += renderMobCoreCard(data);
@@ -284,9 +286,8 @@ function renderMobCard(sec, data) {
h += '<div id="talktree"></div>';
}
}
- h += '</div>';
- }
h += '</div>';
+ h += '</details>';
return h;
}
@@ -746,11 +747,6 @@ function renderMobTableSubtable(sec, st, arr) {
// ---- Card toggle / section add-remove ----
-function toggleMobCard(id) {
- expandedCards[id] = expandedCards[id] === false ? true : false;
- renderCurrent();
-}
-
function toggleMobCardWidth(id) {
cardWidths[id] = !cardWidths[id];
renderCurrent();
diff --git a/internal/admin/static/moduleeditor.js b/internal/admin/static/moduleeditor.js
index b2eb79f..ff9d8a4 100644
--- a/internal/admin/static/moduleeditor.js
+++ b/internal/admin/static/moduleeditor.js
@@ -106,6 +106,9 @@ function renderModuleEditor(id, data) {
html += '</div>';
$('#editorMain').innerHTML = html;
+ document.querySelectorAll('details.obj-card').forEach(function(d) {
+ d.addEventListener('toggle', function() { expandedCards[d.getAttribute('data-card')] = d.open; });
+ });
setupSearchFields();
}
@@ -116,43 +119,41 @@ function renderCurrent() {
}
function renderCard(sec, data) {
- var collapsed = expandedCards[sec.id] === false;
+ var openAttr = expandedCards[sec.id] === false ? '' : ' open';
var isFull = cardWidths[sec.id] !== undefined ? cardWidths[sec.id] : (sec.fullWidth || false);
var fullClass = isFull ? ' obj-card-full' : '';
- var h = '<div class="obj-card' + fullClass + '" data-card="' + sec.id + '">';
- h += '<div class="obj-card-header" onclick="toggleCard(\'' + sec.id + '\')">';
- h += '<span class="obj-card-arrow">' + (collapsed ? '&#9654;' : '&#9660;') + '</span>';
+ var h = '<details class="obj-card' + fullClass + '" data-card="' + sec.id + '"' + openAttr + '>';
+ h += '<summary class="obj-card-header">';
+ h += '<span class="obj-card-arrow"></span>';
h += '<span class="obj-card-label">' + sec.label + '</span>';
- h += '<button class="btn btn-sm obj-card-expand" onclick="event.stopPropagation();toggleCardWidth(\'' + sec.id + '\')" title="' + (isFull ? 'Half width' : 'Full width') + '">' + (isFull ? '\u2190' : '\u2192') + '</button>';
+ h += '<button class="btn btn-sm obj-card-expand" onclick="event.preventDefault();toggleCardWidth(\'' + sec.id + '\')" title="' + (isFull ? 'Half width' : 'Full width') + '">' + (isFull ? '\u2190' : '\u2192') + '</button>';
if (!sec.always) {
- h += '<button class="btn btn-sm btn-danger obj-card-remove" onclick="event.stopPropagation();removeSection(\'' + sec.id + '\')">X</button>';
+ h += '<button class="btn btn-sm btn-danger obj-card-remove" onclick="event.preventDefault();removeSection(\'' + sec.id + '\')">X</button>';
}
- h += '</div>';
- if (!collapsed) {
- h += '<div class="obj-card-body">';
+ h += '</summary>';
+ h += '<div class="obj-card-body">';
- if (sec.isArray) {
- h += renderArraySection(sec, data);
- } else {
- h += '<div class="obj-card-grid">';
- sec.fields.forEach(function(f) {
- h += renderField(sec, f, data, -1);
+ if (sec.isArray) {
+ h += renderArraySection(sec, data);
+ } else {
+ h += '<div class="obj-card-grid">';
+ sec.fields.forEach(function(f) {
+ h += renderField(sec, f, data, -1);
+ });
+ h += '</div>';
+
+ if (sec.inline) {
+ sec.inline.forEach(function(il) {
+ if (il.type === 'kv') {
+ h += ced_renderKV(sec, il, data);
+ } else if (il.type === 'kv_search') {
+ h += ced_renderKVSearch(sec, il, data);
+ }
});
- h += '</div>';
-
- if (sec.inline) {
- sec.inline.forEach(function(il) {
- if (il.type === 'kv') {
- h += ced_renderKV(sec, il, data);
- } else if (il.type === 'kv_search') {
- h += ced_renderKVSearch(sec, il, data);
- }
- });
- }
}
- h += '</div>';
}
h += '</div>';
+ h += '</details>';
return h;
}
@@ -177,11 +178,6 @@ function renderField(sec, f, data, idx) {
return ced_renderField(sec, f, data, idx, null, null, cardPath, fieldID, getVal);
}
-function toggleCard(id) {
- expandedCards[id] = expandedCards[id] === false ? true : false;
- renderCurrent();
-}
-
function toggleCardWidth(id) {
cardWidths[id] = !cardWidths[id];
renderCurrent();
diff --git a/internal/admin/static/objecteditor.js b/internal/admin/static/objecteditor.js
index 363cca9..15b656b 100644
--- a/internal/admin/static/objecteditor.js
+++ b/internal/admin/static/objecteditor.js
@@ -173,6 +173,9 @@ function renderObjectEditor(id, data) {
html += '</div>';
$('#editorMain').innerHTML = html;
+ document.querySelectorAll('details.obj-card').forEach(function(d) {
+ d.addEventListener('toggle', function() { expandedCards[d.getAttribute('data-card')] = d.open; });
+ });
setupSearchFields();
setupObjectDropViews();
setTimeout(function() {
@@ -204,24 +207,23 @@ function fieldIDSub(sec, subKey, idx, fieldKey) {
}
function renderCard(sec, data) {
- var collapsed = expandedCards[sec.id] === false;
+ var openAttr = expandedCards[sec.id] === false ? '' : ' open';
var isFull = cardWidths[sec.id] !== undefined ? cardWidths[sec.id] : (sec.fullWidth || false);
var fullClass = isFull ? ' obj-card-full' : '';
- var h = '<div class="obj-card' + fullClass + '" data-card="' + sec.id + '">';
- h += '<div class="obj-card-header" onclick="toggleCard(\'' + sec.id + '\')">';
- h += '<span class="obj-card-arrow">' + (collapsed ? '&#9654;' : '&#9660;') + '</span>';
+ var h = '<details class="obj-card' + fullClass + '" data-card="' + sec.id + '"' + openAttr + '>';
+ h += '<summary class="obj-card-header">';
+ h += '<span class="obj-card-arrow"></span>';
h += '<span class="obj-card-label">' + sec.label;
if (sec.labelHint) {
h += ' <span style="color:#666;font-size:10px;font-weight:normal">' + esc(sec.labelHint) + '</span>';
}
h += '</span>';
- h += '<button class="btn btn-sm obj-card-expand" onclick="event.stopPropagation();toggleCardWidth(\'' + sec.id + '\')" title="' + (isFull ? 'Half width' : 'Full width') + '">' + (isFull ? '\u2190' : '\u2192') + '</button>';
+ h += '<button class="btn btn-sm obj-card-expand" onclick="event.preventDefault();toggleCardWidth(\'' + sec.id + '\')" title="' + (isFull ? 'Half width' : 'Full width') + '">' + (isFull ? '\u2190' : '\u2192') + '</button>';
if (!sec.always) {
- h += '<button class="btn btn-sm btn-danger obj-card-remove" onclick="event.stopPropagation();removeSection(\'' + sec.id + '\')">X</button>';
+ h += '<button class="btn btn-sm btn-danger obj-card-remove" onclick="event.preventDefault();removeSection(\'' + sec.id + '\')">X</button>';
}
- h += '</div>';
- if (!collapsed) {
- h += '<div class="obj-card-body">';
+ h += '</summary>';
+ h += '<div class="obj-card-body">';
if (sec.isArray) {
h += renderArraySection(sec, data);
@@ -325,9 +327,8 @@ function renderCard(sec, data) {
h += ced_renderTagHelp('gather');
}
}
- h += '</div>';
- }
h += '</div>';
+ h += '</details>';
return h;
}
@@ -731,11 +732,6 @@ function syncGatherToolsFromDOM() {
}
}
-function toggleCard(id) {
- expandedCards[id] = expandedCards[id] === false ? true : false;
- renderCurrent();
-}
-
function toggleCardWidth(id) {
cardWidths[id] = !cardWidths[id];
renderCurrent();
diff --git a/internal/admin/static/techeditor.js b/internal/admin/static/techeditor.js
index 812cded..020ba11 100644
--- a/internal/admin/static/techeditor.js
+++ b/internal/admin/static/techeditor.js
@@ -95,6 +95,9 @@ function renderTechEditor(id, data) {
html += '</div>';
$('#editorMain').innerHTML = html;
+ document.querySelectorAll('details.obj-card').forEach(function(d) {
+ d.addEventListener('toggle', function() { expandedCards[d.getAttribute('data-card')] = d.open; });
+ });
setupSearchFields();
}
@@ -105,25 +108,23 @@ function renderCurrent() {
}
function renderCard(sec, data) {
- var collapsed = expandedCards[sec.id] === false;
+ var openAttr = expandedCards[sec.id] === false ? '' : ' open';
var isFull = cardWidths[sec.id] !== undefined ? cardWidths[sec.id] : (sec.fullWidth || false);
var fullClass = isFull ? ' obj-card-full' : '';
- var h = '<div class="obj-card' + fullClass + '" data-card="' + sec.id + '">';
- h += '<div class="obj-card-header" onclick="toggleCard(\'' + sec.id + '\')">';
- h += '<span class="obj-card-arrow">' + (collapsed ? '&#9654;' : '&#9660;') + '</span>';
+ var h = '<details class="obj-card' + fullClass + '" data-card="' + sec.id + '"' + openAttr + '>';
+ h += '<summary class="obj-card-header">';
+ h += '<span class="obj-card-arrow"></span>';
h += '<span class="obj-card-label">' + sec.label + '</span>';
- h += '<button class="btn btn-sm obj-card-expand" onclick="event.stopPropagation();toggleCardWidth(\'' + sec.id + '\')" title="' + (isFull ? 'Half width' : 'Full width') + '">' + (isFull ? '\u2190' : '\u2192') + '</button>';
+ h += '<button class="btn btn-sm obj-card-expand" onclick="event.preventDefault();toggleCardWidth(\'' + sec.id + '\')" title="' + (isFull ? 'Half width' : 'Full width') + '">' + (isFull ? '\u2190' : '\u2192') + '</button>';
+ h += '</summary>';
+ h += '<div class="obj-card-body">';
+ h += '<div class="obj-card-grid">';
+ sec.fields.forEach(function(f) {
+ h += renderField(sec, f, data, -1);
+ });
h += '</div>';
- if (!collapsed) {
- h += '<div class="obj-card-body">';
- h += '<div class="obj-card-grid">';
- sec.fields.forEach(function(f) {
- h += renderField(sec, f, data, -1);
- });
- h += '</div>';
- h += '</div>';
- }
h += '</div>';
+ h += '</details>';
return h;
}
@@ -131,11 +132,6 @@ function renderField(sec, f, data, idx) {
return ced_renderField(sec, f, data, idx, null, null, cardPath, fieldID, getVal);
}
-function toggleCard(id) {
- expandedCards[id] = expandedCards[id] === false ? true : false;
- renderCurrent();
-}
-
function toggleCardWidth(id) {
cardWidths[id] = !cardWidths[id];
renderCurrent();