UNPKG

@player-ui/player

Version:

74 lines (66 loc) 1.95 kB
import { ViewInstance, ViewPlugin } from "../view"; import type { Parser, Node, ParseObjectOptions, ParseObjectChildOptions, } from "../parser"; import { NodeType } from "../parser"; import { hasTemplateValues, hasTemplateKey } from "../parser/utils"; /** A view plugin to resolve multi nodes */ export class MultiNodePlugin implements ViewPlugin { applyParser(parser: Parser): void { parser.hooks.parseNode.tap( "multi-node", ( obj: any, nodeType: Node.ChildrenTypes, options: ParseObjectOptions, childOptions?: ParseObjectChildOptions, ) => { if ( (childOptions === undefined || !hasTemplateKey(childOptions.key)) && Array.isArray(obj) ) { const values = obj .map((childVal) => parser.parseObject(childVal, NodeType.Value, options), ) .filter((child): child is Node.Node => !!child); if (!values.length) { return []; } const multiNode = parser.createASTNode( { type: NodeType.MultiNode, override: childOptions !== undefined && !hasTemplateValues(childOptions.parentObj, childOptions.key), values, }, obj, ); if (!multiNode) { return []; } if (multiNode.type === NodeType.MultiNode) { multiNode.values.forEach((v) => { v.parent = multiNode; }); } return childOptions === undefined ? multiNode : [ { path: [...childOptions.path, childOptions.key], value: multiNode, }, ]; } }, ); } apply(view: ViewInstance): void { view.hooks.parser.tap("multi-node", this.applyParser.bind(this)); } }