dishui 0.0.84 → 0.0.91
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/components/Input/index.js +52 -62
- package/dist/components/Input/index.js.map +1 -1
- package/dist/components/LayoutSuite/index.d.ts +10 -0
- package/dist/components/LayoutSuite/index.js +27 -18
- package/dist/components/LayoutSuite/index.js.map +1 -1
- package/dist/components/Markdown/markdownComponents.js +1 -0
- package/dist/components/Markdown/markdownComponents.js.map +1 -1
- package/dist/components/Markdown/useMarkdownSource.js +46 -31
- package/dist/components/Markdown/useMarkdownSource.js.map +1 -1
- package/dist/components/Markdown/useMarkmapRenderer.js +44 -31
- package/dist/components/Markdown/useMarkmapRenderer.js.map +1 -1
- package/dist/components/Markdown/useMermaidRenderer.js +49 -31
- package/dist/components/Markdown/useMermaidRenderer.js.map +1 -1
- package/dist/components/ProtectedRoute/index.d.ts +2 -1
- package/dist/components/ProtectedRoute/index.js +16 -6
- package/dist/components/ProtectedRoute/index.js.map +1 -1
- package/dist/components/Select/index.d.ts +6 -0
- package/dist/components/Select/index.js +166 -136
- package/dist/components/Select/index.js.map +1 -1
- package/dist/components/Table/index.d.ts +23 -2
- package/dist/components/Table/index.js +153 -101
- package/dist/components/Table/index.js.map +1 -1
- package/dist/components/Tabs/index.d.ts +12 -1
- package/dist/components/Tabs/index.js +42 -17
- package/dist/components/Tabs/index.js.map +1 -1
- package/dist/components/pro/ArticleContextMenu/index.js +7 -7
- package/dist/components/pro/CodeEditor/editors/CodeEditor.js +200 -189
- package/dist/components/pro/CodeEditor/editors/CodeEditor.js.map +1 -1
- package/dist/components/pro/CodeEditor/types.d.ts +3 -0
- package/dist/components/pro/DataTable/DataTable.d.ts +1 -1
- package/dist/components/pro/DataTable/DataTable.js +124 -247
- package/dist/components/pro/DataTable/DataTable.js.map +1 -1
- package/dist/components/pro/DataTable/components/TableBody.d.ts +3 -1
- package/dist/components/pro/DataTable/components/TableBody.js +41 -41
- package/dist/components/pro/DataTable/components/TableBody.js.map +1 -1
- package/dist/components/pro/DataTable/components/TablePagination.d.ts +3 -9
- package/dist/components/pro/DataTable/components/TablePagination.js +29 -25
- package/dist/components/pro/DataTable/components/TablePagination.js.map +1 -1
- package/dist/components/pro/DataTable/components/TableToolbar.d.ts +2 -1
- package/dist/components/pro/DataTable/components/TableToolbar.js +25 -19
- package/dist/components/pro/DataTable/components/TableToolbar.js.map +1 -1
- package/dist/components/pro/DataTable/index.d.ts +1 -1
- package/dist/components/pro/DataTable/rowDetailExtension.js +1 -1
- package/dist/components/pro/DataTable/rowDetailExtension.js.map +1 -1
- package/dist/components/pro/DataTable/tanstack-table.d.ts +2 -2
- package/dist/components/pro/DataTable/tanstack-table.js +29 -21
- package/dist/components/pro/DataTable/tanstack-table.js.map +1 -1
- package/dist/components/pro/DataTable/treeDataUtils.d.ts +2 -0
- package/dist/components/pro/DataTable/treeDataUtils.js +18 -19
- package/dist/components/pro/DataTable/treeDataUtils.js.map +1 -1
- package/dist/components/pro/DataTable/types.d.ts +43 -0
- package/dist/components/pro/DataTable/useDataTableModel.d.ts +16 -0
- package/dist/components/pro/DataTable/useDataTableModel.js +148 -0
- package/dist/components/pro/DataTable/useDataTableModel.js.map +1 -0
- package/dist/components/pro/FileExplorer/Breadcrumb.js +12 -12
- package/dist/components/pro/Flow/nodes/DataNodeView.js +87 -82
- package/dist/components/pro/Flow/nodes/DataNodeView.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaContent.js +1 -1
- package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaOverlay.js +1 -1
- package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
- package/dist/components/pro/Flow/nodes/Model3DView.js +69 -63
- package/dist/components/pro/Flow/nodes/Model3DView.js.map +1 -1
- package/dist/components/pro/Flow/nodes/chartGeometryBudget.d.ts +14 -0
- package/dist/components/pro/Flow/nodes/chartGeometryBudget.js +76 -0
- package/dist/components/pro/Flow/nodes/chartGeometryBudget.js.map +1 -0
- package/dist/components/pro/Flow/nodes/demandRender.d.ts +11 -0
- package/dist/components/pro/Flow/nodes/demandRender.js +26 -0
- package/dist/components/pro/Flow/nodes/demandRender.js.map +1 -0
- package/dist/components/pro/RichTextEditor/SlashMenu.js +68 -58
- package/dist/components/pro/RichTextEditor/SlashMenu.js.map +1 -1
- package/dist/contexts/AppContext.d.ts +1 -0
- package/dist/contexts/AppContext.js +144 -145
- package/dist/contexts/AppContext.js.map +1 -1
- package/dist/contexts/authentication.d.ts +7 -0
- package/dist/contexts/authentication.js +22 -0
- package/dist/contexts/authentication.js.map +1 -0
- package/dist/data-table.js.map +1 -1
- package/dist/dishui.css +1 -1
- package/dist/hooks/useControllableState.d.ts +6 -14
- package/dist/hooks/useControllableState.js +21 -15
- package/dist/hooks/useControllableState.js.map +1 -1
- package/dist/hooks/useTableColumns.d.ts +3 -3
- package/dist/hooks/useTableColumns.js +2 -2
- package/dist/hooks/useTableColumns.js.map +1 -1
- package/dist/hooks/useTableData.d.ts +11 -4
- package/dist/hooks/useTableData.js +44 -26
- package/dist/hooks/useTableData.js.map +1 -1
- package/dist/index-nostyled.d.ts +2 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +97 -97
- package/dist/lite.d.ts +2 -0
- package/dist/lite.js +22 -21
- package/dist/utils/i18n.js +1 -1
- package/dist/utils/i18n.js.map +1 -1
- package/dist/utils/routerBuilder.d.ts +7 -5
- package/dist/utils/routerBuilder.js +11 -15
- package/dist/utils/routerBuilder.js.map +1 -1
- package/dist/utils/safeStorage.d.ts +8 -0
- package/dist/utils/safeStorage.js +45 -0
- package/dist/utils/safeStorage.js.map +1 -0
- package/package.json +22 -5
|
@@ -1,116 +1,122 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
1
|
+
import { createDemandRender as e } from "./demandRender.js";
|
|
2
|
+
import { useEffect as t, useRef as n, useState as r } from "react";
|
|
3
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
4
|
+
import * as o from "three";
|
|
5
|
+
import { OrbitControls as s } from "three/addons/controls/OrbitControls.js";
|
|
6
|
+
import { ThreeMFLoader as c } from "three/addons/loaders/3MFLoader.js";
|
|
7
|
+
import { OBJLoader as l } from "three/addons/loaders/OBJLoader.js";
|
|
8
|
+
import { STLLoader as u } from "three/addons/loaders/STLLoader.js";
|
|
8
9
|
//#region src/components/pro/Flow/nodes/Model3DView.tsx
|
|
9
|
-
function
|
|
10
|
+
function d(e) {
|
|
10
11
|
let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set();
|
|
11
12
|
e.traverse((e) => {
|
|
12
|
-
if (!(e instanceof
|
|
13
|
+
if (!(e instanceof o.Mesh)) return;
|
|
13
14
|
e.geometry?.dispose();
|
|
14
15
|
let r = Array.isArray(e.material) ? e.material : [e.material];
|
|
15
16
|
for (let e of r) if (e && !t.has(e)) {
|
|
16
17
|
t.add(e);
|
|
17
|
-
for (let t of Object.values(e)) t instanceof
|
|
18
|
+
for (let t of Object.values(e)) t instanceof o.Texture && n.add(t);
|
|
18
19
|
}
|
|
19
20
|
});
|
|
20
21
|
for (let e of n) e.dispose();
|
|
21
22
|
for (let e of t) e.dispose();
|
|
22
23
|
}
|
|
23
|
-
function
|
|
24
|
+
function f(e, t) {
|
|
24
25
|
if (e === "stl") {
|
|
25
|
-
let e = new
|
|
26
|
-
return e.getAttribute("normal") || e.computeVertexNormals(), new
|
|
26
|
+
let e = new u().parse(t);
|
|
27
|
+
return e.getAttribute("normal") || e.computeVertexNormals(), new o.Mesh(e, new o.MeshStandardMaterial({
|
|
27
28
|
color: 12108492,
|
|
28
29
|
metalness: .05,
|
|
29
30
|
roughness: .72,
|
|
30
|
-
side:
|
|
31
|
+
side: o.DoubleSide
|
|
31
32
|
}));
|
|
32
33
|
}
|
|
33
|
-
return e === "obj" ? new
|
|
34
|
+
return e === "obj" ? new l().parse(new TextDecoder().decode(t)) : new c().parse(t);
|
|
34
35
|
}
|
|
35
|
-
function
|
|
36
|
-
let
|
|
37
|
-
return
|
|
38
|
-
|
|
39
|
-
}, [
|
|
40
|
-
let
|
|
41
|
-
if (!
|
|
42
|
-
let
|
|
36
|
+
function p({ content: c, format: l, interactive: u }) {
|
|
37
|
+
let p = n(null), m = n(null), h = n(u), [g, _] = r(null), [v, y] = r(!1);
|
|
38
|
+
return t(() => {
|
|
39
|
+
h.current = u, m.current && (m.current.enabled = u);
|
|
40
|
+
}, [u]), t(() => {
|
|
41
|
+
let t = p.current, n = c.trim();
|
|
42
|
+
if (!t || !n) return;
|
|
43
|
+
let r = !1, i = null, a = new AbortController(), u = new o.Scene(), g = new o.PerspectiveCamera(45, 1, .01, 1e4), v = new o.WebGLRenderer({
|
|
43
44
|
antialias: !0,
|
|
44
45
|
alpha: !0
|
|
45
46
|
});
|
|
46
|
-
|
|
47
|
-
let b = new
|
|
48
|
-
b.position.set(3, 5, 4),
|
|
49
|
-
let x = new
|
|
50
|
-
x.enableDamping = !0, x.enabled =
|
|
51
|
-
let S = (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
};
|
|
55
|
-
S
|
|
56
|
-
let C =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
47
|
+
v.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2)), v.outputColorSpace = o.SRGBColorSpace, v.setClearColor(0, 0), t.appendChild(v.domElement), u.add(new o.HemisphereLight(16777215, 4477030, 2));
|
|
48
|
+
let b = new o.DirectionalLight(16777215, 2.4);
|
|
49
|
+
b.position.set(3, 5, 4), u.add(b);
|
|
50
|
+
let x = new s(g, v.domElement);
|
|
51
|
+
x.enableDamping = !0, x.enabled = h.current, m.current = x;
|
|
52
|
+
let S = e({
|
|
53
|
+
update: () => x.update(),
|
|
54
|
+
render: () => v.render(u, g)
|
|
55
|
+
});
|
|
56
|
+
x.addEventListener("change", S.invalidate);
|
|
57
|
+
let C = typeof IntersectionObserver > "u", w = () => S.setActive(C && !document.hidden), T = typeof IntersectionObserver > "u" ? null : new IntersectionObserver((e) => {
|
|
58
|
+
C = e.some((e) => e.isIntersecting && e.intersectionRect.width > 0 && e.intersectionRect.height > 0), w();
|
|
59
|
+
});
|
|
60
|
+
T?.observe(t), document.addEventListener("visibilitychange", w), w();
|
|
61
|
+
let E = () => {
|
|
62
|
+
let e = Math.max(1, t.clientWidth), n = Math.max(1, t.clientHeight);
|
|
63
|
+
v.setSize(e, n, !1), g.aspect = e / n, g.updateProjectionMatrix(), S.invalidate();
|
|
60
64
|
};
|
|
61
|
-
|
|
65
|
+
E();
|
|
66
|
+
let D = new ResizeObserver(E);
|
|
67
|
+
return D.observe(t), y(!0), _(null), fetch(n, { signal: a.signal }).then((e) => {
|
|
62
68
|
if (!e.ok) throw Error(`模型加载失败:HTTP ${e.status}`);
|
|
63
69
|
return e.arrayBuffer();
|
|
64
70
|
}).then((e) => {
|
|
65
71
|
if (e.byteLength > 52428800) throw Error("模型超过 50 MiB,无法加载");
|
|
66
|
-
let t =
|
|
67
|
-
if (
|
|
68
|
-
|
|
72
|
+
let t = f(l, e);
|
|
73
|
+
if (r) {
|
|
74
|
+
d(t);
|
|
69
75
|
return;
|
|
70
76
|
}
|
|
71
77
|
i = t, t.updateMatrixWorld(!0);
|
|
72
|
-
let
|
|
73
|
-
if (
|
|
74
|
-
let
|
|
75
|
-
t.position.sub(
|
|
76
|
-
let s = new
|
|
78
|
+
let n = new o.Box3().setFromObject(t);
|
|
79
|
+
if (n.isEmpty()) throw Error("模型不包含可显示的几何体");
|
|
80
|
+
let a = n.getCenter(new o.Vector3());
|
|
81
|
+
t.position.sub(a), t.updateMatrixWorld(!0);
|
|
82
|
+
let s = new o.Box3().setFromObject(t).getBoundingSphere(new o.Sphere());
|
|
77
83
|
if (!Number.isFinite(s.radius) || s.radius <= 0) throw Error("模型尺寸无效");
|
|
78
|
-
|
|
79
|
-
let
|
|
80
|
-
|
|
84
|
+
u.add(t);
|
|
85
|
+
let c = o.MathUtils.degToRad(g.fov / 2), p = Math.atan(Math.tan(c) * g.aspect), m = s.radius / Math.sin(Math.min(p, c)) * 1.15;
|
|
86
|
+
g.position.copy(new o.Vector3(1, .75, 1).normalize().multiplyScalar(m)), g.near = Math.max(s.radius / 1e3, .001), g.far = Math.max(m + s.radius * 10, s.radius * 1e3), g.updateProjectionMatrix(), x.target.set(0, 0, 0), x.minDistance = s.radius * .05, x.maxDistance = s.radius * 100, S.invalidate();
|
|
81
87
|
}).catch((e) => {
|
|
82
|
-
!
|
|
88
|
+
!r && e?.name !== "AbortError" && _(e?.message ?? "模型加载失败");
|
|
83
89
|
}).finally(() => {
|
|
84
|
-
|
|
90
|
+
r || y(!1);
|
|
85
91
|
}), () => {
|
|
86
|
-
|
|
92
|
+
r = !0, a.abort(), S.dispose(), D.disconnect(), T?.disconnect(), document.removeEventListener("visibilitychange", w), x.removeEventListener("change", S.invalidate), x.dispose(), m.current = null, i && d(i), u.clear(), v.renderLists.dispose(), v.dispose(), v.forceContextLoss(), v.domElement.remove();
|
|
87
93
|
};
|
|
88
|
-
}, [
|
|
89
|
-
ref:
|
|
94
|
+
}, [c, l]), c.trim() ? /* @__PURE__ */ a("div", {
|
|
95
|
+
ref: p,
|
|
90
96
|
className: "flow-media-model3d",
|
|
91
97
|
style: {
|
|
92
|
-
pointerEvents:
|
|
93
|
-
touchAction:
|
|
98
|
+
pointerEvents: u ? "auto" : "none",
|
|
99
|
+
touchAction: u ? "none" : "auto"
|
|
94
100
|
},
|
|
95
101
|
onPointerDown: (e) => {
|
|
96
|
-
|
|
102
|
+
u && e.stopPropagation();
|
|
97
103
|
},
|
|
98
104
|
onWheel: (e) => {
|
|
99
|
-
|
|
105
|
+
u && e.stopPropagation();
|
|
100
106
|
},
|
|
101
|
-
children: [
|
|
107
|
+
children: [v && /* @__PURE__ */ i("div", {
|
|
102
108
|
className: "flow-media-loading flow-media-model3d-status",
|
|
103
109
|
children: "加载模型…"
|
|
104
|
-
}),
|
|
110
|
+
}), g && /* @__PURE__ */ i("div", {
|
|
105
111
|
className: "flow-media-error flow-media-model3d-status",
|
|
106
|
-
children:
|
|
112
|
+
children: g
|
|
107
113
|
})]
|
|
108
|
-
}) : /* @__PURE__ */
|
|
114
|
+
}) : /* @__PURE__ */ i("div", {
|
|
109
115
|
className: "flow-media-image-empty",
|
|
110
116
|
children: "输入 STL、OBJ 或 3MF 模型链接"
|
|
111
117
|
});
|
|
112
118
|
}
|
|
113
119
|
//#endregion
|
|
114
|
-
export {
|
|
120
|
+
export { p as Model3DView };
|
|
115
121
|
|
|
116
122
|
//# sourceMappingURL=Model3DView.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Model3DView.js","names":[],"sources":["../../../../../src/components/pro/Flow/nodes/Model3DView.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport * as THREE from 'three';\nimport { OrbitControls } from 'three/addons/controls/OrbitControls.js';\nimport { ThreeMFLoader } from 'three/addons/loaders/3MFLoader.js';\nimport { OBJLoader } from 'three/addons/loaders/OBJLoader.js';\nimport { STLLoader } from 'three/addons/loaders/STLLoader.js';\nimport type { FlowModelFormat } from '../types';\n\nfunction disposeObject(root: any) {\n const materials = new Set<any>();\n const textures = new Set<any>();\n root.traverse((object: any) => {\n if (!(object instanceof THREE.Mesh)) return;\n object.geometry?.dispose();\n const list = Array.isArray(object.material) ? object.material : [object.material];\n for (const material of list) {\n if (!material || materials.has(material)) continue;\n materials.add(material);\n for (const value of Object.values(material)) {\n if (value instanceof THREE.Texture) textures.add(value);\n }\n }\n });\n for (const texture of textures) texture.dispose();\n for (const material of materials) material.dispose();\n}\n\nfunction parseModel(format: FlowModelFormat, data: ArrayBuffer): any {\n if (format === 'stl') {\n const geometry = new STLLoader().parse(data);\n if (!geometry.getAttribute('normal')) geometry.computeVertexNormals();\n return new THREE.Mesh(\n geometry,\n new THREE.MeshStandardMaterial({\n color: 0xb8c2cc,\n metalness: 0.05,\n roughness: 0.72,\n side: THREE.DoubleSide,\n }),\n );\n }\n if (format === 'obj') {\n return new OBJLoader().parse(new TextDecoder().decode(data));\n }\n return new ThreeMFLoader().parse(data);\n}\n\nexport function Model3DView({\n content,\n format,\n interactive,\n}: {\n content: string;\n format: FlowModelFormat;\n interactive: boolean;\n}) {\n const hostRef = useRef<HTMLDivElement>(null);\n const controlsRef = useRef<any>(null);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n\n useEffect(() => {\n if (controlsRef.current) controlsRef.current.enabled = interactive;\n }, [interactive]);\n\n useEffect(() => {\n const host = hostRef.current;\n const source = content.trim();\n if (!host || !source) return;\n\n let cancelled = false;\n let frame = 0;\n let model: any = null;\n const abort = new AbortController();\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(45, 1, 0.01, 10000);\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));\n renderer.outputColorSpace = THREE.SRGBColorSpace;\n renderer.setClearColor(0x000000, 0);\n host.appendChild(renderer.domElement);\n\n scene.add(new THREE.HemisphereLight(0xffffff, 0x445066, 2));\n const directional = new THREE.DirectionalLight(0xffffff, 2.4);\n directional.position.set(3, 5, 4);\n scene.add(directional);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.enabled = interactive;\n controlsRef.current = controls;\n\n const resize = () => {\n const width = Math.max(1, host.clientWidth);\n const height = Math.max(1, host.clientHeight);\n renderer.setSize(width, height, false);\n camera.aspect = width / height;\n camera.updateProjectionMatrix();\n };\n resize();\n const observer = new ResizeObserver(resize);\n observer.observe(host);\n\n const animate = () => {\n controls.update();\n renderer.render(scene, camera);\n frame = requestAnimationFrame(animate);\n };\n animate();\n\n setLoading(true);\n setError(null);\n fetch(source, { signal: abort.signal })\n .then(response => {\n if (!response.ok) throw new Error(`模型加载失败:HTTP ${response.status}`);\n return response.arrayBuffer();\n })\n .then(data => {\n if (data.byteLength > 50 * 1024 * 1024) throw new Error('模型超过 50 MiB,无法加载');\n const root = parseModel(format, data);\n if (cancelled) {\n disposeObject(root);\n return;\n }\n model = root;\n root.updateMatrixWorld(true);\n const box = new THREE.Box3().setFromObject(root);\n if (box.isEmpty()) throw new Error('模型不包含可显示的几何体');\n const center = box.getCenter(new THREE.Vector3());\n root.position.sub(center);\n root.updateMatrixWorld(true);\n const sphere = new THREE.Box3().setFromObject(root).getBoundingSphere(new THREE.Sphere());\n if (!Number.isFinite(sphere.radius) || sphere.radius <= 0) throw new Error('模型尺寸无效');\n scene.add(root);\n\n const halfFovY = THREE.MathUtils.degToRad(camera.fov / 2);\n const halfFovX = Math.atan(Math.tan(halfFovY) * camera.aspect);\n const distance = (sphere.radius / Math.sin(Math.min(halfFovX, halfFovY))) * 1.15;\n camera.position.copy(new THREE.Vector3(1, 0.75, 1).normalize().multiplyScalar(distance));\n camera.near = Math.max(sphere.radius / 1000, 0.001);\n camera.far = Math.max(distance + sphere.radius * 10, sphere.radius * 1000);\n camera.updateProjectionMatrix();\n controls.target.set(0, 0, 0);\n controls.minDistance = sphere.radius * 0.05;\n controls.maxDistance = sphere.radius * 100;\n controls.update();\n })\n .catch(nextError => {\n if (!cancelled && nextError?.name !== 'AbortError') setError(nextError?.message ?? '模型加载失败');\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n\n return () => {\n cancelled = true;\n abort.abort();\n cancelAnimationFrame(frame);\n observer.disconnect();\n controls.dispose();\n controlsRef.current = null;\n if (model) disposeObject(model);\n scene.clear();\n renderer.renderLists.dispose();\n renderer.dispose();\n renderer.forceContextLoss();\n renderer.domElement.remove();\n };\n }, [content, format]);\n\n if (!content.trim()) {\n return <div className=\"flow-media-image-empty\">输入 STL、OBJ 或 3MF 模型链接</div>;\n }\n\n return (\n <div\n ref={hostRef}\n className=\"flow-media-model3d\"\n style={{ pointerEvents: interactive ? 'auto' : 'none', touchAction: interactive ? 'none' : 'auto' }}\n onPointerDown={event => { if (interactive) event.stopPropagation(); }}\n onWheel={event => { if (interactive) event.stopPropagation(); }}\n >\n {loading && <div className=\"flow-media-loading flow-media-model3d-status\">加载模型…</div>}\n {error && <div className=\"flow-media-error flow-media-model3d-status\">{error}</div>}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Model3DView.js","names":[],"sources":["../../../../../src/components/pro/Flow/nodes/Model3DView.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport * as THREE from 'three';\nimport { OrbitControls } from 'three/addons/controls/OrbitControls.js';\nimport { ThreeMFLoader } from 'three/addons/loaders/3MFLoader.js';\nimport { OBJLoader } from 'three/addons/loaders/OBJLoader.js';\nimport { STLLoader } from 'three/addons/loaders/STLLoader.js';\nimport type { FlowModelFormat } from '../types';\nimport { createDemandRender } from './demandRender';\n\nfunction disposeObject(root: any) {\n const materials = new Set<any>();\n const textures = new Set<any>();\n root.traverse((object: any) => {\n if (!(object instanceof THREE.Mesh)) return;\n object.geometry?.dispose();\n const list = Array.isArray(object.material) ? object.material : [object.material];\n for (const material of list) {\n if (!material || materials.has(material)) continue;\n materials.add(material);\n for (const value of Object.values(material)) {\n if (value instanceof THREE.Texture) textures.add(value);\n }\n }\n });\n for (const texture of textures) texture.dispose();\n for (const material of materials) material.dispose();\n}\n\nfunction parseModel(format: FlowModelFormat, data: ArrayBuffer): any {\n if (format === 'stl') {\n const geometry = new STLLoader().parse(data);\n if (!geometry.getAttribute('normal')) geometry.computeVertexNormals();\n return new THREE.Mesh(\n geometry,\n new THREE.MeshStandardMaterial({\n color: 0xb8c2cc,\n metalness: 0.05,\n roughness: 0.72,\n side: THREE.DoubleSide,\n }),\n );\n }\n if (format === 'obj') {\n return new OBJLoader().parse(new TextDecoder().decode(data));\n }\n return new ThreeMFLoader().parse(data);\n}\n\nexport function Model3DView({\n content,\n format,\n interactive,\n}: {\n content: string;\n format: FlowModelFormat;\n interactive: boolean;\n}) {\n const hostRef = useRef<HTMLDivElement>(null);\n const controlsRef = useRef<OrbitControls | null>(null);\n const interactiveRef = useRef(interactive);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n\n useEffect(() => {\n interactiveRef.current = interactive;\n if (controlsRef.current) controlsRef.current.enabled = interactive;\n }, [interactive]);\n\n useEffect(() => {\n const host = hostRef.current;\n const source = content.trim();\n if (!host || !source) return;\n\n let cancelled = false;\n let model: any = null;\n const abort = new AbortController();\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(45, 1, 0.01, 10000);\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));\n renderer.outputColorSpace = THREE.SRGBColorSpace;\n renderer.setClearColor(0x000000, 0);\n host.appendChild(renderer.domElement);\n\n scene.add(new THREE.HemisphereLight(0xffffff, 0x445066, 2));\n const directional = new THREE.DirectionalLight(0xffffff, 2.4);\n directional.position.set(3, 5, 4);\n scene.add(directional);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.enabled = interactiveRef.current;\n controlsRef.current = controls;\n\n const drawing = createDemandRender({\n update: () => controls.update(),\n render: () => renderer.render(scene, camera),\n });\n controls.addEventListener('change', drawing.invalidate);\n // Observe the actual DOM box, including overlay transforms and clipping.\n // Pausing keeps the loaded model, camera and WebGL context intact.\n let intersecting = typeof IntersectionObserver === 'undefined';\n const updateVisibility = () => drawing.setActive(intersecting && !document.hidden);\n const visibilityObserver = typeof IntersectionObserver === 'undefined' ? null : new IntersectionObserver(entries => {\n intersecting = entries.some(entry => entry.isIntersecting && entry.intersectionRect.width > 0 && entry.intersectionRect.height > 0);\n updateVisibility();\n });\n visibilityObserver?.observe(host);\n document.addEventListener('visibilitychange', updateVisibility);\n updateVisibility();\n\n const resize = () => {\n const width = Math.max(1, host.clientWidth);\n const height = Math.max(1, host.clientHeight);\n renderer.setSize(width, height, false);\n camera.aspect = width / height;\n camera.updateProjectionMatrix();\n drawing.invalidate();\n };\n resize();\n const observer = new ResizeObserver(resize);\n observer.observe(host);\n\n setLoading(true);\n setError(null);\n fetch(source, { signal: abort.signal })\n .then(response => {\n if (!response.ok) throw new Error(`模型加载失败:HTTP ${response.status}`);\n return response.arrayBuffer();\n })\n .then(data => {\n if (data.byteLength > 50 * 1024 * 1024) throw new Error('模型超过 50 MiB,无法加载');\n const root = parseModel(format, data);\n if (cancelled) {\n disposeObject(root);\n return;\n }\n model = root;\n root.updateMatrixWorld(true);\n const box = new THREE.Box3().setFromObject(root);\n if (box.isEmpty()) throw new Error('模型不包含可显示的几何体');\n const center = box.getCenter(new THREE.Vector3());\n root.position.sub(center);\n root.updateMatrixWorld(true);\n const sphere = new THREE.Box3().setFromObject(root).getBoundingSphere(new THREE.Sphere());\n if (!Number.isFinite(sphere.radius) || sphere.radius <= 0) throw new Error('模型尺寸无效');\n scene.add(root);\n\n const halfFovY = THREE.MathUtils.degToRad(camera.fov / 2);\n const halfFovX = Math.atan(Math.tan(halfFovY) * camera.aspect);\n const distance = (sphere.radius / Math.sin(Math.min(halfFovX, halfFovY))) * 1.15;\n camera.position.copy(new THREE.Vector3(1, 0.75, 1).normalize().multiplyScalar(distance));\n camera.near = Math.max(sphere.radius / 1000, 0.001);\n camera.far = Math.max(distance + sphere.radius * 10, sphere.radius * 1000);\n camera.updateProjectionMatrix();\n controls.target.set(0, 0, 0);\n controls.minDistance = sphere.radius * 0.05;\n controls.maxDistance = sphere.radius * 100;\n drawing.invalidate();\n })\n .catch(nextError => {\n if (!cancelled && nextError?.name !== 'AbortError') setError(nextError?.message ?? '模型加载失败');\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n\n return () => {\n cancelled = true;\n abort.abort();\n drawing.dispose();\n observer.disconnect();\n visibilityObserver?.disconnect();\n document.removeEventListener('visibilitychange', updateVisibility);\n controls.removeEventListener('change', drawing.invalidate);\n controls.dispose();\n controlsRef.current = null;\n if (model) disposeObject(model);\n scene.clear();\n renderer.renderLists.dispose();\n renderer.dispose();\n renderer.forceContextLoss();\n renderer.domElement.remove();\n };\n }, [content, format]);\n\n if (!content.trim()) {\n return <div className=\"flow-media-image-empty\">输入 STL、OBJ 或 3MF 模型链接</div>;\n }\n\n return (\n <div\n ref={hostRef}\n className=\"flow-media-model3d\"\n style={{ pointerEvents: interactive ? 'auto' : 'none', touchAction: interactive ? 'none' : 'auto' }}\n onPointerDown={event => { if (interactive) event.stopPropagation(); }}\n onWheel={event => { if (interactive) event.stopPropagation(); }}\n >\n {loading && <div className=\"flow-media-loading flow-media-model3d-status\">加载模型…</div>}\n {error && <div className=\"flow-media-error flow-media-model3d-status\">{error}</div>}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ChartMark, SceneNode } from '@tanstack/charts';
|
|
2
|
+
type Position = readonly [number, number];
|
|
3
|
+
/** Keep sparse charts' dots, but not overlapping dots in dense/multi-series lines. */
|
|
4
|
+
export declare function showLinePoints(rowCount: number, seriesCount: number, width: number): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* First/min/max/last per two CSS plot pixels (at most ~2 vertices/pixel).
|
|
7
|
+
* Keep source order and extrema. Repeated/non-monotonic category positions are
|
|
8
|
+
* deliberately left alone: bucketing them can change backtracking geometry.
|
|
9
|
+
*/
|
|
10
|
+
export declare function budgetPolyline(points: readonly Position[]): readonly Position[];
|
|
11
|
+
export declare function budgetChartNode(node: SceneNode): SceneNode;
|
|
12
|
+
/** Budget only display geometry, after full-data domains and tooltip points exist. */
|
|
13
|
+
export declare function withChartGeometryBudget<T extends ChartMark<any, any, any, any, any, any, any>>(mark: T): T;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
//#region src/components/pro/Flow/nodes/chartGeometryBudget.ts
|
|
2
|
+
function e(e, t, n) {
|
|
3
|
+
return e * t <= Math.min(200, Math.floor(Math.max(0, n) / 6));
|
|
4
|
+
}
|
|
5
|
+
function t(e) {
|
|
6
|
+
if (e.length < 3) return e;
|
|
7
|
+
let t = -Infinity;
|
|
8
|
+
for (let [n, r] of e) {
|
|
9
|
+
if (!Number.isFinite(n) || !Number.isFinite(r) || n <= t) return e;
|
|
10
|
+
t = n;
|
|
11
|
+
}
|
|
12
|
+
let n = [];
|
|
13
|
+
for (let t = 0; t < e.length;) {
|
|
14
|
+
let r = Math.floor(e[t][0] / 2), i = t + 1, a = t, o = t;
|
|
15
|
+
for (; i < e.length && Math.floor(e[i][0] / 2) === r;) e[i][1] < e[a][1] && (a = i), e[i][1] > e[o][1] && (o = i), i++;
|
|
16
|
+
let s = [
|
|
17
|
+
t,
|
|
18
|
+
Math.min(a, o),
|
|
19
|
+
Math.max(a, o),
|
|
20
|
+
i - 1
|
|
21
|
+
];
|
|
22
|
+
for (let t = 0; t < s.length; t++) (t === 0 || s[t] !== s[t - 1]) && n.push(e[s[t]]);
|
|
23
|
+
t = i;
|
|
24
|
+
}
|
|
25
|
+
return n.length < e.length ? n : e;
|
|
26
|
+
}
|
|
27
|
+
function n(e) {
|
|
28
|
+
if (e.kind === "group") return {
|
|
29
|
+
...e,
|
|
30
|
+
children: e.children.map(n)
|
|
31
|
+
};
|
|
32
|
+
if (e.kind === "polyline" && !e.path) {
|
|
33
|
+
let n = t(e.points);
|
|
34
|
+
return n === e.points ? e : {
|
|
35
|
+
...e,
|
|
36
|
+
points: n
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (e.kind === "area" && !e.path && !e.polygons) {
|
|
40
|
+
let n = e.interaction?.points?.length;
|
|
41
|
+
if (n && e.points.length === n * 2) {
|
|
42
|
+
let r = e.points.slice(0, n), i = Array.from({ length: n }, (t, n) => e.points[e.points.length - 1 - n]), a = t(r), o = t(i);
|
|
43
|
+
if (a !== r || o !== i) {
|
|
44
|
+
let t = [...a];
|
|
45
|
+
for (let e = o.length - 1; e >= 0; e--) t.push(o[e]);
|
|
46
|
+
return {
|
|
47
|
+
...e,
|
|
48
|
+
points: t
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return e;
|
|
54
|
+
}
|
|
55
|
+
function r(e) {
|
|
56
|
+
return {
|
|
57
|
+
...e,
|
|
58
|
+
initialize(t) {
|
|
59
|
+
let r = e.initialize(t);
|
|
60
|
+
return {
|
|
61
|
+
...r,
|
|
62
|
+
render(e) {
|
|
63
|
+
let t = r.render(e);
|
|
64
|
+
return {
|
|
65
|
+
...t,
|
|
66
|
+
nodes: t.nodes.map(n)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
export { n as budgetChartNode, t as budgetPolyline, e as showLinePoints, r as withChartGeometryBudget };
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=chartGeometryBudget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chartGeometryBudget.js","names":[],"sources":["../../../../../src/components/pro/Flow/nodes/chartGeometryBudget.ts"],"sourcesContent":["import type { ChartMark, SceneNode } from '@tanstack/charts';\n\ntype Position = readonly [number, number];\n\n/** Keep sparse charts' dots, but not overlapping dots in dense/multi-series lines. */\nexport function showLinePoints(rowCount: number, seriesCount: number, width: number) {\n return rowCount * seriesCount <= Math.min(200, Math.floor(Math.max(0, width) / 6));\n}\n\n/**\n * First/min/max/last per two CSS plot pixels (at most ~2 vertices/pixel).\n * Keep source order and extrema. Repeated/non-monotonic category positions are\n * deliberately left alone: bucketing them can change backtracking geometry.\n */\nexport function budgetPolyline(points: readonly Position[]): readonly Position[] {\n if (points.length < 3) return points;\n let previousX = -Infinity;\n for (const [x, y] of points) {\n if (!Number.isFinite(x) || !Number.isFinite(y) || x <= previousX) return points;\n previousX = x;\n }\n const result: Position[] = [];\n for (let start = 0; start < points.length;) {\n const bucket = Math.floor(points[start][0] / 2);\n let end = start + 1, min = start, max = start;\n while (end < points.length && Math.floor(points[end][0] / 2) === bucket) {\n if (points[end][1] < points[min][1]) min = end;\n if (points[end][1] > points[max][1]) max = end;\n end++;\n }\n const indices = [start, Math.min(min, max), Math.max(min, max), end - 1];\n for (let i = 0; i < indices.length; i++) {\n if (i === 0 || indices[i] !== indices[i - 1]) result.push(points[indices[i]]);\n }\n start = end;\n }\n return result.length < points.length ? result : points;\n}\n\nexport function budgetChartNode(node: SceneNode): SceneNode {\n if (node.kind === 'group') return { ...node, children: node.children.map(budgetChartNode) };\n // Never rewrite precomputed curves or arbitrary polygons. Interaction points\n // remain the full-resolution source data, separate from the painted vertices.\n if (node.kind === 'polyline' && !node.path) {\n const points = budgetPolyline(node.points);\n return points === node.points ? node : { ...node, points };\n }\n if (node.kind === 'area' && !node.path && !node.polygons) {\n const count = node.interaction?.points?.length;\n // areaY emits the upper edge then the reversed lower edge for each gap-\n // separated segment. Check this shape before applying the budget.\n if (count && node.points.length === count * 2) {\n const top = node.points.slice(0, count);\n const bottom = Array.from({ length: count }, (_, i) => node.points[node.points.length - 1 - i]);\n const upper = budgetPolyline(top), lower = budgetPolyline(bottom);\n if (upper !== top || lower !== bottom) {\n const points = [...upper];\n for (let i = lower.length - 1; i >= 0; i--) points.push(lower[i]);\n return { ...node, points };\n }\n }\n }\n return node;\n}\n\n/** Budget only display geometry, after full-data domains and tooltip points exist. */\nexport function withChartGeometryBudget<T extends ChartMark<any, any, any, any, any, any, any>>(mark: T): T {\n return {\n ...mark,\n initialize(context) {\n const initialized = mark.initialize(context);\n return {\n ...initialized,\n render(renderContext) {\n const scene = initialized.render(renderContext);\n return { ...scene, nodes: scene.nodes.map(budgetChartNode) };\n },\n };\n },\n };\n}\n"],"mappings":";AAKA,SAAgB,EAAe,GAAkB,GAAqB,GAAe;CACnF,OAAO,IAAW,KAAe,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,IAAI,GAAG,CAAK,IAAI,CAAC,CAAC;AACnF;AAOA,SAAgB,EAAe,GAAkD;CAC/E,IAAI,EAAO,SAAS,GAAG,OAAO;CAC9B,IAAI,IAAY;CAChB,KAAK,IAAM,CAAC,GAAG,MAAM,GAAQ;EAC3B,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,KAAK,KAAK,GAAW,OAAO;EACzE,IAAY;CACd;CACA,IAAM,IAAqB,CAAC;CAC5B,KAAK,IAAI,IAAQ,GAAG,IAAQ,EAAO,SAAS;EAC1C,IAAM,IAAS,KAAK,MAAM,EAAO,EAAM,CAAC,KAAK,CAAC,GAC1C,IAAM,IAAQ,GAAG,IAAM,GAAO,IAAM;EACxC,OAAO,IAAM,EAAO,UAAU,KAAK,MAAM,EAAO,EAAI,CAAC,KAAK,CAAC,MAAM,IAG/D,AAFI,EAAO,EAAI,CAAC,KAAK,EAAO,EAAI,CAAC,OAAI,IAAM,IACvC,EAAO,EAAI,CAAC,KAAK,EAAO,EAAI,CAAC,OAAI,IAAM,IAC3C;EAEF,IAAM,IAAU;GAAC;GAAO,KAAK,IAAI,GAAK,CAAG;GAAG,KAAK,IAAI,GAAK,CAAG;GAAG,IAAM;EAAC;EACvE,KAAK,IAAI,IAAI,GAAG,IAAI,EAAQ,QAAQ,KAClC,CAAI,MAAM,KAAK,EAAQ,OAAO,EAAQ,IAAI,OAAI,EAAO,KAAK,EAAO,EAAQ,GAAG;EAE9E,IAAQ;CACV;CACA,OAAO,EAAO,SAAS,EAAO,SAAS,IAAS;AAClD;AAEA,SAAgB,EAAgB,GAA4B;CAC1D,IAAI,EAAK,SAAS,SAAS,OAAO;EAAE,GAAG;EAAM,UAAU,EAAK,SAAS,IAAI,CAAe;CAAE;CAG1F,IAAI,EAAK,SAAS,cAAc,CAAC,EAAK,MAAM;EAC1C,IAAM,IAAS,EAAe,EAAK,MAAM;EACzC,OAAO,MAAW,EAAK,SAAS,IAAO;GAAE,GAAG;GAAM;EAAO;CAC3D;CACA,IAAI,EAAK,SAAS,UAAU,CAAC,EAAK,QAAQ,CAAC,EAAK,UAAU;EACxD,IAAM,IAAQ,EAAK,aAAa,QAAQ;EAGxC,IAAI,KAAS,EAAK,OAAO,WAAW,IAAQ,GAAG;GAC7C,IAAM,IAAM,EAAK,OAAO,MAAM,GAAG,CAAK,GAChC,IAAS,MAAM,KAAK,EAAE,QAAQ,EAAM,IAAI,GAAG,MAAM,EAAK,OAAO,EAAK,OAAO,SAAS,IAAI,EAAE,GACxF,IAAQ,EAAe,CAAG,GAAG,IAAQ,EAAe,CAAM;GAChE,IAAI,MAAU,KAAO,MAAU,GAAQ;IACrC,IAAM,IAAS,CAAC,GAAG,CAAK;IACxB,KAAK,IAAI,IAAI,EAAM,SAAS,GAAG,KAAK,GAAG,KAAK,EAAO,KAAK,EAAM,EAAE;IAChE,OAAO;KAAE,GAAG;KAAM;IAAO;GAC3B;EACF;CACF;CACA,OAAO;AACT;AAGA,SAAgB,EAAgF,GAAY;CAC1G,OAAO;EACL,GAAG;EACH,WAAW,GAAS;GAClB,IAAM,IAAc,EAAK,WAAW,CAAO;GAC3C,OAAO;IACL,GAAG;IACH,OAAO,GAAe;KACpB,IAAM,IAAQ,EAAY,OAAO,CAAa;KAC9C,OAAO;MAAE,GAAG;MAAO,OAAO,EAAM,MAAM,IAAI,CAAe;KAAE;IAC7D;GACF;EACF;CACF;AACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** One pending frame at most; OrbitControls.update() reports when damping settles. */
|
|
2
|
+
export declare function createDemandRender({ update, render, request, cancel, }: {
|
|
3
|
+
update: () => boolean;
|
|
4
|
+
render: () => void;
|
|
5
|
+
request?: (callback: FrameRequestCallback) => number;
|
|
6
|
+
cancel?: (id: number) => void;
|
|
7
|
+
}): {
|
|
8
|
+
invalidate: () => void;
|
|
9
|
+
setActive(next: boolean): void;
|
|
10
|
+
dispose(): void;
|
|
11
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/components/pro/Flow/nodes/demandRender.ts
|
|
2
|
+
function e({ update: e, render: t, request: n = requestAnimationFrame, cancel: r = cancelAnimationFrame }) {
|
|
3
|
+
let i = null, a = !1, o = !1, s = !1, c = !0, l = () => {
|
|
4
|
+
a && !o && i === null && (i = n(u));
|
|
5
|
+
}, u = () => {
|
|
6
|
+
if (i = null, !a || o) return;
|
|
7
|
+
s = !0;
|
|
8
|
+
let n = e();
|
|
9
|
+
s = !1, (c || n) && t(), c = !1, n && l();
|
|
10
|
+
}, d = () => {
|
|
11
|
+
s || o || (c = !0, l());
|
|
12
|
+
};
|
|
13
|
+
return {
|
|
14
|
+
invalidate: d,
|
|
15
|
+
setActive(e) {
|
|
16
|
+
a === e || o || (a = e, a ? d() : i !== null && (r(i), i = null));
|
|
17
|
+
},
|
|
18
|
+
dispose() {
|
|
19
|
+
o = !0, i !== null && r(i), i = null;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { e as createDemandRender };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=demandRender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demandRender.js","names":[],"sources":["../../../../../src/components/pro/Flow/nodes/demandRender.ts"],"sourcesContent":["/** One pending frame at most; OrbitControls.update() reports when damping settles. */\nexport function createDemandRender({\n update,\n render,\n request = requestAnimationFrame,\n cancel = cancelAnimationFrame,\n}: {\n update: () => boolean;\n render: () => void;\n request?: (callback: FrameRequestCallback) => number;\n cancel?: (id: number) => void;\n}) {\n let frame: number | null = null;\n let active = false;\n let disposed = false;\n let updating = false;\n let dirty = true;\n\n const schedule = () => {\n if (active && !disposed && frame === null) frame = request(tick);\n };\n const tick = () => {\n frame = null;\n if (!active || disposed) return;\n updating = true;\n const changed = update();\n updating = false;\n if (dirty || changed) render();\n dirty = false;\n if (changed) schedule();\n };\n const invalidate = () => {\n // update() emits change synchronously; its boolean result already accounts\n // for that change. Scheduling here would leave an extra perpetual RAF.\n if (updating || disposed) return;\n dirty = true;\n schedule();\n };\n return {\n invalidate,\n setActive(next: boolean) {\n if (active === next || disposed) return;\n active = next;\n if (active) invalidate();\n else if (frame !== null) {\n cancel(frame);\n frame = null;\n }\n },\n dispose() {\n disposed = true;\n if (frame !== null) cancel(frame);\n frame = null;\n },\n };\n}\n"],"mappings":";AACA,SAAgB,EAAmB,EACjC,WACA,WACA,aAAU,uBACV,YAAS,wBAMR;CACD,IAAI,IAAuB,MACvB,IAAS,IACT,IAAW,IACX,IAAW,IACX,IAAQ,IAEN,UAAiB;EACrB,AAAI,KAAU,CAAC,KAAY,MAAU,SAAM,IAAQ,EAAQ,CAAI;CACjE,GACM,UAAa;EAEjB,IADA,IAAQ,MACJ,CAAC,KAAU,GAAU;EACzB,IAAW;EACX,IAAM,IAAU,EAAO;EAIvB,AAHA,IAAW,KACP,KAAS,MAAS,EAAO,GAC7B,IAAQ,IACJ,KAAS,EAAS;CACxB,GACM,UAAmB;EAGnB,KAAY,MAChB,IAAQ,IACR,EAAS;CACX;CACA,OAAO;EACL;EACA,UAAU,GAAe;GACnB,MAAW,KAAQ,MACvB,IAAS,GACL,IAAQ,EAAW,IACd,MAAU,SACjB,EAAO,CAAK,GACZ,IAAQ;EAEZ;EACA,UAAU;GAGR,AAFA,IAAW,IACP,MAAU,QAAM,EAAO,CAAK,GAChC,IAAQ;EACV;CACF;AACF"}
|
|
@@ -121,11 +121,11 @@ var c = [
|
|
|
121
121
|
action: (e) => e
|
|
122
122
|
}
|
|
123
123
|
], l = ({ editor: l }) => {
|
|
124
|
-
let [u, d] = i(!1), [f, p] = i(""
|
|
124
|
+
let [u, d] = i(!1), [f, p] = i(null), m = f?.query ?? "", [h, g] = i({
|
|
125
125
|
x: 0,
|
|
126
126
|
y: 0
|
|
127
|
-
}), [
|
|
128
|
-
if (l.isDestroyed || !l.isEditable || l.view.composing ||
|
|
127
|
+
}), [_, v] = i(0), y = r(null), b = r(null), x = r(null), S = r(!1), C = e(() => {
|
|
128
|
+
if (l.isDestroyed || !l.isEditable || l.view.composing || S.current) return null;
|
|
129
129
|
let e = l.state.selection;
|
|
130
130
|
if (!(e instanceof s) || !e.empty || e.$from.parent.type.spec.code || e.$from.marks().some((e) => e.type.spec.code)) return null;
|
|
131
131
|
let { $from: t } = e, n = t.parent.textBetween(0, t.parentOffset, "\n", (e) => e.type.name === "hardBreak" ? "\n" : ""), r = /(?:^|\s)\/([^\s/]*)$/.exec(n);
|
|
@@ -134,70 +134,80 @@ var c = [
|
|
|
134
134
|
to: t.pos,
|
|
135
135
|
query: r[1]
|
|
136
136
|
} : null;
|
|
137
|
-
}, [l]),
|
|
138
|
-
let t =
|
|
137
|
+
}, [l]), w = m ? c.filter((e) => {
|
|
138
|
+
let t = m.toLowerCase();
|
|
139
139
|
return e.label.toLowerCase().includes(t) || e.description.toLowerCase().includes(t) || e.keywords?.some((e) => e.includes(t));
|
|
140
|
-
}) : c,
|
|
141
|
-
d(!1), p(
|
|
142
|
-
let e =
|
|
143
|
-
e && (
|
|
144
|
-
}, []),
|
|
145
|
-
let t =
|
|
146
|
-
if (!t || !n || t.from !== n.from || t.to !== n.to || t.query !== n.query) {
|
|
147
|
-
|
|
140
|
+
}) : c, T = e(() => {
|
|
141
|
+
d(!1), p(null);
|
|
142
|
+
let e = b.current;
|
|
143
|
+
e && (x.current = `${e.from}:${e.to}:${e.query}`), b.current = null, v(0);
|
|
144
|
+
}, []), E = e((e) => {
|
|
145
|
+
let t = C(), n = b.current;
|
|
146
|
+
if (!t || !n || !f || t.from !== f.from || t.to !== f.to || t.query !== f.query || t.from !== n.from || t.to !== n.to || t.query !== n.query) {
|
|
147
|
+
T();
|
|
148
148
|
return;
|
|
149
149
|
}
|
|
150
150
|
let r = e.label === "Image" ? window.prompt("Image URL:")?.trim() : void 0;
|
|
151
151
|
if (e.label === "Image" && !r) {
|
|
152
|
-
|
|
152
|
+
T();
|
|
153
153
|
return;
|
|
154
154
|
}
|
|
155
|
-
|
|
155
|
+
T();
|
|
156
156
|
let i = l.chain().focus().deleteRange(t);
|
|
157
157
|
(r ? i.setImage({ src: r }) : e.action(i)).run();
|
|
158
158
|
}, [
|
|
159
159
|
l,
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
C,
|
|
161
|
+
T,
|
|
162
|
+
f
|
|
162
163
|
]);
|
|
163
164
|
return t(() => {
|
|
164
165
|
let e, t = () => {
|
|
165
|
-
let e = l.isFocused ?
|
|
166
|
+
let e = l.isFocused ? C() : null;
|
|
166
167
|
if (!e) {
|
|
167
|
-
|
|
168
|
+
b.current = null, x.current = null, d(!1);
|
|
168
169
|
return;
|
|
169
170
|
}
|
|
170
|
-
|
|
171
|
+
x.current !== `${e.from}:${e.to}:${e.query}` && ((b.current?.query !== e.query || b.current?.from !== e.from) && v(0), b.current = e, p(e), d(!0));
|
|
171
172
|
}, n = () => {
|
|
172
|
-
|
|
173
|
+
S.current = !0, T();
|
|
173
174
|
}, r = () => {
|
|
174
|
-
|
|
175
|
+
S.current = !1, x.current = null, e = setTimeout(t, 0);
|
|
175
176
|
}, i = l.view.dom;
|
|
176
|
-
return l.on("transaction", t), l.on("blur",
|
|
177
|
-
clearTimeout(e), l.off("transaction", t), l.off("blur",
|
|
177
|
+
return l.on("transaction", t), l.on("blur", T), i.addEventListener("compositionstart", n), i.addEventListener("compositionend", r), () => {
|
|
178
|
+
clearTimeout(e), l.off("transaction", t), l.off("blur", T), i.removeEventListener("compositionstart", n), i.removeEventListener("compositionend", r);
|
|
178
179
|
};
|
|
179
180
|
}, [
|
|
180
181
|
l,
|
|
181
|
-
|
|
182
|
-
|
|
182
|
+
C,
|
|
183
|
+
T
|
|
183
184
|
]), n(() => {
|
|
184
|
-
if (!u || !
|
|
185
|
-
let e = l.view.dom.closest(".rte-editor-wrapper"), t =
|
|
185
|
+
if (!u || !w.length) return;
|
|
186
|
+
let e = l.view.dom.closest(".rte-editor-wrapper"), t = y.current;
|
|
186
187
|
if (!e || !t) return;
|
|
187
188
|
let n = () => {
|
|
188
|
-
let n =
|
|
189
|
+
let n = C();
|
|
189
190
|
if (!n) {
|
|
190
|
-
|
|
191
|
+
T();
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
let r = l.view.coordsAtPos(n.to), i = e.getBoundingClientRect(), a = Math.max(8, i.left + e.clientLeft), o = Math.min(window.innerWidth - 8, i.right), s = Math.max(8, i.top + e.clientTop), c = Math.min(window.innerHeight - 8, i.bottom);
|
|
195
|
+
if (o <= a || c <= s || r.bottom < s || r.top > c) {
|
|
196
|
+
T();
|
|
191
197
|
return;
|
|
192
198
|
}
|
|
193
|
-
let
|
|
194
|
-
t.style.minWidth = "0", t.style.width = `${Math.min(280,
|
|
195
|
-
let f = c - d - 4, p = u - s - 4, m = f < Math.min(300, t.scrollHeight) && p > f;
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
199
|
+
let u = Math.min(Math.max(r.top, s), c), d = Math.min(Math.max(r.bottom, s), c);
|
|
200
|
+
t.style.boxSizing = "border-box", t.style.minWidth = "0", t.style.width = `${Math.min(280, o - a)}px`;
|
|
201
|
+
let f = c - d - 4, p = u - s - 4, m = f < Math.min(300, t.scrollHeight) && p > f, h = m ? p : f;
|
|
202
|
+
if (h <= 0) {
|
|
203
|
+
T();
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
t.style.maxHeight = `${Math.min(300, h)}px`;
|
|
207
|
+
let _ = Math.max(a, Math.min(r.left, o - t.offsetWidth)), v = m ? u - t.offsetHeight - 4 : d + 4;
|
|
208
|
+
g({
|
|
209
|
+
x: _ - i.left - e.clientLeft + e.scrollLeft,
|
|
210
|
+
y: v - i.top - e.clientTop + e.scrollTop
|
|
201
211
|
});
|
|
202
212
|
};
|
|
203
213
|
return n(), window.addEventListener("scroll", n, !0), window.addEventListener("resize", n), l.on("transaction", n), () => {
|
|
@@ -206,54 +216,54 @@ var c = [
|
|
|
206
216
|
}, [
|
|
207
217
|
l,
|
|
208
218
|
u,
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
219
|
+
w.length,
|
|
220
|
+
C,
|
|
221
|
+
T
|
|
212
222
|
]), t(() => {
|
|
213
223
|
if (!u) return;
|
|
214
|
-
let e =
|
|
224
|
+
let e = y.current, t = e?.children[_];
|
|
215
225
|
e && t && (t.offsetTop < e.scrollTop ? e.scrollTop = t.offsetTop : t.offsetTop + t.offsetHeight > e.scrollTop + e.clientHeight && (e.scrollTop = t.offsetTop + t.offsetHeight - e.clientHeight));
|
|
216
|
-
}, [
|
|
226
|
+
}, [_, u]), t(() => {
|
|
217
227
|
if (!u) return;
|
|
218
228
|
let e = (e) => {
|
|
219
|
-
!l.view.dom.contains(e.target) || !l.isFocused || e.isComposing || e.keyCode === 229 || l.view.composing ||
|
|
229
|
+
!l.view.dom.contains(e.target) || !l.isFocused || e.isComposing || e.keyCode === 229 || l.view.composing || S.current || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || (w.length || e.key === "Escape") && ([
|
|
220
230
|
"ArrowDown",
|
|
221
231
|
"ArrowUp",
|
|
222
232
|
"Enter",
|
|
223
233
|
"Escape"
|
|
224
|
-
].includes(e.key) && e.stopImmediatePropagation(), e.key === "ArrowDown" ? (e.preventDefault(),
|
|
234
|
+
].includes(e.key) && e.stopImmediatePropagation(), e.key === "ArrowDown" ? (e.preventDefault(), v((e) => (e + 1) % w.length)) : e.key === "ArrowUp" ? (e.preventDefault(), v((e) => (e - 1 + w.length) % w.length)) : e.key === "Enter" ? (e.preventDefault(), w[_] && E(w[_])) : e.key === "Escape" && (e.preventDefault(), T()));
|
|
225
235
|
};
|
|
226
236
|
return document.addEventListener("keydown", e, !0), () => document.removeEventListener("keydown", e, !0);
|
|
227
237
|
}, [
|
|
228
238
|
l,
|
|
229
239
|
u,
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
240
|
+
w,
|
|
241
|
+
_,
|
|
242
|
+
E,
|
|
243
|
+
T
|
|
234
244
|
]), t(() => {
|
|
235
245
|
if (!u) return;
|
|
236
246
|
let e = (e) => {
|
|
237
|
-
|
|
247
|
+
y.current && !y.current.contains(e.target) && T();
|
|
238
248
|
};
|
|
239
249
|
return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
|
|
240
|
-
}, [u,
|
|
241
|
-
ref:
|
|
250
|
+
}, [u, T]), !u || w.length === 0 ? null : /* @__PURE__ */ a("div", {
|
|
251
|
+
ref: y,
|
|
242
252
|
className: "rte-slash-menu",
|
|
243
253
|
role: "menu",
|
|
244
254
|
"aria-label": "Insert block",
|
|
245
255
|
style: {
|
|
246
|
-
left:
|
|
247
|
-
top:
|
|
256
|
+
left: h.x,
|
|
257
|
+
top: h.y
|
|
248
258
|
},
|
|
249
259
|
onMouseDown: (e) => e.preventDefault(),
|
|
250
|
-
children:
|
|
260
|
+
children: w.map((e, t) => /* @__PURE__ */ o("button", {
|
|
251
261
|
type: "button",
|
|
252
262
|
role: "menuitem",
|
|
253
263
|
tabIndex: -1,
|
|
254
|
-
className: `rte-slash-menu__item ${t ===
|
|
255
|
-
onClick: () =>
|
|
256
|
-
onMouseEnter: () =>
|
|
264
|
+
className: `rte-slash-menu__item ${t === _ ? "rte-slash-menu__item--active" : ""}`,
|
|
265
|
+
onClick: () => E(e),
|
|
266
|
+
onMouseEnter: () => v(t),
|
|
257
267
|
children: [/* @__PURE__ */ a("span", {
|
|
258
268
|
className: "rte-slash-menu__icon",
|
|
259
269
|
children: e.icon
|