This commit is contained in:
Rizky 2023-12-14 19:32:50 +07:00
parent 51807aa0c7
commit 8188589065
3 changed files with 142 additions and 293 deletions

View File

@ -148,13 +148,7 @@ export const ScriptMonaco = () => {
if (!mitem) {
active.item_id = "";
return <div>no mitem</div>;
} else if (
item.type === "item" &&
item.component?.id &&
meta.parent_mcomp?.meta.mitem
) {
mitem = meta.parent_mcomp?.meta.mitem;
} else if (item.type === "item" && item.component?.id) {
if (!mitem) {
active.item_id = "";
return <div>no mitem</div>;

View File

@ -1,5 +1,4 @@
import type { OnMount } from "@monaco-editor/react";
import { deepClone } from "web-utils";
import {
EPage,
IMeta,
@ -7,7 +6,6 @@ import {
PG,
active,
} from "../../../logic/ed-global";
import { getMetaById } from "../../../logic/tree/build";
type Monaco = Parameters<OnMount>[1];
export type MonacoEditor = Parameters<OnMount>[0];
@ -17,231 +15,54 @@ export const declareScope = async (
editor: MonacoEditor,
monaco: Monaco
) => {
let active_id = active.item_id;
const root = active.comp_id
? p.comp.list[active.comp_id].scope
: p.page.scope;
const meta_root = active.comp_id
? p.comp.list[active.comp_id].meta
const metas = active.comp_id
? p.comp.list[active.comp_id]?.meta
: p.page.meta;
if (!root) return;
const parents: IMeta[] = [];
let cur = meta;
while (!root[cur.item.id]) {
const parent = meta_root[cur.parent_item.id];
if (parent) {
cur = parent;
} else {
break;
if (cur && cur.parent) {
while (cur && cur.parent && cur.parent.id) {
if (cur.mitem) {
parents.unshift(cur);
}
}
const s = root[cur.item.id];
if (!s) return;
s.p.push(active_id);
const existing: Record<string, IEachArgScope> = {};
spreadScope(p, s, (arg) => {
const { name } = arg;
const e = existing[name];
if (e && e.s.s) {
if (e.type === "local") {
delete e.s.s.local;
}
if (e.type === "passprop" && e.s.s.passprop) {
delete e.s.s.passprop[e.name];
}
if (e.type === "prop" && e.s.s.props) {
delete e.s.s.props[e.name];
cur = metas[cur.parent.id];
}
}
existing[name] = arg;
});
spreadScope(p, s, (arg) => {
let { prev } = arg;
if (arg.type !== "local") {
addScope(
for (const p of parents) {
const def = p.scope.def;
if (def) {
if (def.local) {
addScope({
monaco,
`${arg.comp_id || ""}~${prev?.comp_id || ""}~${prev?.item_id || ""}__${
arg.type
}~${arg.name}~${arg.id}`,
`\
loc: { item_id: p.item.id, type: "item" },
source: `\
export const {};
declare global {
const ${arg.name} = ${arg.value};
}`
);
} else {
addScope(
monaco,
`${arg.comp_id || ""}~${prev?.comp_id || ""}~${prev?.item_id || ""}__${
arg.type
}~${arg.id}`,
`\
export const {};
const __val = ${arg.value};
declare global {
const ${arg.name}: typeof __val & { render: ()=>void };
}`
);
}
const ${def.local.name} = ${def.local.value};
}`,
});
};
const layout_scope = {} as Record<string, ISingleScope>;
type IEachArgScope = {
s: ISingleScope;
name: string;
value: string;
id: string;
type: "local" | "prop" | "passprop";
index?: number;
is_prop?: boolean;
comp_id?: string;
prev?: { comp_id: string; item_id: string };
};
const spreadScope = (
p: PG,
s: ISingleScope | undefined,
each: (arg: IEachArgScope) => void
) => {
if (!s) return;
const parents = [...s.p];
const layout_id = p.site.layout.id;
let layout = null as null | EPage;
if (layout_id && p.page.list[layout_id]) {
layout = p.page.list[layout_id].page;
if (!layout_scope[layout_id]) {
if (layout) {
const scopes = Object.values(layout.scope).filter((e) => {
return e.n === "content";
});
const scope = scopes.shift();
if (scope) {
layout_scope[layout_id] = scope;
}
}
}
const scope = layout_scope[layout_id];
if (scope) {
parents.shift();
scope.p.forEach((e) => parents.push(e));
}
}
const mergeScopes = (
parents: string[],
each: (arg: IEachArgScope) => void,
arg: { prev?: { comp_id: string; item_id: string } }
) => {
let { prev } = arg;
for (const _parent_id of parents) {
let parent_id = _parent_id;
if (parent_id === "root") continue;
let item = null as null | ISingleScope;
const meta = p.page.meta[parent_id];
if (layout && layout_scope[layout_id]) {
const scope = layout_scope[layout_id];
if (scope.p.includes(parent_id)) {
item = layout.scope[parent_id];
}
}
let comp_id = "";
if (!item) {
if (meta) {
if (meta.parent_mcomp) {
comp_id =
meta.parent_mcomp.meta.mitem?.get("component")?.get("id") || "";
if (comp_id) {
const scope = p.comp.list[comp_id].scope;
item = scope[meta.item.originalId || meta.item.id];
if (item) {
parent_id = meta.item.originalId || meta.item.id;
}
}
}
if (!item) {
item = p.page.scope[parent_id];
}
}
}
if (item) {
const scope = item.s;
if (scope) {
if (scope.local)
each({
s,
comp_id,
type: "local",
id: parent_id,
name: scope.local.name,
value: scope.local?.value,
index: scope.local?.index,
prev,
});
if (scope.passprop) {
for (const [k, v] of Object.entries(scope.passprop)) {
each({
s,
comp_id,
type: "passprop",
id: parent_id,
name: k,
value: v.value,
index: v.index,
prev,
});
}
}
if (scope.props) {
for (const [k, v] of Object.entries(scope.props)) {
each({
s,
comp_id,
type: "prop",
id: parent_id,
name: k,
value: v.value,
is_prop: true,
prev,
});
}
}
}
}
}
};
mergeScopes(parents, each, {});
};
const addScope = (arg: {
monaco: Monaco;
loc: { item_id: string; type: "prop" | "item" };
source: string;
}) => {
const { monaco, source } = arg;
const addScope = (monaco: Monaco, id: string, source: string) => {
const filename = `ts:scope~${JSON.stringify(arg.loc)}.d.ts`;
const model = monaco.editor.getModels().find((e) => {
return e.uri.toString() === `ts:scope~${id}.d.ts`;
return e.uri.toString() === filename;
});
if (model) {
model.setValue(source);
} else {
monaco.editor.createModel(
source,
"typescript",
monaco.Uri.parse(`ts:scope~${id}.d.ts`)
);
monaco.editor.createModel(source, "typescript", monaco.Uri.parse(filename));
}
};

View File

@ -27,7 +27,7 @@ export const jsMount = async (editor: MonacoEditor, monaco: Monaco, p?: PG) => {
jsxFragmentFactory: "React.Fragment",
target: monaco.languages.typescript.ScriptTarget.ES2015,
allowNonTsExtensions: true,
lib: ["esnext"],
lib: ["esnext", "dom"],
module: monaco.languages.typescript.ModuleKind.ESNext,
esModuleInterop: true,
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
@ -38,88 +38,122 @@ export const jsMount = async (editor: MonacoEditor, monaco: Monaco, p?: PG) => {
openCodeEditor(source, r, selectionOrPosition) {
if (p) {
p.ui.popup.script.mode === "js";
const cpath = r.path.substring(`scope~`.length).split("__");
const cpath =
r.path.substring(`scope~`.length).split("__").pop() || "";
const [comp_id, prev_comp_id, prev_item_id] = cpath[0].split("~");
if (cpath[1]) {
const path = cpath[1].split("~");
const type = path[0] as "prop" | "passprop" | "local";
const id = path[path.length - 1].replace(".d.ts", "");
if (type === "prop") {
p.ui.popup.script.open = false;
p.render();
setTimeout(() => {
p.ui.popup.script.type = "item";
p.ui.popup.script.prop_name = path[1];
p.ui.popup.script.type = "prop-instance";
p.ui.popup.script.prop_kind = "value";
p.ui.popup.script.open = true;
if (
!prev_comp_id &&
!prev_item_id &&
active.instance.item_id &&
active.comp_id
) {
active.item_id = active.instance.item_id;
active.comp_id = active.instance.comp_id;
active.instance.item_id = "";
active.instance.comp_id = "";
}
p.render();
}, 100);
return false;
} else {
let arg = {
type: "" as "prop" | "item",
item_id: "" as string | undefined,
comp_id: "",
instance_id: "",
};
try {
arg = JSON.parse(cpath.substring(0, cpath.length - 5) || "{}");
} catch (e) {}
if (arg.type) {
if (arg.type === "item") {
p.ui.popup.script.open = false;
p.ui.popup.script.type = "item";
p.ui.popup.script.prop_name = "";
p.render();
} else {
p.ui.popup.script.open = false;
p.render();
}
setTimeout(() => {
if (comp_id) {
let meta = p.page.meta[id];
if (active.comp_id) {
meta = p.comp.list[active.comp_id].meta[id];
return false;
}
active.instance.comp_id = active.comp_id;
active.instance.item_id = active.item_id;
if (meta && meta.item.originalId) {
active.item_id = meta.item.originalId;
} else {
active.item_id = id;
}
active.comp_id = comp_id;
} else {
if (active.comp_id) {
let meta = p.comp.list[active.comp_id].meta[id];
if (!meta) {
const _id = p.comp.list[active.comp_id].doc
.getMap("map")
.get("root")
?.get("id");
if (_id) {
active.item_id = _id;
p.render();
}
}
return false;
}
active.item_id = id;
}
p.ui.popup.script.open = true;
if (arg.type === "item") {
if (arg.item_id) {
active.item_id = arg.item_id;
p.render();
}
} else if (arg.type === "prop") {
}
}, 100);
}
}
// const [comp_id, prev_comp_id, prev_item_id] = cpath[0].split("~");
// if (cpath[1]) {
// const path = cpath[1].split("~");
// const type = path[0] as "prop" | "passprop" | "local";
// const id = path[path.length - 1].replace(".d.ts", "");
// if (type === "prop") {
// p.ui.popup.script.open = false;
// p.render();
// setTimeout(() => {
// p.ui.popup.script.type = "item";
// p.ui.popup.script.prop_name = path[1];
// p.ui.popup.script.type = "prop-instance";
// p.ui.popup.script.prop_kind = "value";
// p.ui.popup.script.open = true;
// if (
// !prev_comp_id &&
// !prev_item_id &&
// active.instance.item_id &&
// active.comp_id
// ) {
// active.item_id = active.instance.item_id;
// active.comp_id = active.instance.comp_id;
// active.instance.item_id = "";
// active.instance.comp_id = "";
// }
// p.render();
// }, 100);
// return false;
// } else {
// p.ui.popup.script.open = false;
// p.ui.popup.script.type = "item";
// p.ui.popup.script.prop_name = "";
// p.render();
// setTimeout(() => {
// if (comp_id) {
// let meta = p.page.meta[id];
// if (active.comp_id) {
// meta = p.comp.list[active.comp_id].meta[id];
// return false;
// }
// active.instance.comp_id = active.comp_id;
// active.instance.item_id = active.item_id;
// if (meta && meta.item.originalId) {
// active.item_id = meta.item.originalId;
// } else {
// active.item_id = id;
// }
// active.comp_id = comp_id;
// } else {
// if (active.comp_id) {
// let meta = p.comp.list[active.comp_id].meta[id];
// if (!meta) {
// const _id = p.comp.list[active.comp_id].doc
// .getMap("map")
// .get("root")
// ?.get("id");
// if (_id) {
// active.item_id = _id;
// p.render();
// }
// }
// return false;
// }
// active.item_id = id;
// }
// p.ui.popup.script.open = true;
// p.render();
// }, 100);
// }
// }
}
return false;