{"version":3,"file":"template-C8XYMS58.cjs","sources":["../src/methods/template.ts"],"sourcesContent":["\r\n/* IMPORT */\r\n\r\nimport {SYMBOL_TEMPLATE_ACCESSOR} from '../constants';\r\nimport wrapElement from '../methods/wrap_element';\r\nimport {assign, indexOf, isFunction, isString} from '../utils/lang';\r\nimport {setAttribute, setChildReplacement, setClasses, setEvent, setHTML, setProperty, setRef, setStyles} from '../utils/setters';\r\nimport type {Child, TemplateActionPath, TemplateActionWithNodes, TemplateActionWithPaths, TemplateVariableProperties, TemplateVariableData, TemplateVariablesMap} from '../types';\r\n\r\n/* MAIN */\r\n\r\n//TODO: Avoid using \"Function\" and \"eval\", while still keeping similar performance, if possible\r\n//TODO: Support complex children in the template function\r\n//TODO: Support argumentless calls on props, like props.foo.bar()\r\n\r\nconst template = <P = {}> ( fn: (( props: P ) => Child) ): (( props: P ) => () => Child) => {\r\n\r\n  const safePropertyRe = /^[a-z0-9-_]+$/i;\r\n\r\n  const checkValidProperty = ( property: unknown ): property is string => {\r\n\r\n    if ( isString ( property ) && safePropertyRe.test ( property ) ) return true;\r\n\r\n    throw new Error ( `Invalid property, only alphanumeric properties are allowed inside templates, received: \"${property}\"` );\r\n\r\n  };\r\n\r\n  const makeAccessor = ( actionsWithNodes: TemplateActionWithNodes[] ): any => {\r\n\r\n    return new Proxy ( {}, {\r\n\r\n      get ( target: unknown, prop: string ) {\r\n\r\n        checkValidProperty ( prop );\r\n\r\n        const accessor = ( node: Node, method: string, key?: string, targetNode?: Node ): void => {\r\n\r\n          if ( key ) checkValidProperty ( key );\r\n\r\n          actionsWithNodes.push ([ node, method, prop, key, targetNode ]);\r\n\r\n        };\r\n\r\n        const metadata = { [SYMBOL_TEMPLATE_ACCESSOR]: true };\r\n\r\n        return assign ( accessor, metadata );\r\n\r\n      }\r\n\r\n    });\r\n\r\n  };\r\n\r\n  const makeActionsWithNodesAndTemplate = (): { actionsWithNodes: TemplateActionWithNodes[], root: Element } => {\r\n\r\n    const actionsWithNodes: TemplateActionWithNodes[] = [];\r\n    const accessor = makeAccessor ( actionsWithNodes );\r\n    const component = fn ( accessor );\r\n\r\n    if ( isFunction ( component ) ) {\r\n\r\n      const root = component ();\r\n\r\n      if ( root instanceof Element ) {\r\n\r\n        return { actionsWithNodes, root };\r\n\r\n      }\r\n\r\n    }\r\n\r\n    throw new Error ( 'Invalid template, it must return a function that returns an Element' );\r\n\r\n  };\r\n\r\n  const makeActionsWithPaths = ( actionsWithNodes: TemplateActionWithNodes[] ): TemplateActionWithPaths[] => {\r\n\r\n    const actionsWithPaths: TemplateActionWithPaths[] = [];\r\n\r\n    for ( let i = 0, l = actionsWithNodes.length; i < l; i++ ) {\r\n\r\n      const [node, method, prop, key, targetNode] = actionsWithNodes[i];\r\n\r\n      const nodePath = makeNodePath ( node );\r\n      const targetNodePath = targetNode ? makeNodePath ( targetNode ) : undefined;\r\n\r\n      actionsWithPaths.push ([ nodePath, method, prop, key, targetNodePath ]);\r\n\r\n    }\r\n\r\n    return actionsWithPaths;\r\n\r\n  };\r\n\r\n  const makeNodePath = (() => {\r\n\r\n    let prevNode: Node | null = null;\r\n    let prevPath: TemplateActionPath;\r\n\r\n    return ( node: Node ): TemplateActionPath => {\r\n\r\n      if ( node === prevNode ) return prevPath; // Cache hit\r\n\r\n      const path: TemplateActionPath = [];\r\n\r\n      let child = node;\r\n      let parent = child.parentNode;\r\n\r\n      while ( parent ) {\r\n\r\n        const index = !child.previousSibling ? 0 : !child.nextSibling ? -0 : indexOf ( parent.childNodes, child );\r\n\r\n        path.push ( index );\r\n\r\n        child = parent;\r\n        parent = parent.parentNode;\r\n\r\n      }\r\n\r\n      prevNode = node;\r\n      prevPath = path;\r\n\r\n      return path;\r\n\r\n    };\r\n\r\n  })();\r\n\r\n  const makeNodePathProperties = ( path: TemplateActionPath ): TemplateVariableProperties => {\r\n\r\n    const properties: TemplateVariableProperties = ['root'];\r\n\r\n    const parts = path.slice ().reverse ();\r\n\r\n    for ( let i = 0, l = parts.length; i < l; i++ ) {\r\n\r\n      const part = parts[i];\r\n\r\n      if ( Object.is ( 0, part ) ) {\r\n\r\n        properties.push ( 'firstChild' );\r\n\r\n      } else if ( Object.is ( -0, part ) ) {\r\n\r\n        properties.push ( 'lastChild' );\r\n\r\n      } else {\r\n\r\n        properties.push ( 'firstChild' );\r\n\r\n        for ( let nsi = 0; nsi < part; nsi++ ) {\r\n\r\n          properties.push ( 'nextSibling' );\r\n\r\n        }\r\n\r\n      }\r\n\r\n    }\r\n\r\n    return properties;\r\n\r\n  };\r\n\r\n  const makeReviverPaths = ( actionsWithPaths: TemplateActionWithPaths[] ): TemplateActionPath[] => {\r\n\r\n    const paths: TemplateActionPath[] = [];\r\n\r\n    for ( let i = 0, l = actionsWithPaths.length; i < l; i++ ) {\r\n\r\n      const action = actionsWithPaths[i];\r\n      const nodePath = action[0];\r\n      const targetNodePath = action[4];\r\n\r\n      paths.push ( nodePath );\r\n\r\n      if ( targetNodePath ) {\r\n\r\n        paths.push ( targetNodePath );\r\n\r\n      }\r\n\r\n    }\r\n\r\n    return paths;\r\n\r\n  };\r\n\r\n  const makeReviverVariablesData = ( paths: TemplateActionPath[], properties: TemplateVariableProperties[] ): TemplateVariableData[] => {\r\n\r\n    const data: TemplateVariableData[] = new Array ( paths.length );\r\n\r\n    for ( let i = 0, l = paths.length; i < l; i++ ) {\r\n\r\n      data[i] = {\r\n        path: paths[i],\r\n        properties: properties[i]\r\n      };\r\n\r\n    }\r\n\r\n    return data;\r\n\r\n  };\r\n\r\n  const makeReviverVariables = ( actionsWithPaths: TemplateActionWithPaths[] ): { assignments: string[], map: Map<TemplateActionPath, string> } => { //TODO: Optimize this further, there's some duplication and unnecessary work being done\r\n\r\n    const paths = makeReviverPaths ( actionsWithPaths );\r\n    const properties = paths.map ( makeNodePathProperties );\r\n    const data = makeReviverVariablesData ( paths, properties );\r\n    const assignments: string[] = [];\r\n    const map: TemplateVariablesMap = new Map ();\r\n\r\n    let variableId = 0;\r\n\r\n    while ( true ) {\r\n\r\n      const datum = data.find ( datum => datum.properties.length > 1 );\r\n\r\n      if ( !datum ) break;\r\n\r\n      const [current, next] = datum.properties;\r\n      const variable = `$${variableId++}`;\r\n      const assignment = `const ${variable} = ${current}.${next};`;\r\n\r\n      assignments.push ( assignment );\r\n\r\n      for ( let i = 0, l = data.length; i < l; i++ ) {\r\n\r\n        const datum = data[i];\r\n        const [otherCurrent, otherNext] = datum.properties;\r\n\r\n        if ( otherCurrent !== current || otherNext !== next ) continue;\r\n\r\n        datum.properties[0] = variable;\r\n        datum.properties.splice ( 1, 1 );\r\n\r\n      }\r\n\r\n    }\r\n\r\n    for ( let i = 0, l = data.length; i < l; i++ ) {\r\n\r\n      const datum = data[i];\r\n\r\n      map.set ( datum.path, datum.properties[0] );\r\n\r\n    }\r\n\r\n    return {assignments, map};\r\n\r\n  };\r\n\r\n  const makeReviverActions = ( actionsWithPaths: TemplateActionWithPaths[], variables: Map<TemplateActionPath, string> ): string[] => {\r\n\r\n    const actions: string[] = [];\r\n\r\n    for ( let i = 0, l = actionsWithPaths.length; i < l; i++ ) { //TODO: Write this more cleanly, with a single case\r\n\r\n      const [nodePath, method, prop, key, targetNodePath] = actionsWithPaths[i];\r\n\r\n      if ( targetNodePath ) {\r\n\r\n        actions.push ( `this.${method} ( props[\"${prop}\"], ${variables.get ( targetNodePath )} );` );\r\n\r\n      } else if ( key ) {\r\n\r\n        actions.push ( `this.${method} ( ${variables.get ( nodePath )}, \"${key}\", props[\"${prop}\"] );` );\r\n\r\n      } else {\r\n\r\n        actions.push ( `this.${method} ( ${variables.get ( nodePath )}, props[\"${prop}\"] );` );\r\n\r\n      }\r\n\r\n    }\r\n\r\n    return actions;\r\n\r\n  };\r\n\r\n  const makeReviver = ( actionsWithPaths: TemplateActionWithPaths[] ): (( root: Element, props: P ) => Element) => {\r\n\r\n    const {assignments, map} = makeReviverVariables ( actionsWithPaths );\r\n    const actions = makeReviverActions ( actionsWithPaths, map );\r\n    const fn = new Function ( 'root', 'props', `${assignments.join ( '' )}${actions.join ( '' )}return root;` );\r\n    const apis = {setAttribute, setChildReplacement, setClasses, setEvent, setHTML, setProperty, setRef, setStyles};\r\n    const reviver = fn.bind ( apis );\r\n\r\n    return reviver;\r\n\r\n  };\r\n\r\n  const makeComponent = (): (( props: P ) => () => Child) => {\r\n\r\n    const {actionsWithNodes, root} = makeActionsWithNodesAndTemplate ();\r\n    const actionsWithPaths = makeActionsWithPaths ( actionsWithNodes );\r\n    const reviver = makeReviver ( actionsWithPaths );\r\n\r\n    return ( props: P ): (() => Child) => {\r\n\r\n      const clone = root.cloneNode ( true );\r\n\r\n      return wrapElement ( reviver.bind ( undefined, clone as any, props ) );\r\n\r\n    };\r\n\r\n  };\r\n\r\n  return makeComponent ();\r\n\r\n};\r\n\r\n/* EXPORT */\r\n\r\nexport default template;"],"names":["isString","SYMBOL_TEMPLATE_ACCESSOR","assign","isFunction","indexOf","datum","fn","setAttribute","setChildReplacement","setClasses","setEvent","setHTML","setProperty","setRef","setStyles","wrapElement"],"mappings":"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"}