68 lines
1.9 KiB
TypeScript
68 lines
1.9 KiB
TypeScript
/**
|
|
* Dynamic shape registry — replaces the 300-line switch in canvas.html
|
|
* and the 165-line if-chain in community-sync.ts.
|
|
*
|
|
* Each shape class registers itself with `fromData()` and `applyData()`,
|
|
* so creation and sync are fully data-driven.
|
|
*/
|
|
|
|
import type { FolkShape } from "./folk-shape";
|
|
import type { ShapeData } from "./community-sync";
|
|
|
|
export interface ShapeRegistration {
|
|
tagName: string;
|
|
/** The custom element class (must have fromData/applyData) */
|
|
elementClass: typeof HTMLElement & {
|
|
fromData?(data: ShapeData): HTMLElement;
|
|
};
|
|
}
|
|
|
|
class ShapeRegistry {
|
|
#registrations = new Map<string, ShapeRegistration>();
|
|
|
|
/** Register a shape type. */
|
|
register(tagName: string, elementClass: ShapeRegistration["elementClass"]): void {
|
|
this.#registrations.set(tagName, { tagName, elementClass });
|
|
}
|
|
|
|
/** Get registration for a tag name. */
|
|
getRegistration(tagName: string): ShapeRegistration | undefined {
|
|
return this.#registrations.get(tagName);
|
|
}
|
|
|
|
/** Create a new element from ShapeData using the class's static fromData(). */
|
|
createElement(data: ShapeData): HTMLElement | null {
|
|
const reg = this.#registrations.get(data.type);
|
|
if (!reg) return null;
|
|
|
|
if (typeof reg.elementClass.fromData === "function") {
|
|
return reg.elementClass.fromData(data);
|
|
}
|
|
|
|
// Fallback: basic createElement
|
|
const el = document.createElement(data.type);
|
|
el.id = data.id;
|
|
return el;
|
|
}
|
|
|
|
/** Update an existing element using its instance applyData(). */
|
|
updateElement(shape: any, data: ShapeData): void {
|
|
if (typeof shape.applyData === "function") {
|
|
shape.applyData(data);
|
|
}
|
|
}
|
|
|
|
/** List all registered tag names. */
|
|
listAll(): string[] {
|
|
return Array.from(this.#registrations.keys());
|
|
}
|
|
|
|
/** Check if a type is registered. */
|
|
has(tagName: string): boolean {
|
|
return this.#registrations.has(tagName);
|
|
}
|
|
}
|
|
|
|
/** Singleton registry instance. */
|
|
export const shapeRegistry = new ShapeRegistry();
|