{"version":3,"sources":["template.ts"],"sourcesContent":["import { getCallerFile } from \"datex-core-legacy/utils/caller_metadata.ts\";\nimport { IS_TEMPLATE, SET_DEFAULT_ATTRIBUTES, SET_DEFAULT_CHILDREN } from \"../uix-dom/jsx/parser.ts\";\nimport { Component } from \"../components/Component.ts\";\nimport { DOMUtils } from \"../uix-dom/datex-bindings/dom-utils.ts\";\nimport { domContext, domUtils } from \"../app/dom-context.ts\";\nimport { initDefaultOptions } from \"../base/decorators.ts\";\nimport type { Class } from \"datex-core-legacy/utils/global_types.ts\";\nimport { METADATA } from \"datex-core-legacy/js_adapter/js_class_adapter.ts\";\nimport { MappedProps } from \"./template-types.ts\";\n\n/**\n * cloneNode(true), but also clones shadow roots.\n * @param element original element\n */\nfunction cloneWithShadowRoots(element:Node) {\n\tif (!(element instanceof domContext.Element)) return element.cloneNode(true);\n\n\tfunction walk(node:Element, clone:Element) {\n\t\tconst shadow = node.shadowRoot;\n\t\tif (shadow) {\n\t\tclone.attachShadow({ mode: shadow.mode }).append(...([].map.call(shadow.childNodes, (c:Node) => cloneWithListeners(c)) as Node[]));\n\t\t}\n\t\tfor (let i=0; i<node.children.length; i++) walk(node.children[i], clone.children[i]);\n\t}\n\tconst clone = cloneWithListeners(element) as Element;\n\twalk(element, clone);\n\n\t// add template content\n\tif (element instanceof domContext.HTMLTemplateElement) {\n\t\tfor (const node of element.content.childNodes as unknown as Node[]) (clone as HTMLTemplateElement).content.append(cloneWithShadowRoots(node))\n\t}\n\n\treturn clone;\n}\n\n/**\n * deep clone node, add listeners bound with [DOMUtils.EVENT_LISTENERS]\n * @param element\n * @returns \n */\nfunction cloneWithListeners(element: Node) {\n\t// cannot use cloneNode(true) because listeners have to be copied for all children\n\tconst clone = element.cloneNode(false);\n\tif (clone instanceof domContext.Element) {\n\t\tfor (const [event, listeners] of (<DOMUtils.elWithUIXAttributes>element)[DOMUtils.EVENT_LISTENERS]??[]) {\n\t\t\tfor (const [listener] of listeners) {\n\t\t\t\tdomUtils.setElementAttribute(clone, \"on\"+event, listener);\n\t\t\t}\n\t\t}\t\n\t}\n\t// clone children\n\tfor (const child of (element.childNodes as unknown as ChildNode[])) clone.appendChild(cloneWithListeners(child))\n\treturn clone;\t\n}\n\ntype childrenToArray<ChildOrChildren> = ChildOrChildren extends Array<any> ? ChildOrChildren : [ChildOrChildren]\n\ntype Equals<X, Y> =\n    (<T>() => T extends X ? 1 : 2) extends\n    (<T>() => T extends Y ? 1 : 2) ? true : false;\n\n\ntype Props<Options extends Record<string,unknown>, Children, handleAllProps = true, optionalChildren = false> = Options & \n(\n\thandleAllProps extends true ? \n\t\t(JSX._IntrinsicAttributes & \n\t\t\t(Equals<Children, undefined> extends true ? unknown : (Equals<Children, never> extends true ? unknown : (\n\t\t\t\toptionalChildren extends true ? \n\t\t\t\t\t{children?: Children} :\n\t\t\t\t\t{children: Children}\n\t\t\t)\n\t\t\t)) // TODO: optional children for JSX, but not for template callback function\n\t\t) : unknown\n)\n\nexport type jsxInputGenerator<\n\tReturn, \n\t_Props extends Record<string,unknown>, \n\tChildren, \n\thandleAllProps = true, \n\toptionalChildren = true, \n\tContext extends HTMLElement = HTMLElement\n> =\n\t(\n\t\tthis: Context,\n\t\tprops: Props<\n\t\t\t// inferred options:\n\t\t\tContext extends {properties: unknown} ? Context['properties'] : _Props\n\t\t\t, Children, handleAllProps, optionalChildren>,\n\t) => Return;\n\n\n\n/**\n * Define an HTML template that can be used as an anonymous JSX component.\n * Default HTML Attributes defined in JSX are also set for the root element.\n * Custom Attributes can be handled in the generator\n * @example\n * ```tsx\n * const CustomComponent = template<{color:string}>(({color}) => <div class='class1 class2' style={{color}}></div>)\n * // create:\n * const comp = <CustomComponent id=\"c1\" color=\"green\"/>\n * ```\n * By default, children are just appended to the root element of the template.\n * You can create a template with a shadow root by adding the 'shadow-root' attribute to the root element.\n * Children are appended to the <slot> element inside the root:\n * @example\n * ```tsx\n * const CustomComponent2 = template<{color:string}>(({color}) => \n * \t<div shadow-root>\n * \t    Custom content before children\n * \t\t<slot/>\n *      Custom content after children\n * \t</div>)\n * // create:\n * const comp2 = (\n * <CustomComponent2>\n *      <span>child 1</span>\n *      <span>child 2</span>\n * </CustomComponent2>\n * )\n * ```\n * @param elementGenerator \n */\nexport function template<\n\tProps extends Record<string, unknown> = Record<string,never>,\n\tChildren = JSX.childrenOrChildrenPromise|JSX.childrenOrChildrenPromise[], \n\tContext extends typeof HTMLElement = typeof HTMLElement\n> (\n\telementGenerator: jsxInputGenerator<JSX.Element|Promise<JSX.Element>, Props, never, false, false, InstanceType<Context>>\n):\n\tjsxInputGenerator<JSX.Element, MappedProps<Props>, Children> & ((cl: Context, context: ClassDecoratorContext<Context>)=>any)\n\n/**\n * Define an HTML template that can be used as an anonymous JSX component.\n * Default HTML Attributes defined in JSX are also set for the root element.\n * @example\n * ```tsx\n * const CustomComponent = template(<div class='class1 class2'></div>)\n * // create:\n * const comp = <CustomComponent id=\"c1\"/>\n * ```\n * @param elementGenerator \n */\nexport function template<Options extends Record<string, any> = {}, Children = JSX.childrenOrChildrenPromise|JSX.childrenOrChildrenPromise[]>(element:JSX.Element):jsxInputGenerator<JSX.Element, Options, Children>&((cl: Class, context: ClassDecoratorContext)=>any)\n\n/**\n * Empty template for component\n * ```ts\n * @template()\n * class MyComponent extends Component {\n * }\n * ```\n * @param elementGenerator \n */\nexport function template():jsxInputGenerator<JSX.Element, Record<string, never>, never>&((cl: Class, context: ClassDecoratorContext)=>any)\n\n\nexport function template(templateOrGenerator?: any): any {\n\tconst module = getCallerFile();\n\treturn createTemplateGenerator(templateOrGenerator, module);\n}\n\nexport function createTemplateGenerator(templateOrGenerator?:JSX.Element|jsxInputGenerator<JSX.Element|Promise<JSX.Element>, any, any, any>, module?: string):jsxInputGenerator<JSX.Element, Record<string, never>, never>&((cl: Class, context: ClassDecoratorContext)=>any) {\n\n\tlet generator: Function;\n\n\tmodule ??= getCallerFile();\n\n\tif (typeof templateOrGenerator == \"function\") generator = function(propsOrClass:any, context?:any) {\n\t\t// decorator\n\t\tif (Component.isPrototypeOf(propsOrClass)) {\n\t\t\tpropsOrClass._init_module = module;\n\t\t\t// workaround: immediately set metadata for class\n\t\t\tif (context) (propsOrClass as any)[METADATA] = context.metadata;\n\t\t\tconst decoratedClass = initDefaultOptions(module, propsOrClass)\n\t\t\tdecoratedClass.template = generator\n\t\t\treturn decoratedClass\n\t\t}\n\t\t// jsx\n\t\telse {\n\t\t\tif (context && templateOrGenerator.call) return templateOrGenerator.call(context, propsOrClass, propsOrClass)\n\t\t\telse return templateOrGenerator(propsOrClass, propsOrClass);\n\t\t}\n\t}\n\telse if (templateOrGenerator) {\n\t\tgenerator = function(maybeClass:any, context?:ClassDecoratorContext) {\n\t\t\t// decorator\n\t\t\tif (Component.isPrototypeOf(maybeClass)) {\n\t\t\t\tmaybeClass._init_module = module;\n\t\t\t\t// workaround: immediately set metadata for class\n\t\t\t\tif (context) (maybeClass as any)[METADATA] = context.metadata;\n\t\t\t\tconst decoratedClass = initDefaultOptions(module, maybeClass)\n\t\t\t\tdecoratedClass.template = generator\n\t\t\t\treturn decoratedClass\n\t\t\t}\n\t\t\t// jsx\n\t\t\telse {\n\t\t\t\treturn cloneWithShadowRoots(templateOrGenerator);\n\t\t\t}\n\t\t}\n\t}\n\telse generator = function(maybeClass:any, context?:ClassDecoratorContext) {\n\t\t// decorator\n\t\tif (Component.isPrototypeOf(maybeClass)) {\n\t\t\tmaybeClass._init_module = module;\n\t\t\t// workaround: immediately set metadata for class\n\t\t\tif (context) (maybeClass as any)[METADATA] = context.metadata;\n\t\t\treturn initDefaultOptions(module, maybeClass)\n\t\t}\n\t\t// jsx\n\t\telse {\n\t\t\tthrow new Error(\"invalid template definition\")\n\t\t}\n\t};\n\n\t(generator as any)[SET_DEFAULT_ATTRIBUTES] = true;\n\t(generator as any)[SET_DEFAULT_CHILDREN] = true;\n\t(generator as any)[IS_TEMPLATE] = true;\n\treturn generator;\n}\n\n\n\n/**\n * Define an HTML template that can be used as an anonymous JSX component.\n * \n * `template` should be used instead of this function when possible. \n * \n * In contrast to `template`, children defined in JSX are not automatically appended to the root element of the template,\n * and HTML Attributes defined in JSX are also not automatically set for the root element.\n * \n * All attributes and the children are available in the props argument of the generator function.\n * @example\n * ```tsx\n * const CustomComponent = blankTemplate<{color:string}>(({color, style, id, children}) => <div id={id} style={style}><h1>Header</h1>{...children}</div>)\n * // create:\n * const comp = (\n * <CustomComponent id=\"c1\">\n *     <div>first child</div>\n *     <div>second child</div>\n * </CustomComponent>\n * )\n * ```\n * @param elementGenerator \n */\nexport function blankTemplate<\n\tOptions extends Record<string, any>,\n\tChildren = JSX.childrenOrChildrenPromise|JSX.childrenOrChildrenPromise[], \n\tContext extends typeof HTMLElement = typeof HTMLElement\n> (\n\telementGenerator: jsxInputGenerator<JSX.Element|Promise<JSX.Element>, Options, Children extends any[] ? Children : Children[], true, false, InstanceType<Context>>\n): jsxInputGenerator<JSX.Element|Promise<JSX.Element>, Options, Children>&((cl: Context, context: ClassDecoratorContext<Context>)=>any) {\n\tconst module = getCallerFile();\n\n\tfunction generator(propsOrClass:any, context?:any) {\n\t\t// decorator\n\t\tif (Component.isPrototypeOf(propsOrClass)) {\n\t\t\tpropsOrClass._init_module = module;\n\t\t\tconst decoratedClass = initDefaultOptions(module, propsOrClass)\n\t\t\tdecoratedClass.template = generator\n\t\t\tdecoratedClass[SET_DEFAULT_CHILDREN] = false;\n\t\t\treturn decoratedClass\n\t\t}\n\n\t\telse {\n\t\t\tif (context && elementGenerator.call) return elementGenerator.call(context, propsOrClass, propsOrClass)\n\t\t\telse return elementGenerator(propsOrClass, propsOrClass);\n\t\t}\n\n\t}\n\n\t(generator as any)[IS_TEMPLATE] = true;\n\treturn generator;\n}\n\n"],"names":["getCallerFile","IS_TEMPLATE","SET_DEFAULT_ATTRIBUTES","SET_DEFAULT_CHILDREN","Component","DOMUtils","domContext","domUtils","initDefaultOptions","METADATA","cloneWithShadowRoots","element","Element","cloneNode","walk","node","clone","shadow","shadowRoot","attachShadow","mode","append","map","call","childNodes","c","cloneWithListeners","i","children","length","HTMLTemplateElement","content","event","listeners","EVENT_LISTENERS","listener","setElementAttribute","child","appendChild","template","templateOrGenerator","createTemplateGenerator","module","generator","propsOrClass","context","isPrototypeOf","_init_module","metadata","decoratedClass","maybeClass","Error","blankTemplate","elementGenerator"],"mappings":"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","sourceRoot":"/lib/uix-0.4.39/src/html/","file":"template.ts"}