This commit is contained in:
2022-12-09 16:41:41 +08:00
parent c1cce5a7c2
commit ff7aa8774f
2003 changed files with 156639 additions and 140 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,146 @@
import type { BuiltInParserName } from "prettier";
import { zlibSync, unzlibSync, strToU8, strFromU8 } from "fflate";
const scriptRe = /<script[^>]*>([\s\S]*)<\/script>/;
const exportDefaultRe = /export\s*default\s*\{([\s\S]*)\}\;?\s*<\/script>/;
const setupRe = /setup\s*\(\)\s*\{([\s\S]*)return\s*\{([\s\S]*)\}\;?\s*\}\;?/;
const layerRe =
/import\s?\{\s?layer\s?\}\s?from\s?[\"|\']\@layui\/layer-vue[\"|\']/;
// danger: 以下字符串拼接代码不可改动缩进或换行,否则会影响 URI hash 解码后代码的排版
const MAIN_FILE_NAME = "App.vue";
/**
* 将代码编码为 URI hash, 生成 playground 链接
* @param source 源码
* @param convertSetupSugar 转换 setup仅字符串替换没有做任何语法分析
* @returns 处理后的代码URI hsah playground 链接
}
*/
export const openPlayground = async (
source: string,
convertSetupSugar: boolean
) => {
const decodeCode = source;
const scriptResult = decodeCode.match(scriptRe);
// 替换 script 标签
let code: string | undefined = decodeCode;
if (convertSetupSugar) {
if (scriptResult) {
code = decodeCode.replace(
scriptRe,
`<script lang="ts" setup>$1
</script>`
);
} else {
code = `${decodeCode}
<script lang="ts" setup>
</script>`;
}
// 去除 export default,保留其中的内容
const exportDefaultResult = code.match(exportDefaultRe);
if (exportDefaultResult) {
code = code.replace(
exportDefaultRe,
trimBr(exportDefaultResult[1] + `</script>`).trim()
);
// console.log("export",code);
}
// 去除 setup 函数,保留其中的内容
const setupResult = code.match(setupRe);
if (setupResult) {
code = code.replace(setupRe, trimBr(setupResult[1]));
// console.log("setup",code);
}
}
// 替换 layer 引入语句
// playground 中使用最新版 layer 请从 @layui/layer-vue 引入
if (code.match(layerRe)) {
code = code.replace(layerRe, `import { layer } from "@layui/layui-vue"`);
// console.log("layer",code);
}
code = await formatCode(MAIN_FILE_NAME, code);
const originCode = {
[MAIN_FILE_NAME]: code,
};
const encoded = utoa(JSON.stringify(originCode));
const link = `https://layui-vue.gitee.io/sandbox-vue/#${encoded}`;
return {
code,
encoded,
link,
};
};
/**
*
* @returns 格式化代码
*/
async function formatCode(filename: string, data: string) {
const [format, parserHtml, parserTypeScript, parserBabel, parserPostcss] =
await Promise.all([
import("prettier/standalone").then((r) => r.format),
import("prettier/parser-html").then((m) => m.default),
import("prettier/parser-typescript").then((m) => m.default),
import("prettier/parser-babel").then((m) => m.default),
import("prettier/parser-postcss").then((m) => m.default),
]);
let code = data;
let parser: BuiltInParserName;
if (filename.endsWith(".vue")) {
parser = "vue";
} else if (filename.endsWith(".js")) {
parser = "babel";
} else if (filename.endsWith(".ts")) {
parser = "typescript";
} else if (filename.endsWith(".json")) {
parser = "json";
} else {
return;
}
code = format(code, {
parser,
plugins: [parserHtml, parserTypeScript, parserBabel, parserPostcss],
semi: false, // 语句末尾打印分号
singleQuote: true, // 使用单引号
vueIndentScriptAndStyle: false, // 是否缩进 Vue 文件中的 script 和 style 标签
});
return code;
}
/**
* 去除字符串两端的空白行
* @param str
* @returns
*/
function trimBr(str: string): string {
return str.replace(/(^[\r\n]*)|([\r\n]*$)/, "");
}
export function utoa(data: string): string {
const buffer = strToU8(data);
const zipped = zlibSync(buffer, { level: 9 });
const binary = strFromU8(zipped, true);
return btoa(binary);
}
export function atou(base64: string): string {
const binary = atob(base64);
// zlib header (x78), level 9 (xDA)
if (binary.startsWith("\x78\xDA")) {
const buffer = strToU8(binary, true);
const unzipped = unzlibSync(buffer);
return strFromU8(unzipped);
}
// old unicode hacks for backward compatibility
// https://base64.guru/developers/javascript/examples/unicode-strings
return decodeURIComponent(escape(binary));
}

View File

@@ -0,0 +1,7 @@
export const TAG_COLORS = ["primary", "normal", "warm", "danger"] as const;
export type TagType = typeof TAG_COLORS[number];
export type TagShape = "square" | "round";
export type TagVariant = "dark" | "light" | "plain";

View File

@@ -0,0 +1 @@
xm<><6D>n<EFBFBD>0 <0C>9<EFBFBD>)<29><>@<40><><EFBFBD><02>Gv<47>^ IM<15>ĕ<EFBFBD>v<EFBFBD>?<3F><><EFBFBD> N<><4E><EFBFBD><EFBFBD><EFBFBD>sl /<2F>o3<w<>r<>v<><08><>Qn<51><6E><EFBFBD>G×~<7E>N<EFBFBD><4E><04>_<EFBFBD><5F><EFBFBD>Ƥ<16>^W<><1F>[-B<><42><EFBFBD>ђ'2;<3B>y\<5C>2bR†U<10><>T2Nn6wz<77><7A>n<EFBFBD>x;<3B><>QS<51><53>F/W<><57>R<EFBFBD>[xG)<29><><03>e(<28> ?<15> ޝV0<56>AVp<56>><3E>~<7E>$ <0B>l<EFBFBD><6C><EFBFBD><17>$<24>t<EFBFBD>{]V<56><7F>ߩu+

View File

@@ -0,0 +1,4 @@
x<01>RMO1<10><><EFBFBD>b<EFBFBD><62>`<60>ً&& <0B><>#&<04>x2<1E>e<EFBFBD>T˴<54>v<02>w<EFBFBD>[p<>!zk<7A><6B>y<EFBFBD>:<3A>\*<0E>W<EFBFBD>gb<67><62><EFBFBD>`Wa
<EFBFBD>Z<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>W!$<1B> <16><>¨9tvzQ<7A>˶<EFBFBD><CBB6>A<>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>se<73><65><EFBFBD><EFBFBD><EFBFBD>P<EFBFBD><17><6F>7_><3E><1B>j<EFBFBD><6A><EFBFBD><EFBFBD><EFBFBD>XQn<51>"7<><37>$ 3<>t?<3F><><EFBFBD><06><>Lo<>?<1B>K<EFBFBD>rd+s<><73><EFBFBD> <0C>a*-<2D>2<EFBFBD>.<2E>:<3A><>S<EFBFBD>6Tޤ0<DEA4><30><EFBFBD>7 %<25><>d<>,ǀ
<EFBFBD><EFBFBD>H<EFBFBD><12><><EFBFBD><EFBFBD>o~TIɸ<49><C9B8><EFBFBD><EFBFBD>:i<>&e<>ޤ<EFBFBD><DEA4>V]<5D><><EFBFBD>;l`<12>|l<><6C><EFBFBD>
2d<EFBFBD>

View File

@@ -0,0 +1,16 @@
<script lang="ts">
export default {
name: "TreeIcon",
};
</script>
<script setup lang="ts">
import LayIcon from "../component/icon/index";
const props = defineProps<{
color?: string;
size?: string;
}>();
</script>
<template>
<lay-icon :color="props.color" :size="props.size" type="layui-icon-tree" />
</template>