diff --git a/src/generators/template/bindings/each.js b/src/generators/template/bindings/each.js index 9701b06..e05623a 100644 --- a/src/generators/template/bindings/each.js +++ b/src/generators/template/bindings/each.js @@ -6,6 +6,7 @@ import { EACH_BINDING_TYPE } from '../constants' import { + cloneNodeWithoutSelectorAttribute, createRootNode, createSelectorProperties, createTemplateProperty, @@ -53,7 +54,14 @@ export default function createEachBinding(sourceNode, selectorAttribute, sourceF simplePropertyNode(BINDING_GET_KEY_KEY, attributeOrNull(keyAttribute)), simplePropertyNode(BINDING_CONDITION_KEY, attributeOrNull(ifAttribute)), createTemplateProperty(mightBeARiotComponent ? - [null, [tagBinding(sourceNode, null, sourceCode, sourceCode)]] : + [null, [ + tagBinding( + cloneNodeWithoutSelectorAttribute(sourceNode), + null, + sourceCode, + sourceCode + )] + ] : build(createRootNode(sourceNode), sourceCode, sourceCode) ), ...createSelectorProperties(selectorAttribute), diff --git a/src/generators/template/bindings/if.js b/src/generators/template/bindings/if.js index 26a3d6a..e903692 100644 --- a/src/generators/template/bindings/if.js +++ b/src/generators/template/bindings/if.js @@ -5,6 +5,7 @@ import { IF_BINDING_TYPE } from '../constants' import { + cloneNodeWithoutSelectorAttribute, createRootNode, createSelectorProperties, createTemplateProperty, @@ -44,7 +45,14 @@ export default function createIfBinding(sourceNode, selectorAttribute, sourceFil ), ...createSelectorProperties(selectorAttribute), createTemplateProperty(mightBeARiotComponent ? - [null, [tagBinding(sourceNode, null, sourceCode, sourceCode)]] : + [null, [ + tagBinding( + cloneNodeWithoutSelectorAttribute(sourceNode), + null, + sourceCode, + sourceCode + )] + ] : build(createRootNode(sourceNode), sourceCode, sourceCode) ) ]) diff --git a/src/generators/template/bindings/tag.js b/src/generators/template/bindings/tag.js index 884a5e7..26773a2 100644 --- a/src/generators/template/bindings/tag.js +++ b/src/generators/template/bindings/tag.js @@ -1,13 +1,14 @@ import { BINDING_ATTRIBUTES_KEY, BINDING_BINDINGS_KEY, - BINDING_COMPONENTS_KEY, + BINDING_GET_COMPONENT_KEY, BINDING_HTML_KEY, BINDING_ID_KEY, + BINDING_NAME_KEY, BINDING_SLOTS_KEY, BINDING_TYPES, BINDING_TYPE_KEY, - COMPONENTS_REGISTRY, + GET_COMPONENT_FN, SLOT_ATTRIBUTE, TAG_BINDING_TYPE } from '../constants' @@ -95,11 +96,8 @@ export default function createTagBinding(sourceNode, selectorAttribute, sourceFi false ), ), - simplePropertyNode(BINDING_COMPONENTS_KEY, builders.memberExpression( - builders.identifier(COMPONENTS_REGISTRY), - builders.literal(getCustomNodeName(sourceNode)), - true - )), + simplePropertyNode(BINDING_GET_COMPONENT_KEY, builders.identifier(GET_COMPONENT_FN)), + simplePropertyNode(BINDING_NAME_KEY, builders.literal(getCustomNodeName(sourceNode))), simplePropertyNode(BINDING_SLOTS_KEY, builders.arrayExpression([ ...Object.entries(groupSlots(sourceNode)) .filter(([,value]) => value) diff --git a/src/generators/template/constants.js b/src/generators/template/constants.js index 3306296..142e6ea 100644 --- a/src/generators/template/constants.js +++ b/src/generators/template/constants.js @@ -14,11 +14,11 @@ export const EVENT_EXPRESSION_TYPE = 'EVENT' export const TEMPLATE_FN = 'template' export const SCOPE = 'scope' -export const COMPONENTS_REGISTRY = 'components' +export const GET_COMPONENT_FN = 'getComponent' // keys needed to create the DOM bindings export const BINDING_SELECTOR_KEY = 'selector' -export const BINDING_COMPONENTS_KEY = 'components' +export const BINDING_GET_COMPONENT_KEY = 'getComponent' export const BINDING_TEMPLATE_KEY = 'template' export const BINDING_TYPE_KEY = 'type' export const BINDING_REDUNDANT_ATTRIBUTE_KEY = 'redundantAttribute' diff --git a/src/generators/template/index.js b/src/generators/template/index.js index 071e13b..1c26ef1 100644 --- a/src/generators/template/index.js +++ b/src/generators/template/index.js @@ -1,4 +1,4 @@ -import {BINDING_TYPES, COMPONENTS_REGISTRY, EXPRESSION_TYPES, TEMPLATE_FN} from './constants' +import {BINDING_TYPES, EXPRESSION_TYPES, GET_COMPONENT_FN, TEMPLATE_FN} from './constants' import {builders, types} from '../../utils/build-types' import {callTemplateFunction, createRootNode} from './utils' import {TAG_TEMPLATE_PROPERTY} from '../constants' @@ -23,7 +23,7 @@ function extendTemplateProperty(ast, sourceFile, sourceCode, sourceNode) { TEMPLATE_FN, EXPRESSION_TYPES, BINDING_TYPES, - COMPONENTS_REGISTRY + GET_COMPONENT_FN ].map(builders.identifier), builders.blockStatement([ builders.returnStatement( diff --git a/src/generators/template/utils.js b/src/generators/template/utils.js index bc2d94e..fc72e7f 100644 --- a/src/generators/template/utils.js +++ b/src/generators/template/utils.js @@ -370,6 +370,19 @@ export function cleanAttributes(node) { ].includes(attribute.name)) } +/** + * Clone the node filtering out the selector attribute from the attributes list + * @param {RiotParser.Node} node - riot parser node + * @param {string} selectorAttribute - name of the selector attribute to filter out + * @returns {RiotParser.Node} the node with the attribute cleaned up + */ +export function cloneNodeWithoutSelectorAttribute(node, selectorAttribute) { + return { + ...node, + attributes: getNodeAttributes(node).filter(attribute => attribute.name !== selectorAttribute) + } +} + /** * Create a root node proxing only its nodes and attributes * @param {RiotParser.Node} node - riot parser node diff --git a/test/generators/template.spec.js b/test/generators/template.spec.js index d6c2920..146cd65 100644 --- a/test/generators/template.spec.js +++ b/test/generators/template.spec.js @@ -39,13 +39,13 @@ const getSlotById = (slots, id) => slots.find(slot => slot[BINDING_ID_KEY] === i const removeIdFromExpessionBindings = str => str.replace(/expr(\d+)/g, 'expr') const buildSimpleTemplate = compose(removeIdFromExpessionBindings, res => res[0], builder) -const evaluateOutput = (ast, components = {}) => evaluateScript(` +const evaluateOutput = (ast, getComponent = () => null) => evaluateScript(` import { bindingTypes, expressionTypes, template } from '@riotjs/dom-bindings' - export default function output(components) { + export default function output(getComponent) { return ${recast.print(ast).code} } -`).default(components) +`).default(getComponent) const parse = (input, options) => riotParser(options).parse(input).output describe('Generators - Template', () => {