@cfdez11/vex 0.10.17 → 0.10.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
import{parseDocument,DomUtils}from"htmlparser2";import{render}from"dom-serializer";const fnCache=new Map;function getDataValue(expression,scope){const keys=Object.keys(scope),cacheKey=`${expression}::${keys.join(",")}`;fnCache.has(cacheKey)||fnCache.set(cacheKey,Function(...keys,`return (${expression})`));try{return fnCache.get(cacheKey)(...Object.values(scope))}catch{return""}}function isEmptyTextNode(node){return node.type==="text"&&/^\s*$/.test(node.data)}function parseHTMLToNodes(html){try{const dom=parseDocument(html,{xmlMode:!0});return DomUtils.getChildren(dom)}catch(error){return console.error("Error parsing HTML:",error),[]}}function processNode(node,scope,previousRendered=!1){if(node.type==="text")return node.data=node.data.replace(/</g,"<").replace(/>/g,">").replace(/(?<!\\)\{\{(.+?)\}\}/g,(_,expr)=>getDataValue(expr.trim(),scope)).replace(/\\\{\{/g,"{{"),node;if(node.type==="tag"){const attrs=node.attribs||{};for(const[attrName,attrValue]of Object.entries(attrs))typeof attrValue=="string"&&(attrs[attrName]=attrValue.replace(/(?<!\\)\{\{(.+?)\}\}/g,(_,expr)=>getDataValue(expr.trim(),scope)).replace(/\\\{\{/g,"{{"));if("x-if"in attrs){const show=getDataValue(attrs["x-if"],scope);if(delete attrs["x-if"],!show)return null}if("x-else-if"in attrs){const show=getDataValue(attrs["x-else-if"],scope);if(delete attrs["x-else-if"],previousRendered||!show)return null}if("x-else"in attrs&&(delete attrs["x-else"],previousRendered))return null;if("x-show"in attrs){const show=getDataValue(attrs["x-show"],scope);delete attrs["x-show"],show||(attrs.style=(attrs.style||"")+"display:none;")}if("x-for"in attrs){const exp=attrs["x-for"];delete attrs["x-for"];const match=exp.match(/(.+?)\s+in\s+(.+)/);if(!match)throw new Error("Invalid x-for format: "+exp);const itemName=match[1].trim(),listExpr=match[2].trim(),list=getDataValue(listExpr,scope);if(!Array.isArray(list))return null;const clones=[];for(const item of list){const cloned=structuredClone(node),newScope={...scope,[itemName]:item};clones.push(processNode(cloned,newScope))}return clones}for(const[name,value]of Object.entries({...attrs})){if(name.startsWith(":")){const isSuspenseFallback=name===":fallback"&&node.name==="Suspense",realName=name.slice(1);if(isSuspenseFallback)attrs[realName]=value;else{const val=getDataValue(value,scope);attrs[realName]=val!=null&&typeof val=="object"?JSON.stringify(val):String(val??"")}delete attrs[name]}if(name.startsWith("x-bind:")){const realName=name.slice(7),val=getDataValue(value,scope);attrs[realName]=val!=null&&typeof val=="object"?JSON.stringify(val):String(val??""),delete attrs[name]}}for(const[name]of Object.entries({...attrs}))(name.startsWith("@")||name.startsWith("x-on:"))&&delete attrs[name];if(node.children){const result=[];let isPreviousRendered=!1;const preserveWhitespace=node.name==="pre"||node.name==="textarea";for(const child of node.children){if(!preserveWhitespace&&isEmptyTextNode(child))continue;const processed=processNode(child,scope,isPreviousRendered);Array.isArray(processed)?(result.push(...processed),isPreviousRendered=processed.length>0):processed?(result.push(processed),isPreviousRendered=!0):isPreviousRendered=!1}node.children=result}return node}return node}const parsedTemplateCache=new Map;function compileTemplateToHTML(template,data={}){try{parsedTemplateCache.has(template)||parsedTemplateCache.set(template,parseHTMLToNodes(template));const processed=structuredClone(parsedTemplateCache.get(template)).map(n=>processNode(n,data)).flat().filter(Boolean);return render(processed,{encodeEntities:!1})}catch(error){throw console.error("Error compiling template:",error),error}}export{compileTemplateToHTML};
|
|
1
|
+
import{parseDocument,DomUtils}from"htmlparser2";import{render}from"dom-serializer";const fnCache=new Map;function getDataValue(expression,scope){const keys=Object.keys(scope),cacheKey=`${expression}::${keys.join(",")}`;fnCache.has(cacheKey)||fnCache.set(cacheKey,Function(...keys,`return (${expression})`));try{return fnCache.get(cacheKey)(...Object.values(scope))}catch{return""}}function isEmptyTextNode(node){return node.type==="text"&&/^\s*$/.test(node.data)}function parseHTMLToNodes(html){try{const dom=parseDocument(html,{xmlMode:!0});return DomUtils.getChildren(dom)}catch(error){return console.error("Error parsing HTML:",error),[]}}function processNode(node,scope,previousRendered=!1){if(node.type==="text")return node.data=node.data.replace(/</g,"<").replace(/>/g,">").replace(/(?<!\\)\{\{(.+?)\}\}/g,(_,expr)=>getDataValue(expr.trim(),scope)).replace(/\\\{\{/g,"{{"),node;if(node.type==="tag"){const attrs=node.attribs||{};for(const[attrName,attrValue]of Object.entries(attrs))typeof attrValue=="string"&&(attrs[attrName]=attrValue.replace(/(?<!\\)\{\{(.+?)\}\}/g,(_,expr)=>getDataValue(expr.trim(),scope)).replace(/\\\{\{/g,"{{"));if("x-if"in attrs){const show=getDataValue(attrs["x-if"],scope);if(delete attrs["x-if"],!show)return null}if("x-else-if"in attrs){const show=getDataValue(attrs["x-else-if"],scope);if(delete attrs["x-else-if"],previousRendered||!show)return null}if("x-else"in attrs&&(delete attrs["x-else"],previousRendered))return null;if("x-show"in attrs){const show=getDataValue(attrs["x-show"],scope);delete attrs["x-show"],show||(attrs.style=(attrs.style||"")+"display:none;")}if("x-for"in attrs){const exp=attrs["x-for"];delete attrs["x-for"];const match=exp.match(/(.+?)\s+in\s+(.+)/);if(!match)throw new Error("Invalid x-for format: "+exp);const itemName=match[1].trim(),listExpr=match[2].trim(),list=getDataValue(listExpr,scope);if(!Array.isArray(list))return null;const clones=[];for(const item of list){const cloned=structuredClone(node),newScope={...scope,[itemName]:item};clones.push(processNode(cloned,newScope))}return clones}for(const[name,value]of Object.entries({...attrs})){if(name.startsWith(":")){const isSuspenseFallback=name===":fallback"&&node.name==="Suspense",realName=name.slice(1);if(isSuspenseFallback)attrs[realName]=value;else{const val=getDataValue(value,scope);attrs[realName]=val!=null&&typeof val=="object"?JSON.stringify(val):String(val??"")}delete attrs[name]}if(name.startsWith("x-bind:")){const realName=name.slice(7),val=getDataValue(value,scope);attrs[realName]=val!=null&&typeof val=="object"?JSON.stringify(val):String(val??""),delete attrs[name]}}for(const[name]of Object.entries({...attrs}))(name.startsWith("@")||name.startsWith("x-on:"))&&delete attrs[name];if(node.children){const result=[];let isPreviousRendered=!1;const preserveWhitespace=node.name==="pre"||node.name==="textarea"||node.name==="code";for(const child of node.children){if(!preserveWhitespace&&isEmptyTextNode(child))continue;const processed=processNode(child,scope,isPreviousRendered);Array.isArray(processed)?(result.push(...processed),isPreviousRendered=processed.length>0):processed?(result.push(processed),isPreviousRendered=!0):isPreviousRendered=!1}node.children=result}return node}return node}const parsedTemplateCache=new Map;function compileTemplateToHTML(template,data={}){try{parsedTemplateCache.has(template)||parsedTemplateCache.set(template,parseHTMLToNodes(template));const processed=structuredClone(parsedTemplateCache.get(template)).map(n=>processNode(n,data)).flat().filter(Boolean);return render(processed,{encodeEntities:!1})}catch(error){throw console.error("Error compiling template:",error),error}}export{compileTemplateToHTML};
|