This commit is contained in:
Rizky 2023-12-09 11:17:28 +07:00
parent 1745a5eebc
commit 9e39b7d0fd
13 changed files with 170 additions and 295 deletions

View File

@ -119,7 +119,8 @@ export type EdMeta = {
mitem?: MItem;
};
parent_mcomp?: {
mitem: MItem;
minstance: MItem;
meta: EdMeta;
mcomp: MItem;
};
el?: ReactElement;

View File

@ -45,32 +45,34 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => {
});
}
sections.map((e) => {
if (p.page.root_id === "root") {
p.page.entry.push(e.get("id"));
}
syncWalkMap(
{
note: "tree-rebuild layout",
comps: p.comp.list,
item_loading: p.ui.tree.item_loading,
meta: p.page.meta,
scope: p.page.scope,
},
{
is_layout: true,
mitem: e,
parent_item: { id: p.page.root_id },
tree_root_id: p.page.root_id,
skip_add_tree: true,
portal,
each(meta) {
if (meta.item.name === "content") {
p.page.root_id = meta.item.id;
}
},
ldoc.doc.transact(() => {
sections.map((e) => {
if (p.page.root_id === "root") {
p.page.entry.push(e.get("id"));
}
);
syncWalkMap(
{
note: "tree-rebuild layout",
comps: p.comp.list,
item_loading: p.ui.tree.item_loading,
meta: p.page.meta,
scope: p.page.scope,
},
{
is_layout: true,
mitem: e,
parent_item: { id: p.page.root_id },
tree_root_id: p.page.root_id,
skip_add_tree: true,
portal,
each(meta) {
if (meta.item.name === "content") {
p.page.root_id = meta.item.id;
}
},
}
);
});
});
for (const [k, portal_out] of Object.entries(portal.out)) {

View File

@ -87,37 +87,38 @@ const walkCompTree = async (p: PG, mitem: MItem, comp_id: string) => {
out: {} as Record<string, EdMeta>,
};
syncWalkLoad(p, mitem, (id) => loadComponent(p, id));
mitem.doc?.transact(() => {
syncWalkMap(
{
note: "walk-comp",
comps: p.comp.list,
item_loading: p.ui.tree.item_loading,
meta,
tree,
component_not_found(id) {
setTimeout(() => {
if (loadcomp.pending.has(id) || p.comp.list[id]) {
waitUntil(() => !loadcomp.pending.has(id)).then(async () => {
walkCompTree(p, mitem, comp_id);
syncWalkMap(
{
note: "walk-comp",
comps: p.comp.list,
item_loading: p.ui.tree.item_loading,
meta,
tree,
component_not_found(id) {
setTimeout(() => {
if (loadcomp.pending.has(id) || p.comp.list[id]) {
waitUntil(() => !loadcomp.pending.has(id)).then(async () => {
walkCompTree(p, mitem, comp_id);
const { tree, meta } = await walkCompTree(p, mitem, comp_id);
p.comp.list[comp_id].tree = tree;
p.comp.list[comp_id].meta = meta;
p.render();
});
}
}, 100);
const { tree, meta } = await walkCompTree(p, mitem, comp_id);
p.comp.list[comp_id].tree = tree;
p.comp.list[comp_id].meta = meta;
p.render();
});
}
}, 100);
},
},
},
{
mitem,
is_layout: false,
parent_item: { id: "root" },
portal,
tree_root_id: "root",
}
);
{
mitem,
is_layout: false,
parent_item: { id: "root" },
portal,
tree_root_id: "root",
}
);
});
return { tree, meta };
};

View File

@ -81,7 +81,7 @@ export const syncWalkMap = (
each?: (meta: EdMeta) => void;
}
) => {
const { mitem, parent_item, parent_mcomp } = arg;
const { mitem, parent_item } = arg;
if (typeof mitem.get !== "function") {
return;
}
@ -98,8 +98,8 @@ export const syncWalkMap = (
}
let mapped = false;
if (parent_mcomp && id) {
const fcomp = parent_mcomp.mitem.get("component");
if (arg.parent_mcomp && id) {
const fcomp = arg.parent_mcomp.minstance.get("component");
if (fcomp) {
const ref_ids = fcomp.get("ref_ids");
@ -162,14 +162,20 @@ export const syncWalkMap = (
if (ref_comp && mitem_comp) {
const mcomp = ref_comp.doc.getMap("map").get("root");
if (mcomp) {
let ref_ids: Record<string, string> = item_comp.ref_ids;
if (!ref_ids) {
mitem_comp.set("ref_ids", new Y.Map() as any);
ref_ids = {};
}
const minstance = arg.parent_mcomp
? arg.parent_mcomp.minstance
: (mitem as MItem);
let mref_ids = minstance.get("component")?.get("ref_ids");
if (!mref_ids) {
minstance.get("component")?.set("ref_ids", new Y.Map() as any);
mref_ids = minstance.get("component")?.get("ref_ids");
}
if (mcomp) {
const old_id = item.id;
const ref_ids = mref_ids?.toJSON() || {};
mapItem(mcomp, item, ref_ids);
item.id = old_id;
@ -177,10 +183,11 @@ export const syncWalkMap = (
item,
mitem: mitem as MItem,
parent_item,
parent_mcomp: parent_mcomp,
parent_mcomp: arg.parent_mcomp,
indexed_scope: {},
is_layout: arg.is_layout,
};
if (item.name.startsWith("⬅")) {
arg.portal.in[item.name] = meta;
}
@ -232,7 +239,7 @@ export const syncWalkMap = (
tree_root_id: arg.tree_root_id,
mitem: mcontent,
jsx_prop_name: k,
parent_mcomp: arg.parent_mcomp,
parent_mcomp: { minstance, meta, mcomp },
parent_item: { id: item.id, mitem: mitem as MItem },
portal: arg.portal,
skip_add_tree: skip_tree_child,
@ -254,7 +261,7 @@ export const syncWalkMap = (
tree_root_id: arg.tree_root_id,
mitem: e,
parent_item: { id: item.id, mitem: mitem as MItem },
parent_mcomp: { mitem: mitem as MItem, mcomp },
parent_mcomp: { minstance, meta, mcomp },
skip_add_tree: true,
portal: arg.portal,
each: arg.each,
@ -274,7 +281,7 @@ export const syncWalkMap = (
jsx_prop_name: arg.jsx_prop_name,
mitem: mitem as MItem,
parent_item,
parent_mcomp: parent_mcomp,
parent_mcomp: arg.parent_mcomp,
indexed_scope: {},
};

View File

@ -1,11 +1,11 @@
import { useGlobal, useLocal } from "web-utils";
import { useEffect } from "react";
import { useGlobal } from "web-utils";
import { Loading } from "../../../../utils/ui/loading";
import { View } from "../../../view/view";
import { EDGlobal, active } from "../../logic/ed-global";
import { EDGlobal, EdMeta, active } from "../../logic/ed-global";
import { getMetaById } from "../../logic/tree/build";
import { loadComponent } from "../../logic/tree/sync-walk";
import { code } from "../popup/code/code";
import { useEffect } from "react";
export const EdMain = () => {
const p = useGlobal(EDGlobal, "EDITOR");
@ -49,60 +49,12 @@ export const EdMain = () => {
}}
hover={{
get(meta) {
const item = meta.item;
if (active.comp_id) {
const p = meta.parent_mcomp;
if (p) {
if (
p.mitem.get("id") !== active.instance.item_id ||
p.mcomp.get("component")?.get("id") !== active.comp_id
)
return false;
}
}
if (
item.originalId === active.hover_id ||
item.id === active.hover_id
)
return true;
return false;
return active.hover_id === meta.item.id;
},
set(meta) {
if (meta.parent_mcomp) {
const id = meta.parent_mcomp.mitem.get("id");
if (active.instance.item_id !== id) {
const original_id =
meta.parent_mcomp.mitem.get("originalId");
if (active.comp_id && original_id) {
active.hover_id = original_id;
} else if (id) {
active.hover_id = id;
}
p.render();
p.page.render();
focus();
return;
}
}
if (active.comp_id) {
const parent = meta.parent_mcomp;
if (parent) {
const mcomp = parent.mcomp;
if (mcomp.get("component")?.get("id") === active.comp_id) {
active.hover_id = meta.item.originalId || meta.item.id;
}
} else {
active.hover_id = meta.item.id;
}
} else {
active.hover_id = meta.item.id;
const outer = getOuterItem(meta);
if (outer) {
active.hover_id = outer.id;
}
p.render();
@ -111,86 +63,12 @@ export const EdMain = () => {
}}
active={{
get(meta) {
const item = meta.item;
if (active.comp_id) {
const p = meta.parent_mcomp;
if (p) {
if (
p.mitem.get("id") !== active.instance.item_id ||
p.mcomp.get("component")?.get("id") !== active.comp_id
)
return false;
}
}
if (
item.originalId === active.item_id ||
item.id === active.item_id
)
return true;
return false;
return active.item_id === meta.item.id;
},
set(meta) {
if (meta.parent_mcomp) {
const id = meta.parent_mcomp.mitem.get("id");
if (active.instance.item_id !== id) {
const original_id =
meta.parent_mcomp.mitem.get("originalId");
let active_id = "";
if (active.comp_id && original_id) {
active_id = original_id;
} else if (id) {
active_id = id;
}
if (active_id) {
if (active.item_id !== active_id) {
active.item_id = active_id;
} else {
const comp_id = meta.parent_mcomp.mcomp
.get("component")
?.get("id");
if (comp_id) {
active.instance.item_id = active_id;
active.instance.comp_id = active.comp_id;
active.comp_id = comp_id || "";
const root = p.comp.list[comp_id].tree.find(
(e) => e.parent === "root"
);
if (root && typeof root.id === "string") {
active.item_id = root.id || "";
}
}
}
}
p.render();
p.page.render();
focus();
return;
}
}
if (active.comp_id) {
const parent = meta.parent_mcomp;
if (parent) {
const mcomp = parent.mcomp;
if (mcomp.get("component")?.get("id") === active.comp_id) {
active.item_id = meta.item.originalId || meta.item.id;
}
} else {
active.comp_id = "";
active.item_id = meta.item.id;
active.instance.item_id = "";
active.instance.comp_id = "";
}
} else {
active.item_id = meta.item.id;
const outer = getOuterItem(meta);
if (outer) {
active.item_id = outer.id;
}
p.render();
@ -274,6 +152,15 @@ export const EdMain = () => {
);
};
const getOuterItem = (meta: EdMeta) => {
let cur: undefined | EdMeta = meta;
while (cur.parent_mcomp) {
cur = cur.parent_mcomp.meta;
}
return cur.item;
};
function setEndOfContenteditable(div: any) {
let range: any, sel: any;
if (document.createRange) {

View File

@ -23,6 +23,8 @@ export const ScriptMonaco = () => {
editor: null as null | MonacoEditor,
monaco: null as null | Monaco,
changeTimeout: 0 as any,
init: false,
value: "",
historyOpen: false,
idbstore: createStore(`prasi-page-${p.page.cur.id}`, "script-history"),
});
@ -45,33 +47,57 @@ export const ScriptMonaco = () => {
}, []);
useEffect(() => {
if (local.monaco && local.editor) {
local.monaco.editor.getModels().forEach((model) => {
const uri = model.uri.toString();
if (
uri.startsWith("inmemory://model") ||
uri.startsWith("ts:comp-") ||
uri.startsWith("ts:page-")
) {
model.dispose();
}
});
(async () => {
const editor = local.editor;
const monaco = local.monaco;
if (monaco && editor) {
if (!local.init) {
if (p.ui.popup.script.mode === "js") {
monaco.editor.getModels().forEach((model) => {
model.dispose();
});
monaco.editor.getModels().forEach((model) => {
if (model.uri.toString().startsWith("inmemory://model")) {
model.dispose();
}
});
let model = local.monaco.editor.createModel(
val,
"typescript",
local.monaco.Uri.parse(
`ts:${
active.comp_id ? `comp-${active.comp_id}` : `page-${p.page.cur.id}`
}-${active.item_id}.tsx`
)
);
local.editor.setModel(model);
declareScope(p, local.editor, local.monaco).then(() => {
local.render();
});
}
}, [active.item_id, val]);
let model = monaco.editor.createModel(
val,
"typescript",
monaco.Uri.parse(
`ts:${
active.comp_id
? `comp-${active.comp_id}`
: `page-${p.page.cur.id}`
}-${active.item_id}.tsx`
)
);
editor.setModel(model);
await jsMount(editor, monaco, p);
await monacoTypings(
{
site_dts: p.site_dts,
script: {
siteTypes: {},
},
site: p.site.config,
},
monaco,
{ types: {}, values: {} }
);
declareScope(p, editor, monaco).then(() => {
local.render();
});
}
local.init = true;
local.value = val;
local.render();
}
}
})();
}, [active.item_id, local.monaco, local.editor]);
if (!meta) return null;
@ -121,9 +147,9 @@ export const ScriptMonaco = () => {
} else if (
item.type === "item" &&
item.component?.id &&
meta.parent_mcomp?.mitem
meta.parent_mcomp?.meta.mitem
) {
mitem = meta.parent_mcomp?.mitem;
mitem = meta.parent_mcomp?.meta.mitem;
if (!mitem) {
active.item_id = "";
@ -170,11 +196,8 @@ async () => {
}
}
if (!meta) return null;
return (
<Editor
value={val}
options={{
minimap: { enabled: false },
wordWrap: "wordWrapColumn",
@ -188,7 +211,10 @@ async () => {
language={
{ css: "scss", js: "typescript", html: "html" }[p.ui.popup.script.mode]
}
value={local.value}
onChange={(val) => {
local.value = val || "";
local.render();
clearTimeout(scriptEdit.timeout);
scriptEdit.timeout = setTimeout(() => {
const meta = getMetaById(p, active.item_id);
@ -222,46 +248,13 @@ async () => {
}, 1000);
}}
onMount={async (editor, monaco) => {
local.monaco = monaco;
local.editor = editor;
local.render();
editor.focus();
setTimeout(() => {
editor.focus();
}, 300);
const value = editor.getValue();
if (p.ui.popup.script.mode === "js") {
monaco.editor.getModels().forEach((model) => {
if (model.uri.toString().startsWith("inmemory://model")) {
model.dispose();
}
});
let model = monaco.editor.createModel(
value,
"typescript",
monaco.Uri.parse(
`ts:${
active.comp_id
? `comp-${active.comp_id}`
: `page-${p.page.cur.id}`
}-${active.item_id}.tsx`
)
);
editor.setModel(model);
await jsMount(editor, monaco, p);
await monacoTypings(
{
site_dts: p.site_dts,
script: {
siteTypes: {},
},
site: p.site.config,
},
monaco,
{ types: {}, values: {} }
);
await declareScope(p, editor, monaco);
}
}}
/>
);

View File

@ -20,11 +20,6 @@ export const declareScope = async (
if (!s) return;
s.p.push(active_id);
monaco.editor.getModels().forEach((model) => {
if (model.uri.toString().startsWith("ts:scope~")) {
model.dispose();
}
});
const existing: Record<string, IEachArgScope> = {};
@ -143,7 +138,8 @@ const spreadScope = (
if (!item) {
if (meta) {
if (meta.parent_mcomp) {
comp_id = meta.parent_mcomp.mitem.get("component")?.get("id") || "";
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];

View File

@ -95,7 +95,7 @@ export const EdSidePropInstance: FC<{ meta: EdMeta }> = ({ meta }) => {
</div>
</div>
<div className="flex flex-1 relative overflow-auto">
<div className="flex flex-1 relative overflow-y-auto overflow-x-hidden">
<div className={cx("absolute inset-0")}>
{local.rightClickEvent && (
<Menu

View File

@ -17,25 +17,11 @@ export const EdPropInstanceText: FC<{
const p = useGlobal(EDGlobal, "EDITOR");
const local = useLocal({
value: "",
value: mprop.get("value"),
codeEditing: false,
timeout: null as any,
});
const val = mprop.get("value");
const valBuilt = mprop.get("valueBuilt");
useEffect(() => {
if (val) {
try {
eval(`local.value = ${valBuilt}`);
} catch (e) {}
} else {
local.value = "";
}
local.render();
}, [val, valBuilt]);
return (
<div className="flex items-center min-h-[28px]">
<EdPropLabel name={name} />

View File

@ -92,7 +92,7 @@ export const EdSidePropComp: FC<{ meta: EdMeta }> = ({ meta }) => {
Back to Instance
</div>
</div>
<div className="flex flex-1 relative overflow-auto">
<div className="flex flex-1 relative overflow-y-auto overflow-x-hidden">
<div
className={cx("absolute inset-0")}
ref={(ref) => (propRef.el = ref)}

View File

@ -33,11 +33,11 @@ export const nodeRender: NodeRender<EdMeta> = (node, prm) => {
const meta = getMetaById(p, node.data?.parent_item.id);
if (meta) {
if (meta.propvis) {
jsxPropVisCache[node.data.item.id] = meta.propvis;
jsxPropVisCache[meta.item.id] = meta.propvis;
if (meta.propvis[node.data.jsx_prop_name] === false) return <></>;
} else {
if (jsxPropVisCache[node.data.item.id]) {
meta.propvis = jsxPropVisCache[node.data.item.id];
if (jsxPropVisCache[meta.item.id]) {
meta.propvis = jsxPropVisCache[meta.item.id];
if (meta.propvis) {
if (meta.propvis[node.data.jsx_prop_name] === false) return <></>;
}

View File

@ -1,6 +1,6 @@
import importModule from "../../../render/editor/tools/dynamic-import";
import { devLoader } from "../../../render/live/dev-loader";
import { createAPI, createDB } from "../../../utils/script/init-api";
import { createAPI, createDB, initApi } from "../../../utils/script/init-api";
import { VG } from "./global";
export const oldLoadCode = async (v: VG) => {
@ -21,11 +21,12 @@ export const oldLoadCode = async (v: VG) => {
}
}
await initApi(site.config);
await importModule(loader.npm(p, "site", site.id));
if (site.js_compiled) {
const config = site.config as any;
const exec = (fn: string, scopes: any) => {
if (config.api_url) {
if (config.api_url && !scopes["api"]) {
scopes["api"] = createAPI(config.api_url);
scopes["db"] = createDB(config.api_url);
}

View File

@ -39,6 +39,7 @@ export const jsMount = async (editor: MonacoEditor, monaco: Monaco, p?: PG) => {
if (p) {
p.ui.popup.script.mode === "js";
const cpath = r.path.substring(`scope~`.length).split("__");
const [comp_id, prev_comp_id, prev_item_id] = cpath[0].split("~");
if (cpath[1]) {
const path = cpath[1].split("~");