@dlightjs/view-parser
Advanced tools
Comparing version 0.10.1 to 1.0.0-alpha.0
@@ -1,14 +0,78 @@ | ||
import * as t from '@babel/types'; | ||
import Babel, { types } from '@babel/core'; | ||
interface ParserNode { | ||
tag: t.Node | string; | ||
attr: Record<string, any>; | ||
children: ParserNode[]; | ||
interface ViewProp { | ||
value: types.Expression; | ||
viewPropMap?: Record<string, ViewUnit[]>; | ||
} | ||
declare function parseBlock(nodes: any, path: any): ParserNode[]; | ||
declare function parseBody(nodes: any, path: any): ParserNode[]; | ||
interface TextUnit { | ||
type: "text"; | ||
content: types.Expression; | ||
} | ||
interface HTMLUnit { | ||
type: "html"; | ||
tag: types.Expression; | ||
content?: ViewProp; | ||
props?: Record<string, ViewProp>; | ||
children?: ViewUnit[]; | ||
} | ||
interface CompUnit { | ||
type: "comp"; | ||
tag: types.Expression; | ||
content?: ViewProp; | ||
props?: Record<string, ViewProp>; | ||
children?: ViewUnit[]; | ||
} | ||
interface ForUnit { | ||
type: "for"; | ||
item: types.LVal; | ||
array: types.Expression; | ||
key?: types.Expression; | ||
children: ViewUnit[]; | ||
} | ||
interface IfBranch { | ||
condition: types.Expression; | ||
children: ViewUnit[]; | ||
} | ||
interface IfUnit { | ||
type: "if"; | ||
branches: IfBranch[]; | ||
} | ||
interface EnvUnit { | ||
type: "env"; | ||
props: Record<string, ViewProp>; | ||
children: ViewUnit[]; | ||
} | ||
interface ExpUnit { | ||
type: "exp"; | ||
content: ViewProp; | ||
props?: Record<string, ViewProp>; | ||
} | ||
interface SubviewUnit { | ||
type: "subview"; | ||
tag: string; | ||
props?: Record<string, ViewProp>; | ||
children?: ViewUnit[]; | ||
} | ||
type ViewUnit = TextUnit | HTMLUnit | CompUnit | IfUnit | ForUnit | EnvUnit | ExpUnit | SubviewUnit; | ||
interface ViewParserConfig { | ||
babelApi: typeof Babel; | ||
subviewNames: string[]; | ||
htmlTags: string[]; | ||
} | ||
interface ViewParserOption { | ||
compWrapper?: string; | ||
htmlTagWrapper?: string; | ||
environmentTagName?: string; | ||
expressionTagName?: string; | ||
} | ||
declare const htmlTags: string[]; | ||
declare function isAHtmlTag(key: string): boolean; | ||
/** | ||
* @brief Generate view units from a babel ast | ||
* @param statement | ||
* @param config | ||
* @param options | ||
* @returns ViewUnit[] | ||
*/ | ||
declare function parseView(statement: types.BlockStatement, config: ViewParserConfig, options?: ViewParserOption): ViewUnit[]; | ||
export { ParserNode, htmlTags, isAHtmlTag, parseBlock, parseBody }; | ||
export { CompUnit, EnvUnit, ExpUnit, ForUnit, HTMLUnit, IfBranch, IfUnit, SubviewUnit, TextUnit, ViewParserConfig, ViewParserOption, ViewProp, ViewUnit, parseView }; |
@@ -1,2 +0,2 @@ | ||
import*as t from"@babel/types";function m(e){return t.variableDeclaration("const",[t.variableDeclarator(t.identifier("_"),e)])}function g(){return Math.random().toString(32).slice(2)}function y(e){return t.variableDeclaration("const",[t.variableDeclarator(e,t.nullLiteral())])}function f(e,r,n){if(!r)return{key:e,value:t.booleanLiteral(!0),nodes:{}};let a={};return n.scope.traverse(m(r),{DoExpression(i){let o=i.node,s=g();a[s]=P(o.body.body,i);let l=t.stringLiteral(s);o===r&&(r=l),i.replaceWith(l),i.skip()}}),{key:e,value:r,nodes:a}}function b(e){for(;e;)if(e=e.callee?.object,t.isCallExpression(e))return!1;return!0}function h(e,r){let n={tag:"",attr:{props:[]},children:[]},a=e;for(;a&&a.callee?.object&&!b(a);){let i=a.callee.property.name;n.attr.props.unshift(f(i,a.arguments[0],r)),a=a.callee.object}return a.arguments.length>0&&n.attr.props.unshift(f("_$content",a.arguments[0],r)),n.tag=a.callee,n}function d(e){return t.isDirectiveLiteral(e)&&(e=t.stringLiteral(e.value)),{tag:"_$text",attr:{_$content:e},children:[]}}function x(e,r){let n=p(e.tag,r);Array.isArray(n)||(n=[n]);let a={tag:"_$text",attr:{_$content:e.quasi},children:[]};return[...n,a]}function p(e,r){return t.isCallExpression(e)?h(e,r):t.isStringLiteral(e)||t.isTemplateLiteral(e)?d(e):t.isTaggedTemplateExpression(e)?x(e,r):{tag:t.identifier("_"),attr:{props:[f("_$content",e,r)]},children:[]}}function N(e,r){let n=e.left.declarations[0].id,a=e.right,i={tag:"for",attr:{item:n,array:a},children:[]},o=e.body.body;if(o.length===0)i.children=[];else{if(t.isArrayExpression(o[0].expression)){let s=o[0].expression.elements[0];t.isNullLiteral(s)||t.isIdentifier(s)&&s.name==="undefined"||(i.attr.key=s),o=o.slice(1)}else{let s=JSON.parse(JSON.stringify(n));r.scope.traverse(y(s),{ObjectPattern(l){l.node.type="ObjectExpression"},ArrayPattern(l){l.node.type="ArrayExpression"}}),i.attr.key=s}i.children=c(o,r)}return i}function v(e,r){return{tag:"if",attr:{conditions:u(e,r)},children:[]}}function u(e,r){let n=[],a=e.test,i=c(e.consequent.body,r);return n.push({condition:a,parserNodes:i}),t.isIfStatement(e.alternate)?n.push(...u(e.alternate,r)):e.alternate&&n.push({condition:t.booleanLiteral(!0),parserNodes:c(e.alternate.body,r)}),n}function c(e,r){let n=[];for(let a of e)if(t.isExpressionStatement(a)){let i=p(a.expression,r);Array.isArray(i)||(i=[i]),n.push(...i)}else t.isBlockStatement(a)?n[n.length-1].children=c(a.body,r):t.isForOfStatement(a)?n.push(N(a,r)):t.isIfStatement(a)?n.push(v(a,r)):t.isDirective(a)&&n.push(d(a.value));return n}function P(e,r){return c(e,r)}var L=["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","label","legend","li","link","main","map","mark","menu","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","slot","small","source","span","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr","acronym","applet","basefont","bgsound","big","blink","center","dir","font","frame","frameset","isindex","keygen","listing","marquee","menuitem","multicol","nextid","nobr","noembed","noframes","param","plaintext","rb","rtc","spacer","strike","tt","xmp","animate","animateMotion","animateTransform","circle","clipPath","defs","desc","ellipse","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","filter","foreignObject","g","image","line","linearGradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialGradient","rect","set","stop","svg","switch","symbol","text","textPath","tspan","use","view"];function T(e){return L.includes(e)}export{L as htmlTags,T as isAHtmlTag,c as parseBlock,P as parseBody}; | ||
import{createErrorHandler as g}from"@dlightjs/error-handler";var a=g("ViewParser",{1:"Invalid syntax in DLight's View, only accepts dot chain call expression",2:"First argument of $0() must be an expression",3:"Invalid syntax in DLight's View, only accepts expression as props",4:"Invalid SubView calling, only accepts static subview calling like `this.SubView()`"},{1:"DLight only accepts ForOfStatement as for loop, skipping this statement",2:"EnvUnit must have at least one child, skipping this statement",3:"Only Env/Comp/HTMLUnit can have a statement block as its children, skipping this statement",4:"If you want to use a key in a for loop, make the first statement as a label statement like `key: item`, skipping this key for now",5:"ForUnit must have at least one child, skipping this statement"},{1:"EnvUnit must have at least one prop, skipping this statement and flattening its children"});var l=class{compWrapper="comp";htmlTagWrapper="tag";environmentTagName="env";expressionTagName="_";config;options;t;traverse;subviewNames;htmlTags;viewUnits=[];constructor(t,e){this.config=t,this.options=e,this.t=t.babelApi.types,this.traverse=t.babelApi.traverse,this.subviewNames=t.subviewNames,this.htmlTags=t.htmlTags,e?.environmentTagName&&(this.environmentTagName=e.environmentTagName),e?.expressionTagName&&(this.expressionTagName=e.expressionTagName),e?.htmlTagWrapper&&(this.htmlTagWrapper=e.htmlTagWrapper),e?.compWrapper&&(this.compWrapper=e.compWrapper)}parse(t){return[...t.directives,...t.body].forEach(this.parseStatement.bind(this)),this.viewUnits.length===1&&this.viewUnits[0].type==="env"&&this.viewUnits[0].children.length===0?(a.error2(),[]):this.viewUnits}parseStatement(t){if(!this.isInvalidExpression(t)){if(this.t.isExpressionStatement(t)){this.parseExpression(t.expression);return}if(this.t.isForOfStatement(t)){this.parseFor(t);return}if(this.t.isIfStatement(t)){this.parseIf(t);return}if(this.t.isDirective(t)){this.parseText(t.value);return}if(this.t.isBlockStatement(t)){let e=this.viewUnits[this.viewUnits.length-1],i=e?.type,s=this.parseView(t);i==="html"?(delete e.content,e.children=s):i==="comp"||i==="subview"?e.children=s:i==="env"?s.length>0?e.children=s:(this.viewUnits.pop(),a.error2()):a.error3()}}}parseExpression(t){if(this.t.isCallExpression(t)){this.parseTag(t);return}if(this.t.isStringLiteral(t)||this.t.isTemplateLiteral(t)){this.parseText(t);return}if(this.t.isTaggedTemplateExpression(t)){this.parseTaggedTemplate(t);return}this.viewUnits.push({type:"exp",content:this.parseProp(t)})}parseIfBranches(t){let e=[],i=t.test,s=this.t.isBlockStatement(t.consequent)?t.consequent:this.t.blockStatement([t.consequent]);if(e.push({condition:i,children:this.parseView(s)}),this.t.isIfStatement(t.alternate))e.push(...this.parseIfBranches(t.alternate));else if(t.alternate){let r=this.t.isBlockStatement(t.alternate)?t.alternate:this.t.blockStatement([t.alternate]);e.push({condition:this.t.booleanLiteral(!0),children:this.parseView(r)})}return e}parseIf(t){this.viewUnits.push({type:"if",branches:this.parseIfBranches(t)})}parseFor(t){let e=t.left;this.t.isVariableDeclaration(e)||a.throw1();let i=e.declarations[0].id,s=t.right,r,n=t.body,p;if(this.t.isExpressionStatement(n))p=[n];else if(this.t.isBlockStatement(n)){let o=n.body;if(o.length===0)return a.error5();let h=o[0];if(this.t.isLabeledStatement(h)&&this.t.isIdentifier(h.label)){if(h.label.name!=="key"||!this.t.isExpressionStatement(h.body))a.error4();else{let c=h.body.expression;this.t.isExpression(c)&&!(this.t.isNullLiteral(c)||this.t.isIdentifier(c)&&c.name==="undefined")&&(r=c)}p=o.slice(1)}else p=o}else return;let m=p.filter(o=>this.t.isDirective(o)),v=p.filter(o=>!this.t.isDirective(o)),u=this.t.blockStatement(v,m);this.viewUnits.push({type:"for",item:i,array:s,key:r,children:this.parseView(u)})}parseText(t){this.t.isDirectiveLiteral(t)&&(t=this.t.stringLiteral(t.value)),this.viewUnits.push({type:"text",content:t})}parseTaggedTemplate(t){if(this.t.isStringLiteral(t.tag)||this.t.isTemplateLiteral(t.tag)){this.viewUnits.push({type:"text",content:t.tag}),this.viewUnits.push({type:"text",content:t.quasi});return}this.viewUnits.push({type:"exp",content:this.parseProp(t)})}parseProp(t){if(t&&!this.t.isExpression(t)&&a.throw3(),t=t,!t)return{value:this.t.booleanLiteral(!0),viewPropMap:{}};let e={};return this.traverse(this.valueWrapper(t),{ArrowFunctionExpression:i=>{let s=i.node;if(s.params.length===0)return;let r=s.params[0];if(!this.t.isIdentifier(r,{name:"View"})&&!this.t.isIdentifier(r,{name:"_View"}))return;let n=this.t.isBlockStatement(s.body)?s.body:this.t.blockStatement([this.t.expressionStatement(s.body)]),p=this.uid();e[p]=this.parseView(n);let m=this.t.stringLiteral(p);s===t&&(t=m),i.replaceWith(m),i.skip()}}),{value:t,viewPropMap:e}}parseTag(t){let e={},i=t;for(;this.t.isMemberExpression(i?.callee)&&i?.callee?.object&&!this.isPureMemberExpression(i.callee);){let r=i.callee.property;if(!this.t.isIdentifier(r)||!this.t.isCallExpression(i.callee.object)){a.throw1();continue}let n=r.name,p=this.parseProp(i.arguments[0]);e[n]=p,i=i.callee.object}let s;if(i.arguments.length>0&&(s=this.parseProp(i.arguments[0])),this.t.isIdentifier(i.callee)){let r=i.callee.name;if(r===this.expressionTagName&&s){this.viewUnits.push({type:"exp",content:s,props:e});return}if(r===this.environmentTagName){if(Object.keys(e).length===0){a.warn1();return}this.viewUnits.push({type:"env",props:e,children:[]});return}if(this.htmlTags.includes(r)){this.viewUnits.push({type:"html",tag:this.t.stringLiteral(r),content:s,props:e});return}this.viewUnits.push({type:"comp",tag:i.callee,content:s,props:e});return}if(this.t.isMemberExpression(i.callee)&&this.t.isThisExpression(i.callee.object)&&this.t.isIdentifier(i.callee.property)&&this.subviewNames.includes(i.callee.property.name)){if(s&&(e.content=s),!(this.t.isMemberExpression(i.callee)&&this.t.isThisExpression(i.callee.object)&&this.t.isIdentifier(i.callee.property)))return a.throw4();this.viewUnits.push({type:"subview",tag:i.callee.property.name,props:e});return}if(this.t.isExpression(i.callee)){let[r,n]=this.alterTagType(i.callee);this.viewUnits.push({type:r,tag:n,content:s,props:e})}}isPureMemberExpression(t){let e=!0;return this.traverse(this.valueWrapper(t),{CallExpression:()=>{e=!1}}),e}alterTagType(t){if(this.t.isCallExpression(t)&&this.t.isIdentifier(t.callee)){let e=t.callee.name,i=e===this.htmlTagWrapper?"html":e===this.compWrapper?"comp":void 0;if(i){let s=t.arguments[0];return this.t.isExpression(s)||a.throw2(e),[i,s]}}return["comp",t]}isInvalidExpression(t){return this.t.isForStatement(t)&&!this.t.isForOfStatement(t)?(a.error1(),!0):!1}valueWrapper(t){return this.t.file(this.t.program([this.t.expressionStatement(t)]))}parseView(t){return new l(this.config,this.options).parse(t)}uid(){return Math.random().toString(36).slice(2)}};function T(f,t,e){return new l(t,e).parse(f)}export{T as parseView}; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@dlightjs/view-parser", | ||
"version": "0.10.1", | ||
"description": "DLight's view parser", | ||
"version": "1.0.0-alpha.0", | ||
"description": "DLight DSL syntax parser", | ||
"author": { | ||
@@ -10,4 +10,3 @@ "name": "IanDx", | ||
"keywords": [ | ||
"dlight.js", | ||
"babel-preset" | ||
"dlight.js" | ||
], | ||
@@ -23,11 +22,28 @@ "license": "MIT", | ||
"devDependencies": { | ||
"tsup": "^6.5.0", | ||
"typescript": "^5.1.6" | ||
"@babel/core": "^7.20.12", | ||
"@types/babel__core": "^7.20.5", | ||
"@vitest/ui": "^0.34.5", | ||
"tsup": "^6.7.0", | ||
"typescript": "^5.3.2", | ||
"vitest": "^0.34.5" | ||
}, | ||
"dependencies": { | ||
"@babel/types": "^7.20.7" | ||
"@dlightjs/error-handler": "1.0.0-alpha.0" | ||
}, | ||
"tsup": { | ||
"entry": [ | ||
"src/index.ts" | ||
], | ||
"format": [ | ||
"cjs", | ||
"esm" | ||
], | ||
"clean": true, | ||
"dts": true, | ||
"minify": true | ||
}, | ||
"scripts": { | ||
"build": "tsup --sourcemap" | ||
"build": "tsup --sourcemap", | ||
"test": "vitest --ui" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
71295
131
6
+ Added@dlightjs/error-handler@1.0.0-alpha.0(transitive)
- Removed@babel/types@^7.20.7
- Removed@babel/helper-string-parser@7.25.9(transitive)
- Removed@babel/helper-validator-identifier@7.25.9(transitive)
- Removed@babel/types@7.26.9(transitive)