UNPKG

docxml

Version:

TypeScript (component) library for building and parsing a DOCX file

80 lines (79 loc) 3.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.jsx = void 0; const Component_js_1 = require("../classes/Component.js"); const Text_js_1 = require("../components/Text.js"); /** * The JSX pragma with which you can write `<Paragraph>` instead of `new Paragraph({})`. * * Also exposed as the `jsx` prop on the (static) class as well as instance of this library's top- * level API -- see also {@link Api}. */ async function jsx(component, props, ...children) { const flattenedChildren = await children // Flatten the children, which may themselves have been wrapped in an array because they // contained invalid children. // Moreover, any component might at this point still be only the promise thereof. Resolve all. .reduce(async function flatten(flatPromise, childPromise) { const child = await childPromise; const flat = await flatPromise; return Array.isArray(child) ? [...flat, ...(await child.reduce(flatten, Promise.resolve([])))] : [...flat, child]; }, Promise.resolve([])); return (flattenedChildren // Add the node, if it is valid, or add the node split into pieces with the invalid children // vertically inserted between .reduce((nodes, child) => { if (typeof child === 'string' && (0, Component_js_1.isComponentDefinition)(component) && !component.mixed) { child = new Text_js_1.Text({}, child); } const isValid = !(0, Component_js_1.isComponentDefinition)(component) || (component.mixed && typeof child === 'string') || component.children.includes(child.constructor.name); if (!isValid) { if (child.constructor === Text_js_1.Text && component === Text_js_1.Text) { Object.assign(child.props, props); } nodes.push(child); } else { const lastQueuedItem = nodes[nodes.length - 1]; if (typeof lastQueuedItem === 'string' || lastQueuedItem instanceof Component_js_1.Component) { // Queue this item as a simple object, so that its children can be changed // in the next iteration. nodes.push({ component, props, children: [child], }); } else { lastQueuedItem.children.push(child); } } return nodes; }, [{ component, props, children: [] }]) // Instantiate the "queued" items (props/children that haven't been instantiated yet so that // their children could be shuffled around). .map((node) => { if (typeof node === 'string') { return node; } if (node instanceof Component_js_1.Component) { return node; } if ((0, Component_js_1.isComponentDefinition)(component)) { return new component(node.props || {}, ...(node.children || [])); } else { const x = component({ ...props, children: node.children || [] }); return x; } }) // Flatten again, no telling what came out of a ComponentFunction .reduce((flat, thing) => (Array.isArray(thing) ? [...flat, ...thing] : [...flat, thing]), []) // Remove empty Text components, they don't do anything .filter((node) => !(node.constructor === Text_js_1.Text && !node.children.length))); } exports.jsx = jsx;