mcl-test
Version:
596 lines (595 loc) • 16.4 kB
JavaScript
import { defineComponent as B, createVNode as c, computed as C, reactive as O, createTextVNode as x, ref as H, watchEffect as E, watch as $ } from "vue";
function I(e) {
return Object.prototype.toString.call(e).slice(8, -1).toLowerCase();
}
function N(e, n = "", o = 0, s) {
const {
key: h,
index: m,
type: d = "content",
showComma: b = !1,
length: g = 1
} = s || {}, y = I(e);
if (y === "array") {
const k = F(
e.map(
(v, f, w) => N(v, `${n}/${f}`, o + 1, {
index: f,
showComma: f !== w.length - 1,
length: g,
type: d
})
)
);
return [
N("[", n, o, {
showComma: !1,
key: h,
length: e.length,
type: "arrayStart"
})[0]
].concat(
k,
N("]", n, o, {
showComma: b,
length: e.length,
type: "arrayEnd"
})[0]
);
} else if (y === "object") {
const k = Object.keys(e), v = F(
k.map(
(f, w, j) => N(
e[f],
/^[a-zA-Z_]\w*$/.test(f) ? `${n}/${f}` : `${n}/${f}`,
o + 1,
{
key: f,
showComma: w !== j.length - 1,
length: g,
type: d
}
)
)
);
return [
N("{", n, o, {
showComma: !1,
key: h,
index: m,
length: k.length,
type: "objectStart"
})[0]
].concat(
v,
N("}", n, o, { showComma: b, length: k.length, type: "objectEnd" })[0]
);
}
return [
{
content: e,
level: o,
key: h,
index: m,
path: n,
showComma: b,
length: g,
type: d
}
];
}
function F(e) {
if (typeof Array.prototype.flat == "function")
return e.flat();
const n = [...e], o = [];
for (; n.length; ) {
const s = n.shift();
Array.isArray(s) ? n.unshift(...s) : o.push(s);
}
return o;
}
function P(e, n = /* @__PURE__ */ new WeakMap()) {
if (e == null) return e;
if (e instanceof Date) return new Date(e);
if (e instanceof RegExp) return new RegExp(e);
if (typeof e != "object") return e;
if (n.get(e))
return n.get(e);
if (Array.isArray(e)) {
const s = e.map((h) => P(h, n));
return n.set(e, s), s;
}
const o = {};
for (const s in e)
o[s] = P(e[s], n);
return n.set(e, o), o;
}
function K(e) {
let n;
return e === "null" ? n = null : e === "undefined" ? n = void 0 : e === "true" ? n = !0 : e === "false" ? n = !1 : e[0] + e[e.length - 1] === '""' || e[0] + e[e.length - 1] === "''" ? n = e.slice(1, -1) : typeof Number(e) == "number" && !isNaN(Number(e)) || e === "NaN" ? n = Number(e) : n = e, n;
}
const M = /* @__PURE__ */ B({
props: {
data: {
required: !0,
type: String
},
onClick: Function
},
render() {
const {
data: e
} = this, {
onClick: n
} = this;
return c("span", {
class: "vjs-tree-brackets",
onClick: n
}, [e]);
}
}), Q = /* @__PURE__ */ B({
props: {
nodeType: {
required: !0,
type: String
},
onClick: Function
},
render() {
const {
nodeType: e
} = this, {
onClick: n
} = this, o = e === "objectStart" || e === "arrayStart";
return !o && !(e === "objectCollapsed" || e === "arrayCollapsed") ? null : c("span", {
class: `vjs-carets vjs-carets-${o ? "open" : "close"}`,
onClick: n
}, [c("svg", {
viewBox: "0 0 1024 1024",
focusable: "false",
"data-icon": "caret-down",
width: "1em",
height: "1em",
fill: "currentColor",
"aria-hidden": "true"
}, [c("path", {
d: "M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"
}, null)])]);
}
}), A = {
// Whether to display the length of (array|object).
showLength: {
type: Boolean,
default: !1
},
// Whether the key name uses double quotes.
showDoubleQuotes: {
type: Boolean,
default: !0
},
// Custom render for key.
renderNodeKey: Function,
// Custom render for value.
renderNodeValue: Function,
// Define the selection method supported by the data level, which is not available by default.
selectableType: String,
// Whether to display the selection control.
showSelectController: {
type: Boolean,
default: !1
},
// Whether to display the data level connection.
showLine: {
type: Boolean,
default: !1
},
showLineNumber: {
type: Boolean,
default: !1
},
// Whether to trigger selection when clicking on the node.
selectOnClickNode: {
type: Boolean,
default: !0
},
// When using the selectableType, define whether current path/content is enabled.
nodeSelectable: {
type: Function,
default: () => !0
},
// Highlight current node when selected.
highlightSelectedNode: {
type: Boolean,
default: !1
},
showIcon: {
type: Boolean,
default: !0
},
theme: {
type: String,
default: "light"
},
showKeyValueSpace: {
type: Boolean,
default: !0
},
editable: {
type: Boolean,
default: !1
},
editableTrigger: {
type: String,
default: "click"
},
onNodeClick: {
type: Function
},
onBracketsClick: {
type: Function
},
onIconClick: {
type: Function
},
onValueChange: {
type: Function
}
}, R = /* @__PURE__ */ B({
name: "TreeNode",
props: {
...A,
// Current node data.
node: {
type: Object,
required: !0
},
// Whether the current node is collapsed.
collapsed: Boolean,
// Whether the current node is checked(When using the selection function).
checked: Boolean,
style: Object,
onSelectedChange: {
type: Function
},
pointer: {
type: Object,
default: () => {
}
}
},
emits: ["nodeClick", "bracketsClick", "iconClick", "selectedChange", "valueChange"],
setup(e, {
emit: n
}) {
const o = C(() => I(e.node.content)), s = C(() => `vjs-value vjs-value-${o.value}`), h = C(() => e.showDoubleQuotes ? `"${e.node.key}"` : e.node.key), m = () => {
const t = e.renderNodeKey;
return t ? t({
node: e.node,
defaultKey: h.value || ""
}) : h.value;
}, d = C(() => e.selectableType === "multiple"), b = C(() => e.selectableType === "single"), g = C(() => e.nodeSelectable(e.node) && (d.value || b.value)), y = O({
editing: !1
}), k = (t) => {
var a;
const l = (a = t.target) == null ? void 0 : a.value, i = K(l);
n("valueChange", i, e.node.path);
}, v = C(() => {
var l;
let t = (l = e.node) == null ? void 0 : l.content;
return t === null ? t = "null" : t === void 0 && (t = "undefined"), o.value === "string" ? `"${t}"` : t + "";
}), f = () => {
const t = e.renderNodeValue;
return t ? t({
node: e.node,
defaultValue: v.value
}) : v.value;
}, w = () => {
n("bracketsClick", !e.collapsed, e.node);
}, j = () => {
n("iconClick", !e.collapsed, e.node);
}, L = () => {
n("nodeClick", e.node), g.value && e.selectOnClickNode && n("selectedChange", e.node);
}, T = (t) => {
if (e.editable && !y.editing) {
y.editing = !0;
const l = (i) => {
var a;
i.target !== t.target && ((a = i.target) == null ? void 0 : a.parentElement) !== t.target && (y.editing = !1, document.removeEventListener("click", l));
};
document.removeEventListener("click", l), document.addEventListener("click", l);
}
};
return () => {
const {
node: t,
pointer: l
} = e;
return c("div", {
class: {
"vjs-tree-node": !0,
"has-selector": e.showSelectController,
"has-carets": e.showIcon,
"is-highlight": e.highlightSelectedNode && e.checked,
dark: e.theme === "dark"
},
onClick: L,
style: e.style,
"data-pointer": JSON.stringify(l)
}, [e.showLineNumber && c("span", {
class: "vjs-node-index"
}, [t.id + 1]), c("div", {
class: "vjs-indent"
}, [Array.from(Array(t.level)).map((i, a) => c("div", {
key: a,
class: {
"vjs-indent-unit": !0,
"has-line": e.showLine
}
}, null)), e.showIcon && c(Q, {
nodeType: t.type,
onClick: j
}, null)]), t.key && c("span", {
class: "vjs-key"
}, [m(), c("span", {
class: "vjs-colon"
}, [`:${e.showKeyValueSpace ? " " : ""}`])]), c("span", null, [t.type !== "content" && t.content ? c(M, {
data: t.content.toString(),
onClick: w
}, null) : c("span", {
class: s.value,
onClick: e.editable && (!e.editableTrigger || e.editableTrigger === "click") ? T : void 0,
onDblclick: e.editable && e.editableTrigger === "dblclick" ? T : void 0
}, [e.editable && y.editing ? c("input", {
value: v.value,
onChange: k,
style: {
padding: "3px 8px",
border: "1px solid #eee",
boxShadow: "none",
boxSizing: "border-box",
borderRadius: 5,
fontFamily: "inherit"
}
}, null) : f()]), t.showComma && c("span", null, [","]), e.showLength && e.collapsed && c("span", {
class: "vjs-comment"
}, [x(" // "), t.length, x(" items ")])])]);
};
}
}), Y = /* @__PURE__ */ B({
name: "Tree",
props: {
...A,
// JSONLike data.
data: {
type: [String, Number, Boolean, Array, Object],
default: null
},
collapsedNodeLength: {
type: Number,
default: 1 / 0
},
// Define the depth of the tree, nodes greater than this depth will not be expanded.
deep: {
type: Number,
default: 8
},
pathCollapsible: {
type: Function,
default: () => !1
},
// Data root path.
rootPath: {
type: String,
default: ""
},
// Whether to use virtual scroll, usually applied to big data.
virtual: {
type: Boolean,
default: !1
},
// When using virtual scroll, set the height of tree.
height: {
type: Number,
default: 400
},
// When using virtual scroll, define the height of each row.
itemHeight: {
type: Number,
default: 20
},
// When there is a selection function, define the selected path.
// For multiple selections, it is an array ['root.a','root.b'], for single selection, it is a string of 'root.a'.
selectedValue: {
type: [String, Array],
default: () => ""
},
// Collapsed control.
collapsedOnClickBrackets: {
type: Boolean,
default: !0
},
style: Object,
onSelectedChange: {
type: Function
},
theme: {
type: String,
default: "light"
},
//json字符串位置映射
pointers: {
type: Object,
default: () => {
}
}
},
// slots: ['renderNodeKey', 'renderNodeValue'],
emits: ["nodeClick", "bracketsClick", "iconClick", "selectedChange", "update:selectedValue", "update:data"],
setup(e, {
emit: n,
slots: o
}) {
const s = H(), h = C(() => N(e.data, e.rootPath)), m = (t, l) => h.value.reduce((i, a) => {
var S;
const u = a.level >= t || a.length >= l, r = (S = e.pathCollapsible) == null ? void 0 : S.call(e, a);
return (a.type === "objectStart" || a.type === "arrayStart") && (u || r) ? {
...i,
[a.path]: 1
} : i;
}, {}), d = O({
translateY: 0,
visibleData: null,
hiddenPaths: m(e.deep, e.collapsedNodeLength)
}), b = C(() => {
let t = null;
const l = [], i = h.value.length;
for (let a = 0; a < i; a++) {
const r = {
...h.value[a],
id: a
}, S = d.hiddenPaths[r.path];
if (t && t.path === r.path) {
const D = t.type === "objectStart", V = {
...r,
...t,
showComma: r.showComma,
content: D ? "{...}" : "[...]",
type: D ? "objectCollapsed" : "arrayCollapsed"
};
t = null, l.push(V);
} else if (S && !t) {
t = r;
continue;
} else {
if (t) continue;
l.push(r);
}
}
return l;
}), g = C(() => {
const t = e.selectedValue;
return t && e.selectableType === "multiple" && Array.isArray(t) ? t : [t];
}), y = () => {
var l;
const t = b.value;
if (e.virtual) {
const i = e.height / e.itemHeight, a = ((l = s.value) == null ? void 0 : l.scrollTop) || 0, u = Math.floor(a / e.itemHeight);
let r = u < 0 ? 0 : u + i > t.length ? t.length - i : u;
r < 0 && (r = 0);
const S = r + i;
d.translateY = r * e.itemHeight, d.visibleData = t.filter((D, V) => V >= r && V < S);
} else
d.visibleData = t;
}, k = () => {
y();
}, v = ({
path: t
}) => {
const l = e.selectableType;
if (l === "multiple") {
const i = g.value.findIndex((u) => u === t), a = [...g.value];
i !== -1 ? a.splice(i, 1) : a.push(t), n("update:selectedValue", a), n("selectedChange", a, [...g.value]);
} else if (l === "single" && g.value[0] !== t) {
const [i] = g.value, a = t;
n("update:selectedValue", a), n("selectedChange", a, i);
}
}, f = (t) => {
n("nodeClick", t);
}, w = (t, l) => {
if (t)
d.hiddenPaths = {
...d.hiddenPaths,
[l]: 1
};
else {
const i = {
...d.hiddenPaths
};
delete i[l], d.hiddenPaths = i;
}
}, j = (t, l) => {
e.collapsedOnClickBrackets && w(t, l.path), n("bracketsClick", t, l);
}, L = (t, l) => {
w(t, l.path), n("iconClick", t, l);
}, T = (t, l) => {
const i = P(e.data), a = e.rootPath;
new Function("data", "val", `data${l.slice(a.length)}=val`)(i, t), n("update:data", i);
};
return E(() => {
b.value && y();
}), $(() => e.deep, (t) => {
t && (d.hiddenPaths = m(t, e.collapsedNodeLength));
}), $(() => e.collapsedNodeLength, (t) => {
t && (d.hiddenPaths = m(e.deep, t));
}), () => {
const t = e.renderNodeKey ?? o.renderNodeKey, l = e.renderNodeValue ?? o.renderNodeValue, {
pointers: i
} = e, a = d.visibleData && d.visibleData.map((u) => c(R, {
key: u.id,
node: u,
collapsed: !!d.hiddenPaths[u.path],
theme: e.theme,
showDoubleQuotes: e.showDoubleQuotes,
showLength: e.showLength,
checked: g.value.includes(u.path),
selectableType: e.selectableType,
showLine: e.showLine,
showLineNumber: e.showLineNumber,
showSelectController: e.showSelectController,
selectOnClickNode: e.selectOnClickNode,
nodeSelectable: e.nodeSelectable,
highlightSelectedNode: e.highlightSelectedNode,
editable: e.editable,
editableTrigger: e.editableTrigger,
showIcon: e.showIcon,
showKeyValueSpace: e.showKeyValueSpace,
renderNodeKey: t,
renderNodeValue: l,
onNodeClick: f,
onBracketsClick: j,
onIconClick: L,
onSelectedChange: v,
onValueChange: T,
style: e.itemHeight && e.itemHeight !== 20 ? {
lineHeight: `${e.itemHeight}px`
} : {},
pointer: i[u.path]
}, null));
return c("div", {
ref: s,
class: {
"vjs-tree": !0,
"is-virtual": e.virtual,
dark: e.theme === "dark"
},
onScroll: e.virtual ? k : void 0,
style: e.showLineNumber ? {
paddingLeft: `${Number(h.value.length.toString().length) * 12}px`,
...e.style
} : e.style
}, [e.virtual ? c("div", {
class: "vjs-tree-list",
style: {
height: `${e.height}px`
}
}, [c("div", {
class: "vjs-tree-list-holder",
style: {
height: `${b.value.length * e.itemHeight}px`
}
}, [c("div", {
class: "vjs-tree-list-holder-inner",
style: {
transform: `translateY(${d.translateY}px)`
}
}, [a])])]) : a]);
};
}
});
function z(e) {
e.component("jsonTree", Y);
}
export {
Y as JsonTree,
z as default
};