Phase 2/4 done, working on phase 3/5

This commit is contained in:
Martino Ferrari
2026-04-24 15:46:04 +02:00
parent 9aa89cc0cf
commit 8b548ba1c2
43 changed files with 6800 additions and 156 deletions
+66
View File
@@ -0,0 +1,66 @@
import type { Interface, Widget, SignalRef } from './types';
/**
* Parse an interface XML string into an Interface object.
*
* Expected XML format:
* <interface name="..." version="1">
* <widget id="w1" type="textview" x="100" y="50" w="200" h="60">
* <signal ds="stub" name="sine_1hz" color="#ff0000"/>
* <option key="label" value="Sine 1Hz"/>
* </widget>
* </interface>
*/
export function parseInterface(xml: string): Interface {
const parser = new DOMParser();
const doc = parser.parseFromString(xml, 'application/xml');
// Check for parse errors
const parseError = doc.querySelector('parsererror');
if (parseError) {
throw new Error(`XML parse error: ${parseError.textContent}`);
}
const root = doc.documentElement;
if (root.tagName !== 'interface') {
throw new Error(`Expected root element <interface>, got <${root.tagName}>`);
}
const name = root.getAttribute('name') ?? 'Untitled';
const version = parseInt(root.getAttribute('version') ?? '1', 10);
const widgets: Widget[] = [];
for (const el of Array.from(root.children)) {
if (el.tagName !== 'widget') continue;
const id = el.getAttribute('id') ?? '';
const type = el.getAttribute('type') ?? 'unknown';
const x = parseFloat(el.getAttribute('x') ?? '0');
const y = parseFloat(el.getAttribute('y') ?? '0');
const w = parseFloat(el.getAttribute('w') ?? '100');
const h = parseFloat(el.getAttribute('h') ?? '60');
const signals: Array<SignalRef & { color?: string }> = [];
const options: Record<string, string> = {};
for (const child of Array.from(el.children)) {
if (child.tagName === 'signal') {
const ds = child.getAttribute('ds') ?? '';
const sigName = child.getAttribute('name') ?? '';
const color = child.getAttribute('color') ?? undefined;
signals.push({ ds, name: sigName, ...(color ? { color } : {}) });
} else if (child.tagName === 'option') {
const key = child.getAttribute('key');
const value = child.getAttribute('value');
if (key !== null && value !== null) {
options[key] = value;
}
}
}
widgets.push({ id, type, x, y, w, h, signals, options });
}
return { name, version, widgets };
}