low-code-kit
Version:
low code config
1,242 lines (1,241 loc) • 38.2 kB
JavaScript
var H = Object.defineProperty;
var S = (s) => {
throw TypeError(s);
};
var B = (s, t, e) => t in s ? H(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
var C = (s, t, e) => B(s, typeof t != "symbol" ? t + "" : t, e), z = (s, t, e) => t.has(s) || S("Cannot " + e);
var D = (s, t, e) => t.has(s) ? S("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(s) : t.set(s, e);
var A = (s, t, e) => (z(s, t, "access private method"), e);
import v from "post-robot";
import { chunk as P, isObject as q, omitBy as K, isNil as V } from "lodash-es";
class R {
constructor() {
C(this, "_listeners", {});
this.all = /* @__PURE__ */ new Map();
}
/**
* 注册事件
* @param {string} type 事件类型
* @param {fn} listener
*/
addEventListener(t, e) {
this._listeners === void 0 && (this._listeners = {});
let n = this._listeners;
n[t] === void 0 && (n[t] = []), n[t].indexOf(e) === -1 && n[t].push(e);
}
/**
* 判断是否已注册事件
* @param {string} type
* @param {fn} listener
*/
hasEventListener(t, e) {
if (this._listeners === void 0) return !1;
let n = this._listeners;
return n[t] !== void 0 && n[t].indexOf(e) !== -1;
}
/**
* 移除事件
* @param {string} type 事件类型
* @param {fn} listener
*/
removeEventListener(t, e) {
if (this._listeners === void 0) return;
let i = this._listeners[t];
if (i !== void 0) {
let r = i.indexOf(e);
r !== -1 && i.splice(r, 1);
}
}
/**
* 分发事件
* @param {sting} type 事件类型
* @param {event} event 事件
*/
dispatchEvent(t, e, n) {
if (this._listeners === void 0) return;
let r = this._listeners[t];
if (r !== void 0) {
let a = r.slice(0);
for (let o = 0, l = a.length; o < l; o++)
a[o](e, n);
}
}
}
const U = [
"auxclick",
"click",
"contextmenu",
"dblclick",
"mousedown",
"mouseenter",
"mouseleave",
"mousemove",
"mouseover",
"mouseout",
"mouseup",
"pointerlockchange",
"pointerlockerror",
"select",
"wheel"
];
class F {
constructor(t) {
this.pageHandler = t, v.on("control", { window: this.pageHandler }, (e) => {
this.controlEl(e.data);
});
}
controlEl(t) {
const { compId: e, actionId: n } = t.data, i = t.args, r = document.querySelector(`[data-r-id="${e}"]`);
if (!r) return;
let a;
[n].forEach((o) => {
U.includes(o) ? (a = new MouseEvent(o, {
cancelable: !0
}), a.data = i) : a = new CustomEvent(o, { detail: i });
}), r.dispatchEvent(a);
}
}
function W(s) {
if (typeof s != "string") return !1;
const t = ["anov-part", "handle", "app"], e = s.split(" ");
return t.some((n) => e.includes(n));
}
function N(s) {
return Array.from(s, ([t, e]) => ({
path: t,
data: e
}));
}
const j = {
type: "page",
title: "双平台融合demo",
regions: ["body"],
body: [],
// tabsData
id: "u:-",
pullRefresh: {
disabled: !0
},
// 数据配置,整个项目中的数据
data: {
route: []
// 从路由中获取
},
themeCss: {
baseControlClassName: {
"background:default": "#1c1c2b"
}
}
}, J = {
type: "tabs",
id: "u:-",
tabs: [
{
title: "${label}",
id: "u:abcdefgh",
className: "no-bg",
body: []
// switchContainer
}
],
mountOnEnter: !0,
// source: '${route}',
activeKey: 0,
defaultKey: void 0,
onEvent: {
change: {
weight: 0,
actions: [
{
ignoreError: !1,
actionType: "remote",
groupType: "auto",
args: {
type: "route",
routePath: "${route[event.data.value - 1].value}",
query: []
}
}
]
}
},
linksClassName: "m-b",
contentClassName: "no-bg"
}, X = {
type: "switch-container",
items: [],
// pageConfig
style: {
position: "static",
display: "block"
},
id: "u:-",
isFixedHeight: !1,
isFixedWidth: !1,
visible: !0
}, G = {
title: "-",
// route label
body: [],
// flexConfig
// visibleOn: "${value == '-'}", // route path
id: "u:-",
editing: !1
}, Z = {
type: "flex",
items: [],
// flexItemConfig
style: {
position: "relative",
rowGap: "10px",
columnGap: "10px",
flexWrap: "nowrap"
},
themeCss: {
baseControlClassName: {
"padding-and-margin:default": {
marginBottom: "0.8rem"
}
}
},
id: "u:-"
}, Q = {
type: "container",
body: [],
// textConfig, buttonConfig, selectConfig, switchConfig, datePickerConfig
size: "none",
style: {
position: "static",
display: "block",
flex: "1 1 auto",
flexGrow: 1,
flexBasis: "0px",
minHeight: "100px"
},
wrapperBody: !1,
isFixedHeight: !1,
isFixedWidth: !1,
id: "u:-",
themeCss: {
baseControlClassName: {
"border:default": {
"top-border-width": "var(--borders-width-2)",
"left-border-width": "var(--borders-width-2)",
"right-border-width": "var(--borders-width-2)",
"bottom-border-width": "var(--borders-width-2)",
"top-border-style": "var(--borders-style-2)",
"left-border-style": "var(--borders-style-2)",
"right-border-style": "var(--borders-style-2)",
"bottom-border-style": "var(--borders-style-2)",
"top-border-color": "rgba(229, 229, 229, 0.5)",
"left-border-color": "rgba(229, 229, 229, 0.5)",
"right-border-color": "rgba(229, 229, 229, 0.5)",
"bottom-border-color": "rgba(229, 229, 229, 0.5)"
},
"padding-and-margin:default": {
paddingTop: "4px",
paddingRight: "4px",
paddingLeft: "4px",
paddingBottom: "4px"
},
"radius:default": {
"top-left-border-radius": "var(--borders-radius-5)",
"top-right-border-radius": "var(--borders-radius-5)",
"bottom-left-border-radius": "var(--borders-radius-5)",
"bottom-right-border-radius": "var(--borders-radius-5)"
}
}
}
}, Y = {
label: "按钮",
type: "button",
id: "u:-",
onEvent: {
click: {
actions: []
}
},
level: "dark",
themeCss: {
className: {
"padding-and-margin:default": {
marginTop: "var(--sizes-size-2)",
marginRight: "var(--sizes-size-2)",
marginBottom: "var(--sizes-size-2)",
marginLeft: "var(--sizes-size-2)"
}
}
}
}, ee = {
type: "select",
label: "选择",
name: "select",
options: [],
id: "u:-",
multiple: !1,
labelAlign: "inherit",
onEvent: {},
themeCss: {
selectControlClassName: {
"font:default": {
color: "var(--colors-neutral-text-11)"
},
"padding-and-margin:default": {
paddingLeft: "20px !important"
},
"background:default": "#303540",
"background:hover": "#5c5f66",
"padding-and-margin:hover": {}
},
labelClassName: {
"font:default": {
color: "var(--colors-neutral-text-11)"
}
},
selectPopoverClassName: {
"background:default": "#5c5f66"
}
}
}, te = {
type: "tpl",
tpl: "文字内容",
inline: !1,
wrapperComponent: "",
id: "u:-",
themeCss: {
baseControlClassName: {
"font:default": {
color: "#ffffff"
}
}
}
}, ne = {
type: "switch",
label: "开关",
option: "",
name: "switch",
falseValue: !1,
trueValue: !0,
id: "u:-"
}, se = {
type: "input-date",
label: "日期",
name: "date",
id: "u:-"
}, x = {
mainPage: j,
tabsData: J,
flexConfig: Z,
flexItemConfig: Q,
switchContainer: X,
pageConfig: G
}, E = {
button: Y,
select: ee,
text: te,
switcher: ne,
datePicker: se
};
var w, I;
class ie {
constructor(t) {
D(this, w);
this.candidates = t.map((e) => e.toLowerCase()), this.rules = [
{ keyword: "options", target: "select", weight: 0.3 },
{ keyword: "date", target: "input-date", weight: 0.3 },
{ keyword: "btn", target: "button", weight: 0.4 },
{ keyword: "click", target: "button", weight: 0.4 }
];
}
// 添加规则:keyword 为输入关键词,target 为候选目标,weight 为加权值
addRule(t, e, n) {
if (typeof n != "number")
throw new Error("权重必须是数字");
this.rules.push({
keyword: t.toLowerCase(),
target: e.toLowerCase(),
weight: n
});
}
// 移除规则
removeRule(t, e) {
this.rules = this.rules.filter(
(n) => n.keyword !== t.toLowerCase() || n.target !== e.toLowerCase()
);
}
normalizeData(t) {
if (t == null)
throw new Error("输入数据不能为空");
if (typeof t == "number")
return A(this, w, I).call(this, t);
if (Array.isArray(t))
return t.length === 0 ? [] : t.map((e) => A(this, w, I).call(this, e));
throw new Error("输入数据类型必须是数字或数组");
}
// 查找最佳匹配
findBestMatch(t) {
const e = t.toLowerCase().replace(/\s+/g, " ");
let n = null, i = 1;
return this.candidates.forEach((r) => {
const a = r.toLowerCase();
let o = 1;
if (e.includes(a))
o = a.length * 3;
else {
let l = e;
for (const d of a.split(
new RegExp("(?=[A-Z])|(?<=\\w)(?=\\d)|\\s+")
)) {
const u = l.indexOf(d);
if (u !== -1)
o += d.length, l = l.slice(u + d.length);
else {
o = 1;
break;
}
}
}
this.candidates.forEach((l) => {
l !== r && l.includes(r) && (o /= 2);
}), this.rules.forEach((l) => {
if (e.includes(l.keyword) && r === l.target) {
const d = 1 + this.normalizeData(l.weight);
o += d * r.length * 3;
}
}), o > i && (i = o, n = r);
}), n;
}
}
w = new WeakSet(), // 辅助函数:规范化单个数值
I = function(t) {
return Math.max(-100, Math.min(100, t)) / 100;
};
function O(s) {
let t = null;
for (const e in s) {
const n = s[e];
if (Array.isArray(n) && n.length > 0 && typeof n[0] == "object" && Object.keys(n[0]).length >= 2 && n[0] !== null) {
if (e.toLowerCase().includes("opt"))
return n;
t || (t = n);
}
}
return t;
}
function re(s) {
if (!s || typeof s != "object")
return null;
const t = O(s);
if (!t)
return null;
const e = /* @__PURE__ */ new Map(), n = t[0];
for (const a in n)
e.set(typeof n[a], a);
const i = {
string: [],
number: [],
boolean: []
};
for (const a in s) {
if (Array.isArray(s[a]) && s[a] === t)
continue;
const o = typeof s[a];
(o === "string" || o === "number" || o === "boolean") && i[o].push(a);
}
if (Object.values(i).reduce(
(a, o) => a + o.length,
0
) === 1) {
for (const a in i)
if (i[a].length === 1)
return i[a][0];
}
for (const [a, o] of e)
if (i[a] && i[a].length > 0)
return i[a][0];
for (const a in i)
if (i[a].length > 0)
return i[a][0];
return null;
}
const ae = (s) => K(s, V);
function oe(...s) {
return (t) => s.reduce((e, n) => n(e), t);
}
function le(s, t) {
const e = ce(t);
return oe(
(n) => de(e)(n),
(n) => ue(e)(n),
(n) => he(e)(n),
(n) => pe(e)(n),
(n) => fe(e)(n)
)(s);
}
function ce(s) {
const { mainPage: t, tabsData: e } = x;
return {
...t,
id: "u:main-page",
body: [
{
...e,
activeKey: s,
id: "u:tabs"
}
]
};
}
function de(s) {
return (t) => {
const { pageConfig: e } = x;
s.data.route = t.map((i) => ({
label: i.nameText,
value: i.path
}));
const n = t.map((i) => ({
...e,
title: `${i.nameText}`,
id: `u:${i.path}`,
className: "no-bg",
body: []
}));
return s.body[0].tabs = n, t;
};
}
function ue(s) {
return (t) => {
const { flexConfig: e, flexItemConfig: n } = x, { text: i } = E;
return Array.isArray(t) ? (t.forEach((r, a) => {
const l = (r.parts || []).filter(
(c) => c.isShowAtRemote !== !1
).map((c, h) => ({
...n,
id: `u:${r.path.replace(/\//g, "")}-${c.id}-item${h}`,
body: [
{
...i,
tpl: c.name,
id: `u:${r.path.replace(/\//g, "")}-${c.id}-text${h}`
}
]
})), u = P(l, 2).map((c, h) => ({
...e,
items: c,
id: `u:${r.path.replace(/\//g, "")}-row${h}`
}));
u.length > 0 && (s.body[0].tabs[a].body = u);
}), t) : (console.warn("processParts: data is not an array", t), t);
};
}
function he(s) {
return (t) => Array.isArray(t) ? (t.forEach((e, n) => {
const i = (e.parts || []).filter(
(a) => a.isShowAtRemote !== !1
);
P(i, 2).forEach((a, o) => {
a.forEach((l, d) => {
l.interactComps && l.interactComps.forEach((u) => {
try {
const c = M(u);
if (c) {
const h = s.body[0].tabs[n].body;
h.length > 0 && h[o].items[d].body.push(c);
}
} catch (c) {
console.warn("convertComponent error", c);
}
});
});
});
}), t) : (console.warn("processInteractiveComponents: data is not an array", t), t);
}
function $(s) {
const t = {}, e = (n) => {
const i = _(s);
return {
ignoreError: !1,
actionType: "remote",
args: {
type: "comp",
compId: s.dataRId,
actionId: n,
params: s.tagName === "SELECT" ? [{ key: "value", val: `\${${i}}` }] : []
}
};
};
return s.events.forEach((n) => {
t[n] && t[n].actions ? t[n].actions.push(e(n)) : t[n] = {
actions: [e(n)]
};
}), t;
}
const _ = (s) => {
var t;
return s.id || ((t = s.attributes.find((e) => e.name === "name")) == null ? void 0 : t.value) || s.dataRId;
}, L = new ie(["select", "button", "input-date"]);
function M(s) {
var a, o, l;
const { button: t, select: e, switcher: n, text: i, datePicker: r } = E;
switch (s.tagName) {
case "BUTTON":
return {
...t,
type: "button",
label: s.label || ((a = s.attributes.find((u) => u.name === "title")) == null ? void 0 : a.value),
id: s.dataRId,
onEvent: $(s)
};
case "SELECT":
const d = _(s);
return {
...e,
label: s.label || ((o = s.attributes.find((u) => u.name === "title")) == null ? void 0 : o.value),
name: d,
id: s.dataRId,
options: (l = s.options) == null ? void 0 : l.map((u) => ({
label: u.text,
value: u.value
})),
value: s.value,
onEvent: $(s)
};
// todo: 其他组件
default:
if (q(s.vueInfo)) {
const { tag: u, props: c, model: h, listeners: g, methods: b } = s.vueInfo, y = L.findBestMatch(JSON.stringify(s.vueInfo));
if (y && E[y]) {
if (y === "select" && !s.vueInfo.props.options)
return null;
if (h && Object.keys(h).length > 0) {
const m = h.expression, p = h.value, f = {
ignoreError: !1,
actionType: "remote",
args: {
type: "comp",
compId: s.dataRId,
compName: u,
actionId: "v-model",
params: [
{
key: m,
val: `\${${m}}`
}
]
}
};
return {
...E[y],
label: s.label,
id: s.dataRId,
value: p,
name: m,
options: s.vueInfo.props.options,
onEvent: {
change: {
actions: [f]
}
}
};
} else if (Array.isArray(g) && g.length > 0) {
const m = g.map((p) => ({
ignoreError: !1,
actionType: "remote",
args: {
type: "comp",
compId: s.dataRId,
compName: u,
actionId: "@",
params: [
{
key: g[0],
val: `\${${g[0]}}`
}
]
}
}));
return {
...E[y],
label: s.label,
id: s.dataRId,
value: c[re(c)],
// 猜一个可能的属性名😂
name: g[0],
options: O(s.vueInfo.props),
// 猜一个可能的 options 数组😂
onEvent: {
change: {
actions: m
}
}
};
}
}
return null;
} else {
const u = ae(s), c = L.findBestMatch(JSON.stringify(u));
return c ? (s.tagName = c.toUpperCase(), M(s)) : null;
}
}
}
function pe(s) {
return (t) => (s.body[0].onEvent = x.tabsData.onEvent, t);
}
function fe(s) {
return (t) => s;
}
class ge {
constructor(t, e, n, i) {
this.app = t, this.pageHandler = e, this.selector = n, this.url = i, this.amisData = {}, v.on("amis", { window: this.pageHandler }, async (r) => this._collectData({})), v.on("config", { window: this.pageHandler }, (r) => this._collectConfigData()), v.on("remote.exchange", { window: this.pageHandler }, (r) => {
r.origin === new URL(this.url).origin ? t.actionServer.exec("remote.amis", r.data.data) : console.log("Origin does not match", r);
}), v.on("save", { window: this.pageHandler }, (r) => fetch("/save-data", {
method: "POST",
body: JSON.stringify(r.data)
}).catch((a) => {
console.error("Error saving data", a);
}));
}
// 获取持久化数据
async getPersistentData(t = "./remote-schema.json") {
try {
const e = await fetch(t).then((n) => n.json());
return typeof e == "string" ? JSON.parse(e) : e;
} catch {
return console.warn("Cannot fetch persistent data"), null;
}
}
_collectData(t = {}) {
const e = N(this.selector.data), i = this.app.root.$router.options.routes.findIndex(
(o) => o.path === this.app.root.$router.currentRoute.path
);
if (t && Object.keys(t).length > 0)
return t.body[0].activeKey = i, this.amisData = t, t;
const a = le(
e.map(({ data: o }) => o),
i
);
return a.body[0].activeKey = i, this.amisData = a, a;
}
_collectConfigData() {
const t = this.app.root.$router.options.routes, e = N(this.selector.data).map((n) => {
const i = n.data.parts.reduce((r, a) => (a.interactComps && Array.isArray(a.interactComps) && r.push(...a.interactComps), r), []);
return {
path: n.path,
data: i
};
});
return {
routes: t.map(({ name: n, path: i, nameText: r }) => ({
name: n,
path: i,
nameText: r
})),
activeRoute: this.app.root.$router.currentRoute.path,
components: e
};
}
_sender(t, e) {
v.send(this.pageHandler, t, e).catch((n) => {
console.error("Error sending event to page", n);
});
}
select(t) {
this._sender("select", t);
}
deselect() {
this._sender("deselect");
}
// 同步 amis schema JSON 数据
syncAmisSchema() {
if (this.pageHandler.closed) return;
const t = this._collectData.bind(this)();
console.log("sync amis data", t), v.send(this.pageHandler, "amis", t).catch((e) => {
console.error("Error sending data to page", e);
});
}
// 同步原始数据
syncConfig() {
if (this.pageHandler.closed) return;
const t = this._collectConfigData.bind(this)();
v.send(this.pageHandler, "config", t).catch((e) => {
console.error("Error sending data to page", e);
});
}
}
function me(s) {
const t = s.type;
if (["button", "submit", "reset"].includes(t))
return s.value;
const e = document.querySelector(`label[for="${s.name}"]`);
return (e == null ? void 0 : e.textContent) || s.getAttribute("placeholder");
}
function ve(s) {
if (s.tagName === "LABEL")
return s.textContent.trim();
const t = s.querySelectorAll("input, select, textarea, button");
if (t.length > 0)
for (const e of t) {
if (e.tagName === "INPUT" || e.tagName === "SELECT" || e.tagName === "TEXTAREA") {
const n = e.closest("div").querySelector("label");
if (n)
return n.textContent.trim();
let i = e.previousElementSibling;
for (; i; ) {
if (i.textContent.trim())
return i.textContent.trim();
i = i.previousElementSibling;
}
} else if (e.tagName === "BUTTON")
return (e.textContent || Array.from(e.childNodes).map((n) => n.textContent).join("")).trim();
if (e.title)
return e.title.trim();
}
else {
s.querySelectorAll("*");
const e = Array.from(s.querySelectorAll("*")).map((r) => r.title || r.textContent).find((r) => r.trim()), n = s.getAttribute("title"), i = s.textContent;
return n || i || (e == null ? void 0 : e.trim()) || "";
}
return null;
}
function ye(s) {
const t = s.tagName;
switch (t) {
case "BUTTON":
return (s.textContent || s.title || t).trim();
case "INPUT":
case "SELECT":
case "TEXTAREA":
return me(s) || t;
default:
return ve(s);
}
}
class be {
constructor(t, e) {
this.app = t, this.callback = e, this.isEnter = !1, t.$on(t.EventType.pageEnter, this.enterCb.bind(this)), t.$on(t.EventType.pageTlEnd, this.tlCallback.bind(this));
}
tlCallback() {
this.isEnter && (this.callback(window.location.href), this.isEnter = !1);
}
enterCb() {
this.isEnter = !0;
}
remove() {
app.$off(this.app.EventType.pageEnter, this.enterCb.bind(this)), app.$off(app.EventType.pageTlEnd, this.tlCallback.bind(this));
}
}
class Ee extends R {
constructor(e, n = "#app") {
super();
C(this, "handleMouseOver", (e) => {
if (!this.isPreviewing && this.isSelecting) {
this.highlightedElement && (this.highlightedElement.style.cursor = "");
let n = e.target;
if (e.target.getAttribute("data-r-id"))
e.target.style.cursor = "default";
else {
let i = e.target.parentElement;
for (; i && !i.getAttribute("data-r-id"); )
i = i.parentElement;
i && (n = i);
}
this.highlightElement(n);
}
});
C(this, "handleMouseLeave", (e) => {
this.isPreviewing || this.isSelecting && (this.highlightedElement && (this.highlightedElement.style.cursor = ""), this.removeHighlight());
});
this.app = e, this.selectedElement = null, this.highlightedElement = null, this.isSelecting = !1, this.eventTracker = new we(), this.edgeDom = n, this.maskDom = null, this.handleCapturingClick = this.handleCapturingClick.bind(this), this.routeChange = new be(e, (i) => {
const r = i.split("#")[1].split("?")[0];
this.autoCollectData(r), this.dispatchEvent("routeChange", this.data);
}), this.data = /* @__PURE__ */ new Map(), this.initData(), this.autoCollectData(window.location.hash.split("#")[1].split("?")[0]), this.previewing = !1;
}
get isPreviewing() {
return this.previewing;
}
set isPreviewing(e) {
this.previewing = e;
}
startSelect(e) {
typeof this.edgeDom == "string" && (this.edgeDom = document.querySelector(this.edgeDom)), this.isSelecting = !0, this.edgeDom.addEventListener("mouseover", this.handleMouseOver), this.edgeDom.addEventListener("mouseleave", this.handleMouseLeave), this.edgeDom.addEventListener("click", this.handleCapturingClick, !0), this.callback = e;
}
stopSelect() {
this.isSelecting = !1, this.edgeDom.removeEventListener("mouseover", this.handleMouseOver), this.edgeDom.removeEventListener("mouseleave", this.handleMouseLeave), this.edgeDom.removeEventListener("click", this.handleCapturingClick, !0), this.selectedElement && (this.removeHighlight(), this.removeHighlightSelectedElement(this.selectedElement), this.selectedElement = null), this.routeChange.remove();
}
handleCapturingClick(e) {
if (!this.isPreviewing && this.isSelecting) {
if (e.stopPropagation(), e.preventDefault(), this.selectedElement && this.removeHighlightSelectedElement(this.selectedElement), e.target === this.selectedElement) {
this.selectedElement = null, this.callback(null);
return;
}
this.selectedElement = e.target;
const n = this.getElementInfo(this.selectedElement), { events: i, className: r, dataRId: a } = n;
if (a && i.length > 0 && !W(r))
this.highlightSelectedElement(this.selectedElement), this.callback(n);
else {
let o = e.target.parentElement;
for (; o && !o.getAttribute("data-r-id"); )
o = o.parentElement;
if (o) {
this.selectedElement = o, this.highlightSelectedElement(o);
const l = this.getElementInfo(o);
this.callback(l);
} else
this.callback(null);
}
}
}
removeHighlightSelectedElement(e) {
e.style.outline = "";
}
highlightSelectedElement(e) {
e.style.outline = "3px solid #90ff37c7";
}
createMask(e, n) {
const i = document.querySelector(".low-code-kit-mask");
if (i && i.remove(), !this.maskDom)
this.maskDom = document.createElement("div");
else
for (; this.maskDom.firstChild; )
this.maskDom.removeChild(this.maskDom.firstChild);
this.maskDom.classList.add("low-code-kit-mask"), this.maskDom.style.position = "fixed", this.maskDom.style.top = e.y + "px", this.maskDom.style.left = e.x + "px", this.maskDom.style.width = e.width + "px", this.maskDom.style.height = e.height + "px", this.maskDom.style.backgroundColor = "rgba(66, 202, 215, 0.5)", this.maskDom.style.pointerEvents = "none", this.maskDom.style.borderRadius = "2px", this.maskDom.style.zIndex = "999999";
const r = document.createElement("div");
r.style.position = "absolute", r.style.top = "-3px", r.style.left = "0", r.style.transform = "translate(0%, -100%)", r.style.backgroundColor = "#fff", r.style.color = "black", r.style.padding = "2px 5px", r.style.fontSize = "12px", r.style.fontFamily = "monospace", r.style.borderRadius = "2px", r.style.whiteSpace = "nowrap";
const a = this.getElementInfo(n), o = document.createElement("span");
o.textContent = `<${a.tagName}>`, o.style.color = "#113285", o.style.fontSize = "12px", r.appendChild(o);
const l = document.createElement("span");
l.textContent = `${a.id ? " #" + a.id : ""}`, l.style.color = "#787878", l.style.fontSize = "10px", r.appendChild(l);
const d = document.createElement("div");
d.textContent = `${a.dataRId ? ` id: ${a.dataRId}` : ""}`, d.style.color = "#B35C37", d.style.fontSize = "11px", r.appendChild(d), this.maskDom.appendChild(r), document.body.contains(this.maskDom) || document.body.appendChild(this.maskDom);
}
highlightElement(e, n = !1) {
this.removeHighlight(), this.highlightedElement = e, this.createMask(e.getBoundingClientRect(), e);
}
removeHighlight() {
this.maskDom && this.maskDom.parentNode && this.maskDom.parentNode.removeChild(this.maskDom);
}
getElementInfo(e) {
const n = (i) => {
let r = i.parentElement;
for (; r; ) {
if (r.classList.contains("anov-part"))
return r.id;
r = r.parentElement;
}
return null;
};
return {
tagName: e.tagName,
dataRId: e.getAttribute("data-r-id"),
id: e.id,
partId: n(e),
label: this.getLabel(e),
className: e.className,
attributes: this.getAttributes(e),
events: this.eventTracker.getEvents(e),
value: this.getValue(e),
options: this.getOptions(e),
vueInfo: this.getVueInfo(e)
};
}
getAttributes(e) {
return Array.from(e.attributes).map((n) => ({
name: n.name,
value: n.value
}));
}
getValue(e) {
return e.tagName === "INPUT" || e.tagName === "TEXTAREA" || e.tagName === "SELECT" ? e.value : null;
}
getOptions(e) {
return e.tagName === "SELECT" ? Array.from(e.options).map((n) => ({
value: n.value,
text: n.text,
selected: n.selected
})) : null;
}
getLabel(e) {
return ye(e);
}
_getInstanceByTag(e, n) {
return e.$vnode.tag === n ? e : this._getInstanceByTag(e.$parent, n);
}
getVueInfo(e) {
const n = e.__vue__;
let i = e.getAttribute("data-r-vue");
return i && (i = JSON.parse(i)), n && i ? i : null;
}
initData() {
this.app.config.page.pages.forEach((n) => {
this.data.set(n.path, n);
});
}
autoCollectData(e) {
if (!this.edgeDom) return;
typeof this.edgeDom == "string" && (this.edgeDom = document.querySelector(this.edgeDom));
const i = this.edgeDom.querySelectorAll("[data-r-id]:not(.handle):not(.anov-part)");
if (!i) return;
const r = [...i].map((l) => this.getElementInfo(l));
e || (e = window.location.hash.split("#")[1].split("?")[0]);
const o = this.app.config.page.pages.find((l) => l.path === e);
if (o) {
const l = {};
r.forEach((d) => {
d.partId && (l[d.partId] || (l[d.partId] = []), l[d.partId].push(d));
}), o.parts = o.parts.map((d) => {
const u = { ...d };
return l[d.id] && (u.interactComps = l[d.id]), u;
});
}
this.data.set(e, o);
}
}
class we {
constructor() {
this.events = /* @__PURE__ */ new WeakMap(), this.setupEventListenerTracking();
}
setupEventListenerTracking() {
const t = this, e = Element.prototype.addEventListener, n = Element.prototype.removeEventListener;
Element.prototype.addEventListener = function(i, r, a) {
t.addEvent(this, i, r), e.call(this, i, r, a);
}, Element.prototype.removeEventListener = function(i, r, a) {
t.removeEvent(this, i, r), n.call(this, i, r, a);
};
}
addEvent(t, e, n) {
this.events.has(t) || this.events.set(t, /* @__PURE__ */ new Set()), this.events.get(t).add(e);
}
removeEvent(t, e, n) {
this.events.has(t) && this.events.get(t).delete(e);
}
getEvents(t) {
var r;
let e = this.events.has(t) ? Array.from(this.events.get(t)) : [];
for (let a in t)
a.startsWith("on") && typeof t[a] == "function" && e.push(a.slice(2));
[
"click",
"mouseover",
"mouseout",
"keydown",
"keyup",
"submit",
"change",
"input"
].forEach((a) => {
t[`on${a}`] && e.push(a);
});
const i = ((r = t.getAttribute("data-r-e")) == null ? void 0 : r.split("|")) || [];
return e = [...e, ...i], [...new Set(e)];
}
}
const k = {
manual: "manual",
auto: "auto"
};
class Ce extends R {
constructor(t, e = "#app") {
super(), this.app = t, this.isOpen = !1, this.preview = null, this.pageHandler = null, this.dataExchanger = null, this.edgeDom = e, this.selector = new Ee(t, e), this.isAutoCollectDone = !1;
}
openConfigPage(t) {
if (!t) return;
const e = "width=1920,height=1080,location=no,toolbar=no,menubar=no,scrollbars=yes,resizable=yes";
this.pageHandler = window.open(t, "Config Page", e), this.preview = new F(this.pageHandler), this.dataExchanger = new ge(
app,
this.pageHandler,
this.selector,
t
), this.selector.startSelect((n) => {
n ? this.dataExchanger.select(n) : this.dataExchanger.deselect();
}), this.selector.addEventListener("routeChange", () => {
this.dataExchanger.syncConfig();
}), this.checkChildTimer = setInterval(() => {
this.pageHandler.closed && (clearInterval(this.checkChildTimer), this.closeConfigPage(k.auto));
}, 500), this.dispatchEvent("open", { url: t }), this.isOpen = !0, v.on("preview", { window: this.pageHandler }, ({ data: n }) => (console.log("Received preview data:", n), this.setPreview(n), !0)), window.addEventListener("beforeunload", (n) => {
this.pageHandler.closed || (n.preventDefault(), this.closeConfigPage(k.auto));
}), !this.isAutoCollectDone && this.autoViewEveryRoute();
}
async autoViewEveryRoute() {
this.setMask();
const t = this.app.root.$router.options.routes;
for (let e = 0; e < t.length; e++)
await new Promise((n) => setTimeout(n, 1e3)), await this.changeRoute(), await new Promise((n) => setTimeout(n, 1e3));
setTimeout(() => {
this.isAutoCollectDone = !0, this.removeMask(), this.dataExchanger.syncAmisSchema();
}, 1e3);
}
async changeRoute() {
return this.app.pageServer.go(1), new Promise((t, e) => {
const n = this.app;
let i = !1;
function r() {
i = !0;
}
function a() {
i && (i = !1, setTimeout(() => {
t(), n.$off(n.EventType.pageTlEnd, a), n.$off(n.EventType.pageEnter, r);
}, 2e3));
}
n.$on(n.EventType.pageTlEnd, a), n.$on(n.EventType.pageEnter, r);
});
}
setMask() {
const t = document.querySelector(".low-code-kit-fullmask");
if (t)
t.remove();
else {
const e = document.createElement("div");
e.classList.add("low-code-kit-fullmask"), e.style.position = "absolute", e.style.top = "0", e.style.left = "0", e.style.width = "100%", e.style.height = "100%", e.style.backgroundColor = "rgba(66, 202, 215, 0.5)", e.style.zIndex = "999999", e.style.display = "flex", e.style.justifyContent = "center", e.style.alignItems = "center";
const n = document.createElement("div");
n.style.color = "#fff", n.style.fontSize = "20px", n.style.fontWeight = "bold", n.textContent = "数据自动收集中,请勿操作!", e.appendChild(n), document.querySelector(this.edgeDom).appendChild(e);
}
}
removeMask() {
const t = document.querySelector(".low-code-kit-fullmask");
t && t.remove();
}
setPreview(t) {
this.selector.isPreviewing = t;
}
closeConfigPage(t) {
const e = t !== k.auto && confirm("未保存数据将会丢失,您确定要关闭配置页面吗?");
(t === k.auto || e) && (this.pageHandler.close(), this.selector.stopSelect(), this.dispatchEvent("close"), this.isOpen = !1);
}
}
const ke = [
"auxclick",
"click",
"contextmenu",
"dblclick",
"mousedown",
"mouseenter",
"mouseleave",
"mousemove",
"mouseover",
"mouseout",
"mouseup",
"pointerlockchange",
"pointerlockerror",
"select",
"wheel"
], xe = ["INPUT", "TEXTAREA", "SELECT"], Ae = ["button", "radio", "checkbox"];
function T(s, t) {
return s.$vnode.componentOptions.tag === t ? s : T(s.$parent, t);
}
const Ie = [
{
id: "remote.amis",
name: "通过AMIS控制",
type: "system",
exec: (s, t) => {
const { type: e, routePath: n, query: i, actionId: r, compId: a, params: o } = t;
switch (e) {
case "route":
const l = i.reduce((c, h) => (c[h.key] = h.val, c), {});
if (s.$router.currentRoute.path === n) return;
s.$router.push({ path: n, query: l });
break;
case "comp":
{
const c = document.querySelector(`[data-r-id="${a}"]`);
if (!c) return;
if (r === "v-model") {
const p = c.__vue__;
if (!p) return;
const f = T(
p,
t.compName
);
if (!f) return;
f.$parent[o[0].key] = o[0].val;
return;
} else if (r.startsWith("@")) {
const p = c.__vue__;
if (!p) return;
const f = T(
p,
t.compName
);
if (!f) return;
f.$emit(o[0].key, o[0].val);
return;
}
const h = c.tagName, g = c.type;
let b;
const y = r.split("|"), m = o.reduce((p, f) => (p[f.key] = f.val, p), {});
y.forEach((p) => {
ke.includes(p) ? (b = new MouseEvent(p, {
cancelable: !0
}), b.data = m) : p === "change" && xe.includes(h) && !Ae.includes(g) ? (c.value = m.value, b = new Event(p, { detail: m })) : b = new CustomEvent(p, { detail: m });
}), c.dispatchEvent(b);
}
break;
case "action":
const u = o.reduce((c, h) => (c[h.key] = h.val, c), {});
app.actionServer.exec(r, u);
break;
}
}
}
];
function Te(s, t, e = {}) {
s.directive("collect", {
inserted: (i, r, a) => {
if (!a.componentInstance) {
console.warn("v-collect directive can only be used on Vue components");
return;
}
const o = a.componentOptions, l = a.tag, d = o.tag, u = Object.keys(o.listeners || {}), c = o.propsData || {}, h = a.data.model || {};
let g = {
wrapTag: l,
tag: d,
listeners: u,
props: c,
model: h
};
i.setAttribute("data-r-vue", JSON.stringify(g));
}
}), s.directive("replaceid", {
inserted: (i, r, a) => {
if (i.hasAttribute("dynid"))
i.setAttribute(
"data-r-id",
`${i.getAttribute("data-r-id")}_${i.getAttribute("dynid")}`
);
else if (!i.hasAttribute("dynid") && i.hasAttribute("data-r-id")) {
let o = i.parentElement;
for (; o; ) {
if (o.hasAttribute("dynid")) {
i.setAttribute(
"data-r-id",
`${i.getAttribute("data-r-id")}_${o.getAttribute("dynid")}`
);
break;
}
o = o.parentElement;
}
}
}
});
let n = null;
s.prototype.$lowCodeKit = new Proxy(
{},
{
get: (i, r) => (n || (n = new Ce(window.app, "#app")), typeof n[r] == "function" ? n[r].bind(n) : n[r])
}
), s.prototype.$safeAddAction = /* @__PURE__ */ ((i) => () => {
console.log("safeAddAction", i);
})();
}
(() => {
const s = () => {
console.log("handler"), requestAnimationFrame(() => {
window.app && window.app.isInit && window.app.actionServer ? window.app.actionServer.addActions(Ie) : setTimeout(s, 200);
});
};
setTimeout(s, 200);
})();
const $e = { install: Te };
export {
$e as default
};