Phase 6
This commit is contained in:
+39
-1
@@ -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, '<')
|
||||
.replace(/>/g, '>');
|
||||
}
|
||||
|
||||
/** 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 };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user