@knighted/jsx 1.6.3-rc.1 → 1.7.0
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.
- package/dist/cjs/loader/dom-template-builder.cjs +217 -0
- package/dist/cjs/loader/dom-template-builder.d.cts +12 -0
- package/dist/cjs/loader/helpers/dom-snippets.cjs +149 -0
- package/dist/cjs/loader/helpers/dom-snippets.d.cts +2 -0
- package/dist/cjs/loader/helpers/format-import-specifier.cjs +30 -0
- package/dist/cjs/loader/helpers/format-import-specifier.d.cts +13 -0
- package/dist/cjs/loader/helpers/materialize-slice.cjs +37 -0
- package/dist/cjs/loader/helpers/materialize-slice.d.cts +1 -0
- package/dist/cjs/loader/helpers/parse-range-key.cjs +14 -0
- package/dist/cjs/loader/helpers/parse-range-key.d.cts +1 -0
- package/dist/cjs/loader/helpers/rewrite-imports-without-tags.cjs +62 -0
- package/dist/cjs/loader/helpers/rewrite-imports-without-tags.d.cts +3 -0
- package/dist/cjs/loader/jsx.cjs +57 -33
- package/dist/cjs/loader/jsx.d.cts +3 -1
- package/dist/cjs/loader/modes.cjs +17 -0
- package/dist/cjs/loader/modes.d.cts +3 -0
- package/dist/cjs/runtime/shared.cjs +3 -13
- package/dist/cjs/shared/normalize-text.cjs +22 -0
- package/dist/cjs/shared/normalize-text.d.cts +1 -0
- package/dist/lite/debug/index.js +7 -7
- package/dist/lite/index.js +7 -7
- package/dist/lite/node/debug/index.js +7 -7
- package/dist/lite/node/index.js +7 -7
- package/dist/lite/node/react/index.js +5 -5
- package/dist/lite/react/index.js +5 -5
- package/dist/loader/dom-template-builder.d.ts +12 -0
- package/dist/loader/dom-template-builder.js +213 -0
- package/dist/loader/helpers/dom-snippets.d.ts +2 -0
- package/dist/loader/helpers/dom-snippets.js +146 -0
- package/dist/loader/helpers/format-import-specifier.d.ts +13 -0
- package/dist/loader/helpers/format-import-specifier.js +26 -0
- package/dist/loader/helpers/materialize-slice.d.ts +1 -0
- package/dist/loader/helpers/materialize-slice.js +33 -0
- package/dist/loader/helpers/parse-range-key.d.ts +1 -0
- package/dist/loader/helpers/parse-range-key.js +10 -0
- package/dist/loader/helpers/rewrite-imports-without-tags.d.ts +3 -0
- package/dist/loader/helpers/rewrite-imports-without-tags.js +58 -0
- package/dist/loader/jsx.d.ts +3 -1
- package/dist/loader/jsx.js +55 -31
- package/dist/loader/modes.d.ts +3 -0
- package/dist/loader/modes.js +13 -0
- package/dist/runtime/shared.js +3 -13
- package/dist/shared/normalize-text.d.ts +1 -0
- package/dist/shared/normalize-text.js +18 -0
- package/package.json +6 -6
package/dist/lite/node/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {createRequire}from'module';import {parseSync}from'oxc-parser';import {find,svg,html}from'property-information';var
|
|
2
|
-
`),
|
|
3
|
-
`)},T=(e,t,
|
|
4
|
-
--> ${e} template:${f.line}:${f.column}`,
|
|
5
|
-
${
|
|
1
|
+
import {createRequire}from'module';import {parseSync}from'oxc-parser';import {find,svg,html}from'property-information';var ne=createRequire(import.meta.url),R=()=>ne,M="<!doctype html><html><body></body></html>",oe=["window","self","document","HTMLElement","Element","Node","DocumentFragment","customElements","Text","Comment","MutationObserver","navigator"],se=()=>typeof document<"u"&&typeof document.createElement=="function",ae=e=>{let n=globalThis,t=e;oe.forEach(r=>{n[r]===void 0&&t[r]!==void 0&&(n[r]=t[r]);});},S=()=>{let{parseHTML:e}=R()("linkedom"),{window:n}=e(M);return n},w=()=>{let{JSDOM:e}=R()("jsdom"),{window:n}=new e(M);return n},ie=()=>{let e=typeof process<"u"&&process.env?.KNIGHTED_JSX_NODE_SHIM?process.env.KNIGHTED_JSX_NODE_SHIM.toLowerCase():void 0;return e==="linkedom"||e==="jsdom"?e:"auto"},pe=()=>{let e=ie();return e==="linkedom"?[S,w]:e==="jsdom"?[w,S]:[S,w]},ce=()=>{let e=[];for(let t of pe())try{return t()}catch(r){e.push(r);}let n='Unable to bootstrap a DOM-like environment. Install "linkedom" or "jsdom" (both optional peer dependencies) or set KNIGHTED_JSX_NODE_SHIM to pick one explicitly.';throw new AggregateError(e,n)},X=false,D=()=>{if(se()||X)return;let e=ce();ae(e),X=true;};var L=e=>{let n=e.replace(/\r/g,"").replace(/\n\s+/g," "),t=e.match(/^\s*/)?.[0]??"",r=e.match(/\s*$/)?.[0]??"",o=/\n/.test(t),s=/\n/.test(r),a=n;return o&&(a=a.replace(/^\s+/,"")),s&&(a=a.replace(/\s+$/,"")),a.length===0||a.trim().length===0?null:a};var le="oxc-parser",me=e=>{let n=e.raw??e,t=n[0]??"",r=[];for(let o=0;o<n.length-1;o++){let s="${expr#"+o+"}",a=t.length;t+=s;let c=t.length;r.push({index:o,templateStart:a,templateEnd:c,label:s}),t+=n[o+1]??"";}return {source:t,spans:r}},ue=(e,n)=>{let t=new Map;return n.forEach(r=>{t.set(r.index,r);}),e.expressionRanges.map(r=>{let o=t.get(r.index);if(!o)return null;let s=Math.max(0,r.sourceEnd-r.sourceStart),a=Math.max(0,o.templateEnd-o.templateStart);return {sourceStart:r.sourceStart,sourceEnd:r.sourceEnd,templateStart:o.templateStart,templateEnd:o.templateEnd,delta:a-s}}).filter(r=>!!r).sort((r,o)=>r.sourceStart-o.sourceStart)},de=(e,n,t)=>{if(!Number.isFinite(e)||e<=0)return 0;let r=0;for(let s of n){if(e<s.sourceStart)break;if(e<s.sourceEnd){let a=Math.max(0,e-s.sourceStart),c=Math.max(0,s.templateEnd-s.templateStart);if(c===0)return s.templateStart;let i=Math.min(a,Math.max(0,c-1));return s.templateStart+i}r+=s.delta;}let o=e+r;return o<=0?0:o>=t?t:o},P=(e,n)=>{let t=Math.max(0,Math.min(n,e.length)),r=1,o=1;for(let s=0;s<t;s++){if(e.charCodeAt(s)===10){r++,o=1;continue}o++;}return {line:r,column:o}},fe=e=>{let n=[],t=0;return e.forEach((r,o)=>{n.push(t),t+=r.length,o<e.length-1&&(t+=1);}),n},ge=(e,n,t,r,o,s,a)=>{let c=t+n.length,i=Math.max(r,t),p=Math.min(o,c);if(p>i){let l=Math.max(0,i-t),u=Math.max(1,p-i);return " ".repeat(l)+"^".repeat(u)}if(n.length===0&&e>=s&&e<=a)return "^";if(e===s){let l=Math.max(0,r-t);return " ".repeat(Math.min(l,n.length))+"^"}return ""},xe=(e,n,t,r,o)=>{if(!e.length)return "";let s=e.split(`
|
|
2
|
+
`),a=fe(s),c=Math.max(1,r-1),i=Math.min(s.length,o+1),p=String(i).length,l=[];for(let u=c;u<=i;u++){let d=s[u-1]??"",m=String(u).padStart(p," ");l.push(`${m} | ${d}`);let f=ge(u,d,a[u-1]??0,n,t,r,o);f&&l.push(`${" ".repeat(p)} | ${f}`);}return l.join(`
|
|
3
|
+
`)},T=(e,n,t,r,o)=>{let s=le,a=`[${s}] ${r.message}`,c=r.labels?.[0];if(!c)return a;let{source:i,spans:p}=me(n),l=ue(t,p),u=h=>de(typeof h=="number"?h:0,l,i.length),d=u(c.start),m=u(c.end);m<=d&&(m=Math.min(i.length,d+1));let f=P(i,d),x=P(i,Math.max(d,m-1)),y=xe(i,d,m,f.line,x.line),g=`[${s}] ${r.message}`;return g+=`
|
|
4
|
+
--> ${e} template:${f.line}:${f.column}`,c.message&&(g+=`
|
|
5
|
+
${c.message}`),y&&(g+=`
|
|
6
6
|
${y}`),r.helpMessage&&(g+=`
|
|
7
|
-
${r.helpMessage}`),g};var
|
|
8
|
-
export{
|
|
7
|
+
${r.helpMessage}`),g};var he=/<\s*$/,Ee=/<\/\s*$/,j="__KX_EXPR__",I=new RegExp(`${j}\\d+_\\d+__`,"g"),ye=0;var O={lang:"jsx",sourceType:"module",range:true,preserveParens:true},$=e=>{for(let n of e.body)if(n.type==="ExpressionStatement"){let t=n.expression;if(t.type==="JSXElement"||t.type==="JSXFragment")return t}throw new Error("The jsx template must contain a single JSX element or fragment.")},b=e=>{switch(e.type){case "JSXIdentifier":return e.name;case "JSXNamespacedName":return `${e.namespace.name}:${e.name.name}`;case "JSXMemberExpression":return `${b(e.object)}.${e.property.name}`;default:return ""}},J=(e,n)=>{if(!e||typeof e!="object")return;let t=e;typeof t.type=="string"&&(n(t),Object.values(t).forEach(r=>{if(r){if(Array.isArray(r)){r.forEach(o=>J(o,n));return}typeof r=="object"&&J(r,n);}}));},_=(e,n)=>{let t=L(e);if(!t)return [];let r=[];I.lastIndex=0;let o=0,s;for(;s=I.exec(t);){let c=s.index,i=t.slice(o,c);i&&r.push(i);let p=s[0];n.has(p)?r.push(n.get(p)):r.push(p),o=c+p.length;}let a=t.slice(o);return a&&r.push(a),r},be=(e,n)=>{let t=new Set;return J(e,r=>{r.type==="Identifier"&&n.placeholders.has(r.name)&&t.add(r.name);}),Array.from(t)},F=(e,n,t)=>{if(e.type==="JSXElement"||e.type==="JSXFragment")return t(e);if(!("range"in e)||!e.range)throw new Error("Unable to evaluate expression: missing source range information.");let[r,o]=e.range,s=n.source.slice(r,o),a=be(e,n);try{let c=new Function(...a,`"use strict"; return (${s});`),i=a.map(p=>n.placeholders.get(p));return c(...i)}catch(c){throw new Error(`Failed to evaluate expression ${s}: ${c.message}`)}},Se=e=>{let n=e.replace(/[^a-zA-Z0-9_$]/g,"");return n?/[A-Za-z_$]/.test(n[0])?n:`Component${n}`:"Component"},we=(e,n,t)=>{let r=t.get(e);if(r)return r;let o=e.displayName||e.name||`Component${n.length}`,s=Se(o??""),a=s,c=1;for(;n.some(p=>p.name===a);)a=`${s}${c++}`;let i={name:a,value:e};return n.push(i),t.set(e,i),i},H=(e,n)=>{let t=e.raw??e,r=new Map,o=[],s=new Map,a=t[0]??"",c=ye++,i=0,p=[];for(let l=0;l<n.length;l++){let u=t[l]??"",d=t[l+1]??"",m=n[l],f=he.test(u)||Ee.test(u),x;if(f&&typeof m=="function")x=we(m,o,s).name;else if(f&&typeof m=="string")x=m;else {let h=`${j}${c}_${i++}__`;r.set(h,m),x=h;}let y=a.length;a+=x;let g=a.length;p.push({index:l,sourceStart:y,sourceEnd:g}),a+=d;}return {source:a,placeholders:r,bindings:o,diagnostics:{expressionRanges:p}}};var B=e=>{let{getIdentifierName:n,evaluateExpressionWithNamespace:t}=e;return (r,o,s)=>{let a={},c=(i,p)=>{a[i]=p;};return r.forEach(i=>{if(i.type==="JSXSpreadAttribute"){let l=t(i.argument,o,s);l&&typeof l=="object"&&!Array.isArray(l)&&Object.assign(a,l);return}let p=n(i.name);if(!i.value){c(p,true);return}if(i.value.type==="Literal"){c(p,i.value.value);return}if(i.value.type==="JSXExpressionContainer"){if(i.value.expression.type==="JSXEmptyExpression")return;c(p,t(i.value.expression,o,s));}}),a}};var V="Capture",z=e=>e.endsWith(V)?{eventName:e.slice(0,-V.length),capture:true}:{eventName:e,capture:false},U=e=>{if(!e.startsWith("on"))return null;if(e.startsWith("on:")){let r=e.slice(3);if(!r)return null;let o=z(r);return o.eventName?o:null}let n=e.slice(2);if(!n)return null;let t=z(n);return t.eventName?{eventName:t.eventName.toLowerCase(),capture:t.capture}:null},q=e=>!e||typeof e!="object"?false:"handleEvent"in e&&typeof e.handleEvent=="function",ke=e=>{if(!e||typeof e!="object"||!("handler"in e))return false;let n=e.handler;return typeof n=="function"?true:q(n)},K=(e,n)=>{if(typeof n=="function"||q(n))return {listener:n};if(!ke(n))return null;let t=n,r=t.options?{...t.options}:void 0,o=(s,a)=>{a!=null&&(r||(r={}),r[s]=a);};return o("capture",t.capture),o("once",t.once),o("passive",t.passive),o("signal",t.signal??void 0),{listener:t.handler,options:r}};var Me=()=>{if(typeof document>"u"||typeof document.createElement!="function")throw new Error("The jsx template tag requires a DOM-like environment (document missing).")},De=e=>typeof Node>"u"?false:e instanceof Node||e instanceof DocumentFragment,Le=e=>!e||typeof e=="string"?false:typeof e[Symbol.iterator]=="function",Z=e=>!e||typeof e!="object"&&typeof e!="function"?false:typeof e.then=="function",Pe={xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},Y=e=>{if(!(!e||e==="html"||e==="svg"))return Pe[e]},Ie=e=>e==="svg"?svg:html,C=(e,n,t)=>{let r=Y(n.space),o=String(t);if(r){e.setAttributeNS(r,n.attribute,o);return}e.setAttribute(n.attribute,o);},G=(e,n)=>{let t=Y(n.space);if(t){e.removeAttributeNS(t,n.attribute);return}e.removeAttribute(n.attribute);},k=(e,n)=>Array.isArray(e)?e.filter(Boolean).join(n):e,je=(e,n,t)=>n==="svg"||!t.property||t.property.includes(":")?false:t.property in e,Oe=(e,n,t,r)=>{if(t==null)return;if(n==="dangerouslySetInnerHTML"&&typeof t=="object"&&t&&"__html"in t){e.innerHTML=String(t.__html??"");return}if(n==="ref"){if(typeof t=="function"){t(e);return}if(t&&typeof t=="object"){t.current=e;return}}if(n==="style"&&typeof t=="object"&&t!==null){let p=t,l=e.style;if(!l)return;let u=l;Object.entries(p).forEach(([d,m])=>{if(m!=null){if(d.startsWith("--")){l.setProperty(d,String(m));return}u[d]=m;}});return}let o=U(n);if(o){let p=K(n,t);if(p){let l=p.options?{...p.options}:void 0;o.capture&&(l?l.capture=true:l={capture:true}),e.addEventListener(o.eventName,p.listener,l);return}}let s=find(Ie(r),n),a=e,c=je(e,r,s);if(s.mustUseProperty){let p=s.boolean?!!t:t;a[s.property]=p;return}if(s.boolean){let p=!!t;c&&(a[s.property]=p),p?C(e,s,""):G(e,s);return}let i=t;if(s.spaceSeparated?i=k(t," "):s.commaSeparated?i=k(t,","):s.commaOrSpaceSeparated&&(i=k(t," ")),s.booleanish&&typeof i=="boolean"&&(i=i?"true":"false"),s.overloadedBoolean){if(i===false){G(e,s);return}if(i===true){C(e,s,"");return}}if(c){a[s.property]=i;return}i!==false&&C(e,s,i);},E=(e,n)=>{if(n!=null&&typeof n!="boolean"){if(Z(n))throw new Error("Async values are not supported inside jsx template results.");if(Array.isArray(n)){n.forEach(t=>E(e,t));return}if(Le(n)){for(let t of n)E(e,t);return}if(De(n)){e.appendChild(n);return}e.appendChild(document.createTextNode(String(n)));}},N=(e,n,t)=>F(e,n,r=>v(r,n,t)),Q=B({getIdentifierName:b,evaluateExpressionWithNamespace:N}),$e=(e,n,t,r)=>{let o=Q(n,t,r);Object.entries(o).forEach(([s,a])=>{if(s!=="key"){if(s==="children"){E(e,a);return}Oe(e,s,a,r);}});},A=(e,n,t)=>{let r=[];return e.forEach(o=>{switch(o.type){case "JSXText":{_(o.value,n.placeholders).forEach(a=>{r.push(a);});break}case "JSXExpressionContainer":{if(o.expression.type==="JSXEmptyExpression")break;r.push(N(o.expression,n,t));break}case "JSXSpreadChild":{let s=N(o.expression,n,t);s!=null&&r.push(s);break}case "JSXElement":case "JSXFragment":{r.push(v(o,n,t));break}}}),r},_e=(e,n,t,r)=>{let o=Q(e.openingElement.attributes,n,r),s=A(e.children,n,r);s.length===1?o.children=s[0]:s.length>1&&(o.children=s);let a=t(o);if(Z(a))throw new Error("Async jsx components are not supported.");return a},Fe=(e,n,t)=>{let r=e.openingElement,o=b(r.name),s=n.components.get(o);if(s)return _e(e,n,s,t);if(/[A-Z]/.test(o[0]??""))throw new Error(`Unknown component "${o}". Did you interpolate it with the template literal?`);let a=o==="svg"?"svg":t,c=o==="foreignObject"?null:a,i=a==="svg"?document.createElementNS("http://www.w3.org/2000/svg",o):document.createElement(o);return $e(i,r.attributes,n,a),A(e.children,n,c).forEach(l=>E(i,l)),i},v=(e,n,t)=>{if(e.type==="JSXFragment"){let r=document.createDocumentFragment();return A(e.children,n,t).forEach(s=>E(r,s)),r}return Fe(e,n,t)},ee=(e,...n)=>{Me();let t=H(e,n),r=parseSync("inline.jsx",t.source,O);if(r.errors.length>0)throw new Error(T("jsx",e,t.diagnostics,r.errors[0]));let o=$(r.program),s={source:t.source,placeholders:t.placeholders,components:new Map(t.bindings.map(a=>[a.name,a.value]))};return v(o,s,null)};D();var at=ee;
|
|
8
|
+
export{at as jsx};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {parseSync}from'oxc-parser';import {createElement,Fragment}from'react';var
|
|
2
|
-
`),a=
|
|
3
|
-
`)},b=(e,n,
|
|
4
|
-
--> ${e} template:${
|
|
1
|
+
import {parseSync}from'oxc-parser';import {createElement,Fragment}from'react';var w=e=>{let r=e.replace(/\r/g,"").replace(/\n\s+/g," "),n=e.match(/^\s*/)?.[0]??"",t=e.match(/\s*$/)?.[0]??"",o=/\n/.test(n),s=/\n/.test(t),a=r;return o&&(a=a.replace(/^\s+/,"")),s&&(a=a.replace(/\s+$/,"")),a.length===0||a.trim().length===0?null:a};var O="oxc-parser",j=e=>{let r=e.raw??e,n=r[0]??"",t=[];for(let o=0;o<r.length-1;o++){let s="${expr#"+o+"}",a=n.length;n+=s;let p=n.length;t.push({index:o,templateStart:a,templateEnd:p,label:s}),n+=r[o+1]??"";}return {source:n,spans:t}},L=(e,r)=>{let n=new Map;return r.forEach(t=>{n.set(t.index,t);}),e.expressionRanges.map(t=>{let o=n.get(t.index);if(!o)return null;let s=Math.max(0,t.sourceEnd-t.sourceStart),a=Math.max(0,o.templateEnd-o.templateStart);return {sourceStart:t.sourceStart,sourceEnd:t.sourceEnd,templateStart:o.templateStart,templateEnd:o.templateEnd,delta:a-s}}).filter(t=>!!t).sort((t,o)=>t.sourceStart-o.sourceStart)},D=(e,r,n)=>{if(!Number.isFinite(e)||e<=0)return 0;let t=0;for(let s of r){if(e<s.sourceStart)break;if(e<s.sourceEnd){let a=Math.max(0,e-s.sourceStart),p=Math.max(0,s.templateEnd-s.templateStart);if(p===0)return s.templateStart;let i=Math.min(a,Math.max(0,p-1));return s.templateStart+i}t+=s.delta;}let o=e+t;return o<=0?0:o>=n?n:o},R=(e,r)=>{let n=Math.max(0,Math.min(r,e.length)),t=1,o=1;for(let s=0;s<n;s++){if(e.charCodeAt(s)===10){t++,o=1;continue}o++;}return {line:t,column:o}},B=e=>{let r=[],n=0;return e.forEach((t,o)=>{r.push(n),n+=t.length,o<e.length-1&&(n+=1);}),r},z=(e,r,n,t,o,s,a)=>{let p=n+r.length,i=Math.max(t,n),m=Math.min(o,p);if(m>i){let c=Math.max(0,i-n),l=Math.max(1,m-i);return " ".repeat(c)+"^".repeat(l)}if(r.length===0&&e>=s&&e<=a)return "^";if(e===s){let c=Math.max(0,t-n);return " ".repeat(Math.min(c,r.length))+"^"}return ""},v=(e,r,n,t,o)=>{if(!e.length)return "";let s=e.split(`
|
|
2
|
+
`),a=B(s),p=Math.max(1,t-1),i=Math.min(s.length,o+1),m=String(i).length,c=[];for(let l=p;l<=i;l++){let g=s[l-1]??"",u=String(l).padStart(m," ");c.push(`${u} | ${g}`);let d=z(l,g,a[l-1]??0,r,n,t,o);d&&c.push(`${" ".repeat(m)} | ${d}`);}return c.join(`
|
|
3
|
+
`)},b=(e,r,n,t,o)=>{let s=O,a=`[${s}] ${t.message}`,p=t.labels?.[0];if(!p)return a;let{source:i,spans:m}=j(r),c=L(n,m),l=h=>D(typeof h=="number"?h:0,c,i.length),g=l(p.start),u=l(p.end);u<=g&&(u=Math.min(i.length,g+1));let d=R(i,g),f=R(i,Math.max(g,u-1)),E=v(i,g,u,d.line,f.line),x=`[${s}] ${t.message}`;return x+=`
|
|
4
|
+
--> ${e} template:${d.line}:${d.column}`,p.message&&(x+=`
|
|
5
5
|
${p.message}`),E&&(x+=`
|
|
6
6
|
${E}`),t.helpMessage&&(x+=`
|
|
7
|
-
${t.helpMessage}`),x};var
|
|
7
|
+
${t.helpMessage}`),x};var W=/<\s*$/,U=/<\/\s*$/,$="__KX_EXPR__",X=new RegExp(`${$}\\d+_\\d+__`,"g"),V=0;var A={lang:"jsx",sourceType:"module",range:true,preserveParens:true},k=e=>{for(let r of e.body)if(r.type==="ExpressionStatement"){let n=r.expression;if(n.type==="JSXElement"||n.type==="JSXFragment")return n}throw new Error("The jsx template must contain a single JSX element or fragment.")},S=e=>{switch(e.type){case "JSXIdentifier":return e.name;case "JSXNamespacedName":return `${e.namespace.name}:${e.name.name}`;case "JSXMemberExpression":return `${S(e.object)}.${e.property.name}`;default:return ""}},C=(e,r)=>{if(!e||typeof e!="object")return;let n=e;typeof n.type=="string"&&(r(n),Object.values(n).forEach(t=>{if(t){if(Array.isArray(t)){t.forEach(o=>C(o,r));return}typeof t=="object"&&C(t,r);}}));},M=(e,r)=>{let n=w(e);if(!n)return [];let t=[];X.lastIndex=0;let o=0,s;for(;s=X.exec(n);){let p=s.index,i=n.slice(o,p);i&&t.push(i);let m=s[0];r.has(m)?t.push(r.get(m)):t.push(m),o=p+m.length;}let a=n.slice(o);return a&&t.push(a),t},Z=(e,r)=>{let n=new Set;return C(e,t=>{t.type==="Identifier"&&r.placeholders.has(t.name)&&n.add(t.name);}),Array.from(n)},N=(e,r,n)=>{if(e.type==="JSXElement"||e.type==="JSXFragment")return n(e);if(!("range"in e)||!e.range)throw new Error("Unable to evaluate expression: missing source range information.");let[t,o]=e.range,s=r.source.slice(t,o),a=Z(e,r);try{let p=new Function(...a,`"use strict"; return (${s});`),i=a.map(m=>r.placeholders.get(m));return p(...i)}catch(p){throw new Error(`Failed to evaluate expression ${s}: ${p.message}`)}},G=e=>{let r=e.replace(/[^a-zA-Z0-9_$]/g,"");return r?/[A-Za-z_$]/.test(r[0])?r:`Component${r}`:"Component"},H=(e,r,n)=>{let t=n.get(e);if(t)return t;let o=e.displayName||e.name||`Component${r.length}`,s=G(o??""),a=s,p=1;for(;r.some(m=>m.name===a);)a=`${s}${p++}`;let i={name:a,value:e};return r.push(i),n.set(e,i),i},F=(e,r)=>{let n=e.raw??e,t=new Map,o=[],s=new Map,a=n[0]??"",p=V++,i=0,m=[];for(let c=0;c<r.length;c++){let l=n[c]??"",g=n[c+1]??"",u=r[c],d=W.test(l)||U.test(l),f;if(d&&typeof u=="function")f=H(u,o,s).name;else if(d&&typeof u=="string")f=u;else {let h=`${$}${p}_${i++}__`;t.set(h,u),f=h;}let E=a.length;a+=f;let x=a.length;m.push({index:c,sourceStart:E,sourceEnd:x}),a+=g;}return {source:a,placeholders:t,bindings:o,diagnostics:{expressionRanges:m}}};var Q=e=>!e||typeof e=="string"?false:typeof e[Symbol.iterator]=="function",Y=e=>!e||typeof e!="object"&&typeof e!="function"?false:typeof e.then=="function",y=(e,r)=>{if(r!=null&&typeof r!="boolean"){if(Y(r))throw new Error("Async values are not supported inside reactJsx template results.");if(Array.isArray(r)){r.forEach(n=>y(e,n));return}if(Q(r)){for(let n of r)y(e,n);return}e.push(r);}},T=(e,r)=>N(e,r,n=>J(n,r)),ee=(e,r)=>{let n={};return e.forEach(t=>{if(t.type==="JSXSpreadAttribute"){let s=T(t.argument,r);s&&typeof s=="object"&&!Array.isArray(s)&&Object.assign(n,s);return}let o=S(t.name);if(!t.value){n[o]=true;return}if(t.value.type==="Literal"){n[o]=t.value.value;return}if(t.value.type==="JSXExpressionContainer"){if(t.value.expression.type==="JSXEmptyExpression")return;n[o]=T(t.value.expression,r);}}),n},_=(e,r)=>{let n=[];return e.forEach(t=>{switch(t.type){case "JSXText":{M(t.value,r.placeholders).forEach(s=>y(n,s));break}case "JSXExpressionContainer":{if(t.expression.type==="JSXEmptyExpression")break;y(n,T(t.expression,r));break}case "JSXSpreadChild":{let o=T(t.expression,r);o!=null&&y(n,o);break}case "JSXElement":case "JSXFragment":{n.push(J(t,r));break}}}),n},P=(e,r,n)=>createElement(e,r,...n),te=(e,r)=>{let n=e.openingElement,t=S(n.name),o=r.components.get(t),s=ee(n.attributes,r),a=_(e.children,r);if(o)return P(o,s,a);if(/[A-Z]/.test(t[0]??""))throw new Error(`Unknown component "${t}". Did you interpolate it with the template literal?`);return P(t,s,a)},J=(e,r)=>{if(e.type==="JSXFragment"){let n=_(e.children,r);return createElement(Fragment,null,...n)}return te(e,r)},ne=(e,...r)=>{let n=F(e,r),t=parseSync("inline.jsx",n.source,A);if(t.errors.length>0)throw new Error(b("reactJsx",e,n.diagnostics,t.errors[0]));let o=k(t.program),s={source:n.source,placeholders:n.placeholders,components:new Map(n.bindings.map(a=>[a.name,a.value]))};return J(o,s)};export{ne as reactJsx};
|
package/dist/lite/react/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {parseSync}from'oxc-parser';import {createElement,Fragment}from'react';var
|
|
2
|
-
`),a=
|
|
3
|
-
`)},b=(e,n,
|
|
4
|
-
--> ${e} template:${
|
|
1
|
+
import {parseSync}from'oxc-parser';import {createElement,Fragment}from'react';var w=e=>{let r=e.replace(/\r/g,"").replace(/\n\s+/g," "),n=e.match(/^\s*/)?.[0]??"",t=e.match(/\s*$/)?.[0]??"",o=/\n/.test(n),s=/\n/.test(t),a=r;return o&&(a=a.replace(/^\s+/,"")),s&&(a=a.replace(/\s+$/,"")),a.length===0||a.trim().length===0?null:a};var O="oxc-parser",j=e=>{let r=e.raw??e,n=r[0]??"",t=[];for(let o=0;o<r.length-1;o++){let s="${expr#"+o+"}",a=n.length;n+=s;let p=n.length;t.push({index:o,templateStart:a,templateEnd:p,label:s}),n+=r[o+1]??"";}return {source:n,spans:t}},L=(e,r)=>{let n=new Map;return r.forEach(t=>{n.set(t.index,t);}),e.expressionRanges.map(t=>{let o=n.get(t.index);if(!o)return null;let s=Math.max(0,t.sourceEnd-t.sourceStart),a=Math.max(0,o.templateEnd-o.templateStart);return {sourceStart:t.sourceStart,sourceEnd:t.sourceEnd,templateStart:o.templateStart,templateEnd:o.templateEnd,delta:a-s}}).filter(t=>!!t).sort((t,o)=>t.sourceStart-o.sourceStart)},D=(e,r,n)=>{if(!Number.isFinite(e)||e<=0)return 0;let t=0;for(let s of r){if(e<s.sourceStart)break;if(e<s.sourceEnd){let a=Math.max(0,e-s.sourceStart),p=Math.max(0,s.templateEnd-s.templateStart);if(p===0)return s.templateStart;let i=Math.min(a,Math.max(0,p-1));return s.templateStart+i}t+=s.delta;}let o=e+t;return o<=0?0:o>=n?n:o},R=(e,r)=>{let n=Math.max(0,Math.min(r,e.length)),t=1,o=1;for(let s=0;s<n;s++){if(e.charCodeAt(s)===10){t++,o=1;continue}o++;}return {line:t,column:o}},B=e=>{let r=[],n=0;return e.forEach((t,o)=>{r.push(n),n+=t.length,o<e.length-1&&(n+=1);}),r},z=(e,r,n,t,o,s,a)=>{let p=n+r.length,i=Math.max(t,n),m=Math.min(o,p);if(m>i){let c=Math.max(0,i-n),l=Math.max(1,m-i);return " ".repeat(c)+"^".repeat(l)}if(r.length===0&&e>=s&&e<=a)return "^";if(e===s){let c=Math.max(0,t-n);return " ".repeat(Math.min(c,r.length))+"^"}return ""},v=(e,r,n,t,o)=>{if(!e.length)return "";let s=e.split(`
|
|
2
|
+
`),a=B(s),p=Math.max(1,t-1),i=Math.min(s.length,o+1),m=String(i).length,c=[];for(let l=p;l<=i;l++){let g=s[l-1]??"",u=String(l).padStart(m," ");c.push(`${u} | ${g}`);let d=z(l,g,a[l-1]??0,r,n,t,o);d&&c.push(`${" ".repeat(m)} | ${d}`);}return c.join(`
|
|
3
|
+
`)},b=(e,r,n,t,o)=>{let s=O,a=`[${s}] ${t.message}`,p=t.labels?.[0];if(!p)return a;let{source:i,spans:m}=j(r),c=L(n,m),l=h=>D(typeof h=="number"?h:0,c,i.length),g=l(p.start),u=l(p.end);u<=g&&(u=Math.min(i.length,g+1));let d=R(i,g),f=R(i,Math.max(g,u-1)),E=v(i,g,u,d.line,f.line),x=`[${s}] ${t.message}`;return x+=`
|
|
4
|
+
--> ${e} template:${d.line}:${d.column}`,p.message&&(x+=`
|
|
5
5
|
${p.message}`),E&&(x+=`
|
|
6
6
|
${E}`),t.helpMessage&&(x+=`
|
|
7
|
-
${t.helpMessage}`),x};var
|
|
7
|
+
${t.helpMessage}`),x};var W=/<\s*$/,U=/<\/\s*$/,$="__KX_EXPR__",X=new RegExp(`${$}\\d+_\\d+__`,"g"),V=0;var A={lang:"jsx",sourceType:"module",range:true,preserveParens:true},k=e=>{for(let r of e.body)if(r.type==="ExpressionStatement"){let n=r.expression;if(n.type==="JSXElement"||n.type==="JSXFragment")return n}throw new Error("The jsx template must contain a single JSX element or fragment.")},S=e=>{switch(e.type){case "JSXIdentifier":return e.name;case "JSXNamespacedName":return `${e.namespace.name}:${e.name.name}`;case "JSXMemberExpression":return `${S(e.object)}.${e.property.name}`;default:return ""}},C=(e,r)=>{if(!e||typeof e!="object")return;let n=e;typeof n.type=="string"&&(r(n),Object.values(n).forEach(t=>{if(t){if(Array.isArray(t)){t.forEach(o=>C(o,r));return}typeof t=="object"&&C(t,r);}}));},M=(e,r)=>{let n=w(e);if(!n)return [];let t=[];X.lastIndex=0;let o=0,s;for(;s=X.exec(n);){let p=s.index,i=n.slice(o,p);i&&t.push(i);let m=s[0];r.has(m)?t.push(r.get(m)):t.push(m),o=p+m.length;}let a=n.slice(o);return a&&t.push(a),t},Z=(e,r)=>{let n=new Set;return C(e,t=>{t.type==="Identifier"&&r.placeholders.has(t.name)&&n.add(t.name);}),Array.from(n)},N=(e,r,n)=>{if(e.type==="JSXElement"||e.type==="JSXFragment")return n(e);if(!("range"in e)||!e.range)throw new Error("Unable to evaluate expression: missing source range information.");let[t,o]=e.range,s=r.source.slice(t,o),a=Z(e,r);try{let p=new Function(...a,`"use strict"; return (${s});`),i=a.map(m=>r.placeholders.get(m));return p(...i)}catch(p){throw new Error(`Failed to evaluate expression ${s}: ${p.message}`)}},G=e=>{let r=e.replace(/[^a-zA-Z0-9_$]/g,"");return r?/[A-Za-z_$]/.test(r[0])?r:`Component${r}`:"Component"},H=(e,r,n)=>{let t=n.get(e);if(t)return t;let o=e.displayName||e.name||`Component${r.length}`,s=G(o??""),a=s,p=1;for(;r.some(m=>m.name===a);)a=`${s}${p++}`;let i={name:a,value:e};return r.push(i),n.set(e,i),i},F=(e,r)=>{let n=e.raw??e,t=new Map,o=[],s=new Map,a=n[0]??"",p=V++,i=0,m=[];for(let c=0;c<r.length;c++){let l=n[c]??"",g=n[c+1]??"",u=r[c],d=W.test(l)||U.test(l),f;if(d&&typeof u=="function")f=H(u,o,s).name;else if(d&&typeof u=="string")f=u;else {let h=`${$}${p}_${i++}__`;t.set(h,u),f=h;}let E=a.length;a+=f;let x=a.length;m.push({index:c,sourceStart:E,sourceEnd:x}),a+=g;}return {source:a,placeholders:t,bindings:o,diagnostics:{expressionRanges:m}}};var Q=e=>!e||typeof e=="string"?false:typeof e[Symbol.iterator]=="function",Y=e=>!e||typeof e!="object"&&typeof e!="function"?false:typeof e.then=="function",y=(e,r)=>{if(r!=null&&typeof r!="boolean"){if(Y(r))throw new Error("Async values are not supported inside reactJsx template results.");if(Array.isArray(r)){r.forEach(n=>y(e,n));return}if(Q(r)){for(let n of r)y(e,n);return}e.push(r);}},T=(e,r)=>N(e,r,n=>J(n,r)),ee=(e,r)=>{let n={};return e.forEach(t=>{if(t.type==="JSXSpreadAttribute"){let s=T(t.argument,r);s&&typeof s=="object"&&!Array.isArray(s)&&Object.assign(n,s);return}let o=S(t.name);if(!t.value){n[o]=true;return}if(t.value.type==="Literal"){n[o]=t.value.value;return}if(t.value.type==="JSXExpressionContainer"){if(t.value.expression.type==="JSXEmptyExpression")return;n[o]=T(t.value.expression,r);}}),n},_=(e,r)=>{let n=[];return e.forEach(t=>{switch(t.type){case "JSXText":{M(t.value,r.placeholders).forEach(s=>y(n,s));break}case "JSXExpressionContainer":{if(t.expression.type==="JSXEmptyExpression")break;y(n,T(t.expression,r));break}case "JSXSpreadChild":{let o=T(t.expression,r);o!=null&&y(n,o);break}case "JSXElement":case "JSXFragment":{n.push(J(t,r));break}}}),n},P=(e,r,n)=>createElement(e,r,...n),te=(e,r)=>{let n=e.openingElement,t=S(n.name),o=r.components.get(t),s=ee(n.attributes,r),a=_(e.children,r);if(o)return P(o,s,a);if(/[A-Z]/.test(t[0]??""))throw new Error(`Unknown component "${t}". Did you interpolate it with the template literal?`);return P(t,s,a)},J=(e,r)=>{if(e.type==="JSXFragment"){let n=_(e.children,r);return createElement(Fragment,null,...n)}return te(e,r)},ne=(e,...r)=>{let n=F(e,r),t=parseSync("inline.jsx",n.source,A);if(t.errors.length>0)throw new Error(b("reactJsx",e,n.diagnostics,t.errors[0]));let o=k(t.program),s={source:n.source,placeholders:n.placeholders,components:new Map(n.bindings.map(a=>[a.name,a.value]))};return J(o,s)};export{ne as reactJsx};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type TemplateDiagnostics } from '../internal/template-diagnostics.js';
|
|
2
|
+
import { DOM_HELPER_SNIPPETS, type DomHelperKind } from './helpers/dom-snippets.js';
|
|
3
|
+
export type TemplatePlaceholder = {
|
|
4
|
+
marker: string;
|
|
5
|
+
code: string;
|
|
6
|
+
};
|
|
7
|
+
type DomCompileResult = {
|
|
8
|
+
code: string;
|
|
9
|
+
helpers: Set<DomHelperKind>;
|
|
10
|
+
};
|
|
11
|
+
export declare const compileDomTemplate: (templateSource: string, placeholders: TemplatePlaceholder[], resourcePath: string, tagName: string, templates: TemplateStringsArray, diagnostics: TemplateDiagnostics) => DomCompileResult;
|
|
12
|
+
export { DOM_HELPER_SNIPPETS };
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { parseSync } from 'oxc-parser';
|
|
2
|
+
import { formatTaggedTemplateParserError, } from '../internal/template-diagnostics.js';
|
|
3
|
+
import { DOM_HELPER_SNIPPETS } from './helpers/dom-snippets.js';
|
|
4
|
+
import { normalizeJsxText } from '../shared/normalize-text.js';
|
|
5
|
+
const TEMPLATE_PARSER_OPTIONS = {
|
|
6
|
+
lang: 'tsx',
|
|
7
|
+
sourceType: 'module',
|
|
8
|
+
range: true,
|
|
9
|
+
preserveParens: true,
|
|
10
|
+
};
|
|
11
|
+
const NAMESPACE_URIS = {
|
|
12
|
+
html: 'http://www.w3.org/1999/xhtml',
|
|
13
|
+
svg: 'http://www.w3.org/2000/svg',
|
|
14
|
+
math: 'http://www.w3.org/1998/Math/MathML',
|
|
15
|
+
};
|
|
16
|
+
const createPlaceholderMap = (placeholders) => new Map(placeholders.map(entry => [entry.marker, entry.code]));
|
|
17
|
+
const isLoaderPlaceholderIdentifier = (node) => {
|
|
18
|
+
const name = node.name;
|
|
19
|
+
return typeof name === 'string' && name.startsWith('__JSX_LOADER');
|
|
20
|
+
};
|
|
21
|
+
class DomTemplateBuilder {
|
|
22
|
+
placeholderMap;
|
|
23
|
+
helpers;
|
|
24
|
+
id = 0;
|
|
25
|
+
constructor(placeholderSource) {
|
|
26
|
+
this.placeholderMap = createPlaceholderMap(placeholderSource);
|
|
27
|
+
this.helpers = new Set();
|
|
28
|
+
}
|
|
29
|
+
compile(root) {
|
|
30
|
+
const code = this.compileNode(root, 'html');
|
|
31
|
+
return { code, helpers: this.helpers };
|
|
32
|
+
}
|
|
33
|
+
nextId(prefix) {
|
|
34
|
+
return `__jsxDom_${prefix}_${this.id++}`;
|
|
35
|
+
}
|
|
36
|
+
compileNode(node, namespace) {
|
|
37
|
+
if (node.type === 'JSXFragment') {
|
|
38
|
+
const fragVar = this.nextId('frag');
|
|
39
|
+
const lines = [`const ${fragVar} = document.createDocumentFragment()`];
|
|
40
|
+
node.children.forEach(child => {
|
|
41
|
+
const childExpr = this.compileChild(child, namespace);
|
|
42
|
+
if (childExpr) {
|
|
43
|
+
this.helpers.add('dom');
|
|
44
|
+
lines.push(`__jsxDomAppend(${fragVar}, ${childExpr})`);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
lines.push(`return ${fragVar}`);
|
|
48
|
+
return `(() => { ${lines.join('; ')} })()`;
|
|
49
|
+
}
|
|
50
|
+
const { tagExpr, namespace: tagNs } = this.compileTagName(node.openingElement.name);
|
|
51
|
+
const resolvedNs = tagNs ?? namespace;
|
|
52
|
+
const creator = resolvedNs === 'html'
|
|
53
|
+
? `document.createElement(${tagExpr})`
|
|
54
|
+
: `document.createElementNS('${NAMESPACE_URIS[resolvedNs]}', ${tagExpr})`;
|
|
55
|
+
const elVar = this.nextId('el');
|
|
56
|
+
const lines = [`const ${elVar} = ${creator}`];
|
|
57
|
+
node.openingElement.attributes.forEach(attr => {
|
|
58
|
+
if (attr.type === 'JSXSpreadAttribute') {
|
|
59
|
+
this.helpers.add('dom');
|
|
60
|
+
const value = this.compileExpression(attr.argument);
|
|
61
|
+
lines.push(`__jsxDomAssignProps(${elVar}, ${value}, '${resolvedNs}')`);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const name = this.compileAttributeName(attr.name);
|
|
65
|
+
const valueExpr = this.compileAttributeValue(attr);
|
|
66
|
+
if (!valueExpr) {
|
|
67
|
+
/* c8 ignore next */
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
this.helpers.add('dom');
|
|
71
|
+
lines.push(`__jsxDomSetProp(${elVar}, ${name}, ${valueExpr}, '${resolvedNs}')`);
|
|
72
|
+
});
|
|
73
|
+
node.children.forEach(child => {
|
|
74
|
+
const childExpr = this.compileChild(child, resolvedNs);
|
|
75
|
+
if (childExpr) {
|
|
76
|
+
this.helpers.add('dom');
|
|
77
|
+
lines.push(`__jsxDomAppend(${elVar}, ${childExpr})`);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
lines.push(`return ${elVar}`);
|
|
81
|
+
return `(() => { ${lines.join('; ')} })()`;
|
|
82
|
+
}
|
|
83
|
+
compileAttributeValue(attr) {
|
|
84
|
+
if (!attr.value) {
|
|
85
|
+
return 'true';
|
|
86
|
+
}
|
|
87
|
+
if (attr.value.type === 'Literal') {
|
|
88
|
+
return JSON.stringify(attr.value.value);
|
|
89
|
+
}
|
|
90
|
+
if (attr.value.type === 'JSXExpressionContainer') {
|
|
91
|
+
const expr = attr.value.expression;
|
|
92
|
+
if (expr.type === 'JSXEmptyExpression') {
|
|
93
|
+
/* c8 ignore next */
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
return this.compileExpression(expr);
|
|
97
|
+
}
|
|
98
|
+
/* c8 ignore next */
|
|
99
|
+
return 'undefined';
|
|
100
|
+
}
|
|
101
|
+
compileAttributeName(name) {
|
|
102
|
+
if (name.type === 'JSXIdentifier') {
|
|
103
|
+
return JSON.stringify(name.name);
|
|
104
|
+
}
|
|
105
|
+
if (name.type === 'JSXNamespacedName') {
|
|
106
|
+
return JSON.stringify(`${name.namespace.name}:${name.name.name}`);
|
|
107
|
+
}
|
|
108
|
+
if (name.type === 'JSXMemberExpression') {
|
|
109
|
+
return JSON.stringify(`${this.compileAttributeName(name.object).replace(/"/g, '')}.${name.property.name}`);
|
|
110
|
+
}
|
|
111
|
+
/* c8 ignore next */
|
|
112
|
+
return '""';
|
|
113
|
+
}
|
|
114
|
+
compileChild(child, namespace) {
|
|
115
|
+
switch (child.type) {
|
|
116
|
+
case 'JSXText': {
|
|
117
|
+
const text = normalizeJsxText(child.value);
|
|
118
|
+
if (!text)
|
|
119
|
+
return null;
|
|
120
|
+
return JSON.stringify(text);
|
|
121
|
+
}
|
|
122
|
+
case 'JSXExpressionContainer': {
|
|
123
|
+
if (child.expression.type === 'JSXEmptyExpression')
|
|
124
|
+
return null;
|
|
125
|
+
return this.compileExpression(child.expression);
|
|
126
|
+
}
|
|
127
|
+
case 'JSXSpreadChild': {
|
|
128
|
+
return this.compileExpression(child.expression);
|
|
129
|
+
}
|
|
130
|
+
case 'JSXElement':
|
|
131
|
+
case 'JSXFragment': {
|
|
132
|
+
return this.compileNode(child, namespace);
|
|
133
|
+
}
|
|
134
|
+
default:
|
|
135
|
+
/* c8 ignore next */
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
compileTagName(name) {
|
|
140
|
+
if (!name) {
|
|
141
|
+
/* c8 ignore next */
|
|
142
|
+
throw new Error('[jsx-loader] Encountered JSX element without a tag name.');
|
|
143
|
+
}
|
|
144
|
+
if (name.type === 'JSXIdentifier') {
|
|
145
|
+
if (isLoaderPlaceholderIdentifier(name)) {
|
|
146
|
+
const resolved = this.placeholderMap.get(name.name);
|
|
147
|
+
if (!resolved) {
|
|
148
|
+
throw new Error('[jsx-loader] Unable to resolve placeholder for tag expression.');
|
|
149
|
+
}
|
|
150
|
+
return { tagExpr: resolved, namespace: null };
|
|
151
|
+
}
|
|
152
|
+
const tagName = name.name;
|
|
153
|
+
const lower = tagName.toLowerCase();
|
|
154
|
+
if (lower === 'svg')
|
|
155
|
+
return { tagExpr: JSON.stringify(tagName), namespace: 'svg' };
|
|
156
|
+
if (lower === 'math')
|
|
157
|
+
return { tagExpr: JSON.stringify(tagName), namespace: 'math' };
|
|
158
|
+
return { tagExpr: JSON.stringify(tagName), namespace: null };
|
|
159
|
+
}
|
|
160
|
+
if (name.type === 'JSXMemberExpression') {
|
|
161
|
+
const tagExpr = `${this.compileAttributeName(name.object).replace(/"/g, '')}.${name.property.name}`;
|
|
162
|
+
return { tagExpr: JSON.stringify(tagExpr), namespace: null };
|
|
163
|
+
}
|
|
164
|
+
if (name.type === 'JSXNamespacedName') {
|
|
165
|
+
const tagExpr = `${name.namespace.name}:${name.name.name}`;
|
|
166
|
+
return { tagExpr: JSON.stringify(tagExpr), namespace: null };
|
|
167
|
+
}
|
|
168
|
+
/* c8 ignore next */
|
|
169
|
+
throw new Error('[jsx-loader] Unsupported tag expression in dom mode.');
|
|
170
|
+
}
|
|
171
|
+
compileExpression(node) {
|
|
172
|
+
if (node.type === 'JSXElement' || node.type === 'JSXFragment') {
|
|
173
|
+
return this.compileNode(node, 'html');
|
|
174
|
+
}
|
|
175
|
+
if (node.type === 'Identifier') {
|
|
176
|
+
const resolved = this.placeholderMap.get(node.name);
|
|
177
|
+
if (resolved)
|
|
178
|
+
return resolved;
|
|
179
|
+
return node.name;
|
|
180
|
+
}
|
|
181
|
+
if (node.type === 'Literal') {
|
|
182
|
+
return JSON.stringify(node.value);
|
|
183
|
+
}
|
|
184
|
+
if ('range' in node && Array.isArray(node.range)) {
|
|
185
|
+
throw new Error('[jsx-loader] Unable to inline complex expressions in dom mode.');
|
|
186
|
+
}
|
|
187
|
+
/* c8 ignore next */
|
|
188
|
+
throw new Error('[jsx-loader] Unable to compile expression for dom mode.');
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
export const compileDomTemplate = (templateSource, placeholders, resourcePath, tagName, templates, diagnostics) => {
|
|
192
|
+
const parsed = parseSync(`${resourcePath}?jsx-dom-template`, templateSource, TEMPLATE_PARSER_OPTIONS);
|
|
193
|
+
if (parsed.errors.length > 0) {
|
|
194
|
+
throw new Error(formatTaggedTemplateParserError(tagName, templates, diagnostics, parsed.errors[0], {
|
|
195
|
+
label: 'jsx-loader',
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
const root = extractJsxRoot(parsed.program);
|
|
199
|
+
const builder = new DomTemplateBuilder(placeholders);
|
|
200
|
+
return builder.compile(root);
|
|
201
|
+
};
|
|
202
|
+
const extractJsxRoot = (program) => {
|
|
203
|
+
for (const statement of program.body) {
|
|
204
|
+
if (statement.type === 'ExpressionStatement') {
|
|
205
|
+
const expression = statement.expression;
|
|
206
|
+
if (expression.type === 'JSXElement' || expression.type === 'JSXFragment') {
|
|
207
|
+
return expression;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
throw new Error('[jsx-loader] Expected the template to contain a single JSX root node.');
|
|
212
|
+
};
|
|
213
|
+
export { DOM_HELPER_SNIPPETS };
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
export const DOM_HELPER_SNIPPETS = {
|
|
2
|
+
dom: `const __jsxDomAppend = (parent, child) => {
|
|
3
|
+
if (child === null || child === undefined || typeof child === 'boolean') return
|
|
4
|
+
if (Array.isArray(child)) { child.forEach(entry => __jsxDomAppend(parent, entry)); return }
|
|
5
|
+
if (typeof child === 'object' && typeof child[Symbol.iterator] === 'function') {
|
|
6
|
+
for (const entry of child) __jsxDomAppend(parent, entry); return
|
|
7
|
+
}
|
|
8
|
+
if (child instanceof Node) { parent.appendChild(child); return }
|
|
9
|
+
parent.appendChild(document.createTextNode(String(child)))
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const __jsxDomClass = (el, value) => {
|
|
13
|
+
if (value === null || value === undefined || value === false) return
|
|
14
|
+
if (typeof value === 'string' || typeof value === 'number') { el.classList.add(...String(value).trim().split(/\\s+/u).filter(Boolean)); return }
|
|
15
|
+
if (Array.isArray(value)) { value.forEach(entry => __jsxDomClass(el, entry)); return }
|
|
16
|
+
if (typeof value === 'object') {
|
|
17
|
+
Object.entries(value).forEach(([key, active]) => {
|
|
18
|
+
if (active) el.classList.add(key)
|
|
19
|
+
else el.classList.remove(key)
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const __jsxDomStyle = (el, value) => {
|
|
25
|
+
if (value === null || value === undefined || value === false) return
|
|
26
|
+
const style = el.style
|
|
27
|
+
if (!style) return
|
|
28
|
+
if (typeof value === 'string') { style.cssText += value; return }
|
|
29
|
+
if (typeof value === 'object') {
|
|
30
|
+
Object.entries(value).forEach(([key, v]) => {
|
|
31
|
+
if (v === null || v === undefined) return
|
|
32
|
+
if (key.startsWith('--')) { style.setProperty(key, String(v)); return }
|
|
33
|
+
style[key] = v
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const __jsxDomResolveHandler = (propName, value) => {
|
|
39
|
+
if (typeof value === 'function' || (value && typeof value === 'object' && typeof value.handleEvent === 'function')) {
|
|
40
|
+
return { listener: value }
|
|
41
|
+
}
|
|
42
|
+
if (!value || typeof value !== 'object' || !('handler' in value)) {
|
|
43
|
+
return null
|
|
44
|
+
}
|
|
45
|
+
const handler = value.handler
|
|
46
|
+
if (typeof handler !== 'function' && !(handler && typeof handler === 'object' && typeof handler.handleEvent === 'function')) {
|
|
47
|
+
return null
|
|
48
|
+
}
|
|
49
|
+
const options = value.options ? { ...value.options } : undefined
|
|
50
|
+
const assign = (key, v) => {
|
|
51
|
+
if (v === undefined || v === null) return
|
|
52
|
+
if (!options) options = {}
|
|
53
|
+
options[key] = v
|
|
54
|
+
}
|
|
55
|
+
assign('capture', value.capture)
|
|
56
|
+
assign('once', value.once)
|
|
57
|
+
assign('passive', value.passive)
|
|
58
|
+
assign('signal', value.signal ?? undefined)
|
|
59
|
+
return { listener: handler, options }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const __jsxDomParseEventName = raw => {
|
|
63
|
+
if (!raw.startsWith('on')) return null
|
|
64
|
+
if (raw.startsWith('on:')) {
|
|
65
|
+
const name = raw.slice(3)
|
|
66
|
+
if (!name) return null
|
|
67
|
+
const capture = name.endsWith('Capture')
|
|
68
|
+
const eventName = capture ? name.slice(0, -7) : name
|
|
69
|
+
if (!eventName) return null
|
|
70
|
+
return { eventName, capture }
|
|
71
|
+
}
|
|
72
|
+
const name = raw.slice(2)
|
|
73
|
+
if (!name) return null
|
|
74
|
+
const capture = name.endsWith('Capture')
|
|
75
|
+
const eventName = (capture ? name.slice(0, -7) : name).toLowerCase()
|
|
76
|
+
if (!eventName) return null
|
|
77
|
+
return { eventName, capture }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const __jsxDomEvent = (el, propName, value) => {
|
|
81
|
+
const parsed = __jsxDomParseEventName(propName)
|
|
82
|
+
if (!parsed) return false
|
|
83
|
+
const resolved = __jsxDomResolveHandler(propName, value)
|
|
84
|
+
if (!resolved) return true
|
|
85
|
+
let options = resolved.options ? { ...resolved.options } : undefined
|
|
86
|
+
if (parsed.capture) {
|
|
87
|
+
if (!options) options = { capture: true }
|
|
88
|
+
else options.capture = true
|
|
89
|
+
}
|
|
90
|
+
el.addEventListener(parsed.eventName, resolved.listener, options)
|
|
91
|
+
return true
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const __jsxDomNamespaceForAttr = (raw, namespace) => {
|
|
95
|
+
if (!raw.includes(':')) return null
|
|
96
|
+
const prefix = raw.split(':', 1)[0]
|
|
97
|
+
if (prefix === 'xml') return 'http://www.w3.org/XML/1998/namespace'
|
|
98
|
+
if (prefix === 'xlink') return 'http://www.w3.org/1999/xlink'
|
|
99
|
+
if (namespace === 'svg') return 'http://www.w3.org/2000/svg'
|
|
100
|
+
if (namespace === 'math') return 'http://www.w3.org/1998/Math/MathML'
|
|
101
|
+
return null
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const __jsxDomSetProp = (el, name, value, namespace) => {
|
|
105
|
+
if (value === null || value === undefined) return
|
|
106
|
+
if (name === 'dangerouslySetInnerHTML' && value && typeof value === 'object' && '__html' in value) {
|
|
107
|
+
el.innerHTML = String(value.__html ?? '')
|
|
108
|
+
return
|
|
109
|
+
}
|
|
110
|
+
const ns = __jsxDomNamespaceForAttr(name, namespace)
|
|
111
|
+
if (name === 'ref') {
|
|
112
|
+
if (typeof value === 'function') { value(el); return }
|
|
113
|
+
if (value && typeof value === 'object') { value.current = el; return }
|
|
114
|
+
}
|
|
115
|
+
if (name === 'class' || name === 'className') { __jsxDomClass(el, value); return }
|
|
116
|
+
if (name === 'style') { __jsxDomStyle(el, value); return }
|
|
117
|
+
if (__jsxDomEvent(el, name, value)) return
|
|
118
|
+
if (typeof value === 'boolean') {
|
|
119
|
+
if (value) {
|
|
120
|
+
if (ns) el.setAttributeNS(ns, name, '')
|
|
121
|
+
else el.setAttribute(name, '')
|
|
122
|
+
} else {
|
|
123
|
+
if (ns) el.removeAttributeNS(ns, name)
|
|
124
|
+
else el.removeAttribute(name)
|
|
125
|
+
}
|
|
126
|
+
if (name in el) { try { el[name] = value } catch {}
|
|
127
|
+
}
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
if (name.startsWith('data-')) { el.setAttribute(name, value as any); return }
|
|
131
|
+
if (name in el && name !== 'list') {
|
|
132
|
+
try { (el as any)[name] = value } catch {}
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
if (ns) el.setAttributeNS(ns, name, value as any)
|
|
136
|
+
else el.setAttribute(name, value as any)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const __jsxDomAssignProps = (el, props, namespace) => {
|
|
140
|
+
if (!props) return
|
|
141
|
+
Object.entries(props).forEach(([name, value]) => {
|
|
142
|
+
__jsxDomSetProp(el, name, value, namespace)
|
|
143
|
+
})
|
|
144
|
+
}
|
|
145
|
+
`,
|
|
146
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const formatImportSpecifier = (spec) => {
|
|
2
|
+
const node = spec;
|
|
3
|
+
if (node.type === 'ImportDefaultSpecifier') {
|
|
4
|
+
const name = node.local?.name;
|
|
5
|
+
if (!name) {
|
|
6
|
+
throw new Error('[jsx-loader] Encountered default import without a local name.');
|
|
7
|
+
}
|
|
8
|
+
return name;
|
|
9
|
+
}
|
|
10
|
+
if (node.type === 'ImportNamespaceSpecifier') {
|
|
11
|
+
const name = node.local?.name;
|
|
12
|
+
if (!name) {
|
|
13
|
+
throw new Error('[jsx-loader] Encountered namespace import without a local name.');
|
|
14
|
+
}
|
|
15
|
+
return `* as ${name}`;
|
|
16
|
+
}
|
|
17
|
+
if (node.type === 'ImportSpecifier') {
|
|
18
|
+
const imported = node.imported?.name;
|
|
19
|
+
if (!imported) {
|
|
20
|
+
throw new Error('[jsx-loader] Encountered named import without an imported name.');
|
|
21
|
+
}
|
|
22
|
+
const local = node.local?.name ?? imported;
|
|
23
|
+
return imported === local ? imported : `${imported} as ${local}`;
|
|
24
|
+
}
|
|
25
|
+
return '';
|
|
26
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const materializeSlice: (start: number, end: number, source: string, replacements: Map<string, string>) => string;
|