Files
jiang13-bbs/frontend/lib/widgetCode.ts
freefire ff2ab286fb feat: 书库导入导出/图片变体/书籍搜索/小组件运行时等
新增:
- 书库导入导出(library_import/library_export)及测试
- 图片变体生成(image_variants)与响应式图片(responsiveImage)
- 书籍搜索(bookSearch)+ BookSearch/LibrarySearchGrid 组件
- 小组件运行时(widgetRuntime)与静态检查(widgetLint)
- 上传缓存中间件(upload_cache)与字体 CSS 提取脚本

其它:
- 后端 handlers/services 全量调整
- 前端页面、组件、库函数与配置更新
2026-10-01 03:06:05 +08:00

53 lines
2.0 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 自定义侧栏工具代码处理:
// parseMixedWidgetCode / mergeWidgetCode:「混写一框」(内联 <style>/<script>)与分栏三字段互转;
// 三字段存储结构不变,拆分仅发生在管理端提交/切换视图时。
// 工具的样式隔离由渲染端 Shadow DOM 负责(见 widgetRuntime.ts),本模块不再做 CSS 作用域改写。
export interface WidgetCodeParts {
html: string;
css: string;
js: string;
}
const STYLE_RE = /<style\b[^>]*>([\s\S]*?)<\/style>/gi;
const SCRIPT_RE = /<script\b([^>]*)>([\s\S]*?)<\/script>/gi;
const TYPE_RE = /\btype\s*=\s*(?:"([^"]*)"|'([^']*)')/i;
const JS_TYPES = new Set(["", "text/javascript", "application/javascript", "module"]);
function isNonJsScript(attrs: string): boolean {
const m = attrs.match(TYPE_RE);
if (!m) return false;
return !JS_TYPES.has((m[1] ?? m[2] ?? "").toLowerCase());
}
/** 混写代码 → 三字段:<style>/<script> 段被摘出,剩余全部视为 HTML */
export function parseMixedWidgetCode(code: string): WidgetCodeParts {
const cssParts: string[] = [];
const jsParts: string[] = [];
let html = code.replace(STYLE_RE, (_m, body: string) => {
cssParts.push(body);
return "";
});
html = html.replace(SCRIPT_RE, (m: string, attrs: string, body: string) => {
// 外链脚本、模板/数据脚本(type 非 JS)原样留在 HTML 中
if (/\bsrc\s*=/i.test(attrs) || isNonJsScript(attrs)) return m;
jsParts.push(body);
return "";
});
return {
html: html.trim(),
css: cssParts.join("\n\n").trim(),
js: jsParts.join("\n\n").trim(),
};
}
/** 三字段 → 混写视图:HTML 在前,CSS/JS 分别以标准标签包裹 */
export function mergeWidgetCode(parts: WidgetCodeParts): string {
const out: string[] = [];
if (parts.html.trim()) out.push(parts.html.trim());
if (parts.css.trim()) out.push(`<style>\n${parts.css.trim()}\n</style>`);
if (parts.js.trim()) out.push(`<script>\n${parts.js.trim()}\n</script>`);
return out.join("\n\n");
}