This commit is contained in:
Martino Ferrari
2026-04-25 22:56:09 +02:00
parent 8b548ba1c2
commit 986f6cd6d8
85 changed files with 11479 additions and 5050 deletions
+39 -1
View File
@@ -1,5 +1,40 @@
import type { Interface, Widget, SignalRef } from './types';
/** Escape a string for use as an XML attribute value. */
function xmlEsc(s: string): string {
return s
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}
/** Serialize an Interface object to an XML string. */
export function serializeInterface(iface: Interface): string {
const lines: string[] = [];
lines.push(`<?xml version="1.0" encoding="UTF-8"?>`);
lines.push(
`<interface id="${xmlEsc(iface.id)}" name="${xmlEsc(iface.name)}" ` +
`version="${iface.version}" width="${iface.w}" height="${iface.h}">`
);
for (const w of iface.widgets) {
lines.push(
` <widget id="${xmlEsc(w.id)}" type="${xmlEsc(w.type)}" ` +
`x="${w.x}" y="${w.y}" w="${w.w}" h="${w.h}">`
);
for (const sig of w.signals) {
const colorAttr = sig.color ? ` color="${xmlEsc(sig.color)}"` : '';
lines.push(` <signal ds="${xmlEsc(sig.ds)}" name="${xmlEsc(sig.name)}"${colorAttr}/>`);
}
for (const [key, value] of Object.entries(w.options)) {
lines.push(` <option key="${xmlEsc(key)}" value="${xmlEsc(value)}"/>`);
}
lines.push(` </widget>`);
}
lines.push(`</interface>`);
return lines.join('\n');
}
/**
* Parse an interface XML string into an Interface object.
*
@@ -26,8 +61,11 @@ export function parseInterface(xml: string): Interface {
throw new Error(`Expected root element <interface>, got <${root.tagName}>`);
}
const ifaceId = root.getAttribute('id') ?? '';
const name = root.getAttribute('name') ?? 'Untitled';
const version = parseInt(root.getAttribute('version') ?? '1', 10);
const w = parseInt(root.getAttribute('width') ?? '1200', 10);
const h = parseInt(root.getAttribute('height') ?? '800', 10);
const widgets: Widget[] = [];
@@ -62,5 +100,5 @@ export function parseInterface(xml: string): Interface {
widgets.push({ id, type, x, y, w, h, signals, options });
}
return { name, version, widgets };
return { id: ifaceId, name, version, w, h, widgets };
}