diff --git a/packages/game/src/js/SJDON.js b/packages/game/src/js/SJDON.js new file mode 100644 index 0000000..10b888f0 --- /dev/null +++ b/packages/game/src/js/SJDON.js @@ -0,0 +1,51 @@ +/** + * Renders the specified {@link data `data`} and appends it to the specified {@link element `element`}. + * + * @param {NodeDescriptor} data + * The node to render written in SJDON notation. + * + * @param {HTMLElement} element + * The element to add the rendered node to. + */ +export function render(data, element) +{ + if (Array.isArray(data)) + { + let descriptor = data[0]; + let args = data.slice(1); + + if (typeof descriptor === "function") + { + render(descriptor(...args), element); + } + else if (typeof descriptor === "string") + { + let result = element.ownerDocument.createElement(descriptor); + element.appendChild(result); + + for (let arg of args) + { + if (typeof arg === "object" && !Array.isArray(arg)) + { + Object.assign(result, arg); + } + else + { + render(arg, result); + } + } + } + else + { + throw new SyntaxError(); + } + } + else if (typeof data === "string") + { + element.appendChild(element.ownerDocument.createTextNode(data)); + } + else + { + throw new SyntaxError(); + } +} diff --git a/packages/game/src/js/types.d.ts b/packages/game/src/js/types.d.ts index a2a4c52..8386c02 100644 --- a/packages/game/src/js/types.d.ts +++ b/packages/game/src/js/types.d.ts @@ -28,3 +28,31 @@ interface IState */ board: Board; } + +/** + * Represents a node in the SJDON notation. + */ +type NodeDescriptor = + TextDescriptor | + ElementDescriptor | + FunctionNode; + +/** + * Represents a text-node in the SJDON notation. + */ +type TextDescriptor = string; + +/** + * Represents an html-element in the SJDON notation. + */ +type ElementDescriptor = [ + tag: string, + ...args: NodeDescriptor[] +]; + +/** + * Represents a component in the SJDON notation. + */ +type FunctionNode = [ + fn: (...args: any[]) => NodeDescriptor, ...args: any[] +];