/** * @typedef {import('estree-jsx').JSXAttribute} JSXAttribute * @typedef {import('estree-jsx').JSXClosingElement} JSXClosingElement * @typedef {import('estree-jsx').JSXClosingFragment} JSXClosingFragment * @typedef {import('estree-jsx').JSXElement} JSXElement * @typedef {import('estree-jsx').JSXExpressionContainer} JSXExpressionContainer * @typedef {import('estree-jsx').JSXFragment} JSXFragment * @typedef {import('estree-jsx').JSXIdentifier} JSXIdentifier * @typedef {import('estree-jsx').JSXMemberExpression} JSXMemberExpression * @typedef {import('estree-jsx').JSXNamespacedName} JSXNamespacedName * @typedef {import('estree-jsx').JSXOpeningElement} JSXOpeningElement * @typedef {import('estree-jsx').JSXOpeningFragment} JSXOpeningFragment * @typedef {import('estree-jsx').JSXSpreadAttribute} JSXSpreadAttribute * @typedef {import('estree-jsx').JSXText} JSXText * @typedef {import('./types.js').Generator} Generator * @typedef {import('./types.js').State} State */ export const jsx = { JSXAttribute, JSXClosingElement, JSXClosingFragment, JSXElement, JSXEmptyExpression, JSXExpressionContainer, JSXFragment, JSXIdentifier, JSXMemberExpression, JSXNamespacedName, JSXOpeningElement, JSXOpeningFragment, JSXSpreadAttribute, JSXText } /** * `attr` * `attr="something"` * `attr={1}` * * @this {Generator} * `astring` generator. * @param {JSXAttribute} node * Node to serialize. * @param {State} state * Info passed around. * @returns {void} * Nothing. */ function JSXAttribute(node, state) { this[node.name.type](node.name, state) if (node.value !== undefined && node.value !== null) { state.write('=') // Encode double quotes in attribute values. if (node.value.type === 'Literal') { state.write( '"' + encodeJsx(String(node.value.value)).replace(/"/g, '"') + '"', node ) } else { this[node.value.type](node.value, state) } } } /** * `` * * @this {Generator} * `astring` generator. * @param {JSXClosingElement} node * Node to serialize. * @param {State} state * Info passed around. * @returns {void} * Nothing. */ function JSXClosingElement(node, state) { state.write('') this[node.name.type](node.name, state) state.write('>') } /** * `>` * * @this {Generator} * `astring` generator. * @param {JSXClosingFragment} node * Node to serialize. * @param {State} state * Info passed around. * @returns {void} * Nothing. */ function JSXClosingFragment(node, state) { state.write('>', node) } /** * `
` * `` * * @this {Generator} * `astring` generator. * @param {JSXElement} node * Node to serialize. * @param {State} state * Info passed around. * @returns {void} * Nothing. */ function JSXElement(node, state) { let index = -1 this[node.openingElement.type](node.openingElement, state) if (node.children) { while (++index < node.children.length) { const child = node.children[index] // Supported in types but not by Acorn. /* c8 ignore next 3 */ if (child.type === 'JSXSpreadChild') { throw new Error('JSX spread children are not supported') } this[child.type](child, state) } } if (node.closingElement) { this[node.closingElement.type](node.closingElement, state) } } /** * `{}` (always in a `JSXExpressionContainer`, which does the curlies) * * @this {Generator} * `astring` generator. * @returns {void} * Nothing. */ function JSXEmptyExpression() {} /** * `{expression}` * * @this {Generator} * `astring` generator. * @param {JSXExpressionContainer} node * Node to serialize. * @param {State} state * Info passed around. * @returns {void} * Nothing. */ function JSXExpressionContainer(node, state) { state.write('{') this[node.expression.type](node.expression, state) state.write('}') } /** * `<>>` * * @this {Generator} * `astring` generator. * @param {JSXFragment} node * Node to serialize. * @param {State} state * Info passed around. * @returns {void} * Nothing. */ function JSXFragment(node, state) { let index = -1 this[node.openingFragment.type](node.openingFragment, state) if (node.children) { while (++index < node.children.length) { const child = node.children[index] // Supported in types but not by Acorn. /* c8 ignore next 3 */ if (child.type === 'JSXSpreadChild') { throw new Error('JSX spread children are not supported') } this[child.type](child, state) } } this[node.closingFragment.type](node.closingFragment, state) } /** * `div` * * @this {Generator} * `astring` generator. * @param {JSXIdentifier} node * Node to serialize. * @param {State} state * Info passed around. * @returns {void} * Nothing. */ function JSXIdentifier(node, state) { state.write(node.name, node) } /** * `member.expression` * * @this {Generator} * `astring` generator. * @param {JSXMemberExpression} node * Node to serialize. * @param {State} state * Info passed around. * @returns {void} * Nothing. */ function JSXMemberExpression(node, state) { this[node.object.type](node.object, state) state.write('.') this[node.property.type](node.property, state) } /** * `ns:name` * * @this {Generator} * `astring` generator. * @param {JSXNamespacedName} node * Node to serialize. * @param {State} state * Info passed around. * @returns {void} * Nothing. */ function JSXNamespacedName(node, state) { this[node.namespace.type](node.namespace, state) state.write(':') this[node.name.type](node.name, state) } /** * `