Skip to content

Instantly share code, notes, and snippets.

@leizongmin
Last active December 24, 2018 15:18
Show Gist options
  • Save leizongmin/4ab23d388e0e399f31e8557ec1c42f22 to your computer and use it in GitHub Desktop.
Save leizongmin/4ab23d388e0e399f31e8557ec1c42f22 to your computer and use it in GitHub Desktop.
JSX语法转换
<div class="xxx" zz="{&quote;a&quote;:1}">
<text>hello</text>
<a>dsds</a>
ok
<x>
<y>z</y>
</x>
</div>
const a = $$html(
"div",
{ class: "xxx", zz: { a: 1 } },
$$html("text", null, "hello"),
$$html("a", null, "dsds"),
"ok",
$$html("x", null, $$html("y", null, "z"))
);
console.log(a);
function $$html(
name: string,
props?: Record<string, any>,
...childs: string[]
): string {
if (!childs) return buildSelfCloseTag(name, buildProps(props));
return buildTag(name, buildProps(props), childs);
function buildSelfCloseTag(name: string, props: string) {
if (props) return `<${name} ${props} />`;
return `<${name} />`;
}
function buildTag(name: string, props: string, childs: string[]) {
if (props) return `<${name} ${props}>${childs.join("")}</${name}>`;
return `<${name}>${childs.join("")}</${name}>`;
}
function buildProps(props?: Record<string, any>) {
if (!props) return "";
return Object.keys(props)
.map(k => `${k}="${toString(props[k])}"`)
.join(" ");
}
function toString(v: any) {
switch (typeof v) {
case "string":
case "number":
case "bigint":
case "boolean":
case "function":
case "symbol":
return htmlEscape(v.toString());
case "undefined":
return "";
default:
if (!v) return "";
return htmlEscape(JSON.stringify(v));
}
}
function htmlEscape(str: string) {
return str
.replace(/"/g, "&quote;")
.replace(/\r?\n/g, "&newline;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
}
}
const a = (
<div class="xxx" zz={{ a: 1 }}>
<text>hello</text>
<a>dsds</a>
ok
<x>
<y>z</y>
</x>
</div>
);
console.log(a);
{
"compilerOptions": {
"jsx": "react",
"jsxFactory": "$$html",
"target": "esnext"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment