wip fix tree-rebuild

This commit is contained in:
Rizky 2023-12-15 03:41:29 +07:00
parent 8188589065
commit 3c25a62192
16 changed files with 388 additions and 226 deletions

View File

@ -12,7 +12,6 @@ export const comp_load: SAction["comp"]["load"] = async function (
) {
const result: Record<string, IScopeComp> = {};
for (const id of ids) {
const root = await loadComponent(id, this);
}
return result;
};

View File

@ -6,7 +6,7 @@ import { GenMetaP } from "../../../../web/src/nova/vi/utils/types";
import { IItem } from "../../../../web/src/utils/types/item";
import { DPage } from "../../../../web/src/utils/types/root";
import { SAction } from "../actions";
import { loadComponent } from "../editor/load-component";
import { loadComponent, userSyncComponent } from "../editor/load-component";
import { parseJs } from "../editor/parser/parse-js";
import { activity } from "../entity/activity";
import { conns } from "../entity/conn";
@ -201,6 +201,8 @@ const scanMeta = async (doc: DPage, sync: SyncConnection) => {
});
}
await loading[id];
} else {
userSyncComponent(sync, id);
}
if (docs.comp[id]) {
@ -239,6 +241,6 @@ const scanMeta = async (doc: DPage, sync: SyncConnection) => {
comps[id] = { id, snapshot: await gzipAsync(snap.bin) };
}
}
return { meta: simplifyMeta(meta), comps, entry };
};

View File

@ -6,10 +6,11 @@ import { gzipAsync } from "../entity/zlib";
import { sendWS } from "../sync-handler";
import { SyncConnection, SyncType } from "../type";
export const loadComponent = async (id: string, sync: SyncConnection) => {
let snap = snapshot.get("comp", id);
let ydoc = docs.comp[id];
export const loadComponent = async (comp_id: string, sync: SyncConnection) => {
let snap = snapshot.get("comp", comp_id);
let ydoc = docs.comp[comp_id];
const conf = sync.conf;
if (!conf) return undefined;
const createUndoManager = async (root: Y.Map<any>) => {
@ -21,25 +22,28 @@ export const loadComponent = async (id: string, sync: SyncConnection) => {
};
const attachOnUpdate = async (doc: Y.Doc, um: Y.UndoManager) => {
snapshot.set("comp", id, "id_doc", um.doc.clientID);
snapshot.set("comp", comp_id, "id_doc", um.doc.clientID);
doc.on("update", async (update: Uint8Array, origin: any) => {
const bin = Y.encodeStateAsUpdate(doc);
snapshot.set("comp", id, "bin", bin);
snapshot.set("comp", comp_id, "bin", bin);
const sv_local = await gzipAsync(update);
const all = user.active.findAll({ comp_id: id });
const all = user.active.findAll({ comp_id: comp_id });
all.map((e) => {
if (origin !== um) {
if (e.client_id === origin) return;
}
const ws = conns.get(e.client_id)?.ws;
if (ws) {
sendWS(ws, {
type: SyncType.Event,
event: "remote_svlocal",
data: { type: "comp", sv_local, id },
data: { type: "comp", sv_local, id: comp_id },
});
}
});
@ -51,16 +55,16 @@ export const loadComponent = async (id: string, sync: SyncConnection) => {
};
if (!snap && !ydoc) {
const comp = await db.component.findFirst({ where: { id } });
const comp = await db.component.findFirst({ where: { id: comp_id } });
if (comp) {
const doc = new Y.Doc();
let root = doc.getMap("map");
syncronize(root, { id, root: comp.content_tree });
syncronize(root, { id: comp_id, root: comp.content_tree });
const um = await createUndoManager(root);
docs.comp[id] = {
docs.comp[comp_id] = {
doc: doc as any,
id,
id: comp_id,
um,
};
@ -69,7 +73,7 @@ export const loadComponent = async (id: string, sync: SyncConnection) => {
snapshot.update({
bin,
id,
id: comp_id,
type: "comp",
name: comp.name,
ts: Date.now(),
@ -86,23 +90,23 @@ export const loadComponent = async (id: string, sync: SyncConnection) => {
});
return {
id: id,
id: comp_id,
name: comp.name,
snapshot: await gzipAsync(bin),
};
}
} else if (snap && !ydoc) {
const doc = new Y.Doc();
snapshot.set("comp", id, "id_doc", doc.clientID);
snapshot.set("comp", comp_id, "id_doc", doc.clientID);
Y.applyUpdate(doc, snap.bin);
let root = doc.getMap("map");
const um = await createUndoManager(root);
await attachOnUpdate(doc, um);
docs.comp[id] = {
docs.comp[comp_id] = {
doc: doc as any,
id,
id: comp_id,
um,
};
@ -112,11 +116,11 @@ export const loadComponent = async (id: string, sync: SyncConnection) => {
user_id: sync.user_id,
site_id: conf.site_id,
page_id: conf.page_id,
comp_id: id,
comp_id: comp_id,
});
return {
id: id,
id: comp_id,
name: snap.name,
snapshot: await gzipAsync(snap.bin),
};
@ -127,7 +131,7 @@ export const loadComponent = async (id: string, sync: SyncConnection) => {
user_id: sync.user_id,
site_id: conf.site_id,
page_id: conf.page_id,
comp_id: id,
comp_id: comp_id,
});
return {
@ -137,3 +141,15 @@ export const loadComponent = async (id: string, sync: SyncConnection) => {
};
}
};
export const userSyncComponent = (sync: SyncConnection, comp_id: string) => {
const conf = sync.conf;
user.active.add({
client_id: sync.client_id,
user_id: sync.user_id,
site_id: conf?.site_id || "",
page_id: conf?.page_id || "",
comp_id: comp_id,
});
};

View File

@ -17,7 +17,6 @@ export const user = {
page_id: string;
comp_id?: string;
client_id: string;
select: "" | "comp" | "item" | "section" | "text";
},
"client_id"
>("client_id"),

View File

@ -33,6 +33,7 @@ export const syncHandler: WebSocketHandler<WSData> = {
close(ws) {
const client_id = wconns.get(ws);
if (client_id) {
user.active.delAll({ client_id });
activity.site.disconnect(ws);
conns.delete(client_id);
wconns.delete(ws);

View File

@ -1,9 +1,9 @@
import { NodeModel } from "@minoru/react-dnd-treeview";
import { compress, decompress } from "wasm-gzip";
import { IItem } from "../../../../utils/types/item";
import { DComp } from "../../../../utils/types/root";
import { genMeta } from "../../../vi/meta/meta";
import { IMeta, PG } from "../ed-global";
import { NodeModel } from "@minoru/react-dnd-treeview";
import { pushTreeNode } from "../tree/build/push-tree";
export const loadcomp = {
@ -39,87 +39,108 @@ export const loadComponent = async (p: PG, id_comp: string) => {
export const loadCompSnapshot = async (
p: PG,
id_comp: string,
comp_id: string,
snapshot: Uint8Array
) => {
const doc = new Y.Doc() as DComp;
Y.applyUpdate(doc as any, decompress(snapshot));
const mitem = doc.getMap("map").get("root");
if (mitem) {
if (typeof p.comp.list[id_comp]?.on_update === "function") {
doc.off("update", p.comp.list[id_comp].on_update);
if (typeof p.comp.list[comp_id]?.on_update === "function") {
doc.off("update", p.comp.list[comp_id].on_update);
}
const meta: Record<string, IMeta> = {};
const tree: NodeModel<IMeta>[] = [];
const item = mitem.toJSON() as IItem;
p.comp.loaded[id_comp] = {
comp: item,
};
genMeta(
{
comps: p.comp.loaded,
meta,
on: {
visit(m) {
pushTreeNode(p, m, meta, tree);
const updated = updateComponentMeta(p, doc, comp_id);
if (updated) {
const { meta, tree } = updated;
if (p.comp.list[comp_id]) {
p.comp.list[comp_id].meta = meta;
p.comp.list[comp_id].tree = tree;
} else {
p.comp.list[comp_id] = {
comp: { id: comp_id, snapshot },
doc,
meta,
tree,
async on_update(bin, origin) {
if (origin === "sv_remote" || origin === "local") {
return;
}
if (m.parent) {
if (m.parent.id === "root") {
if (m.item.id === item.id) {
m.mitem = mitem;
}
} else {
const parent = meta[m.parent.id];
const res = await p.sync.yjs.sv_local(
"comp",
comp_id,
Buffer.from(compress(bin))
);
if (parent.mitem) {
parent.mitem.get("childs")?.forEach((child) => {
if (child.get("id") === m.item.id) {
m.mitem = child;
}
});
}
if (res) {
const diff_local = Y.encodeStateAsUpdate(
doc as any,
decompress(res.sv)
);
Y.applyUpdate(doc as any, decompress(res.diff), "local");
await p.sync.yjs.diff_local(
"comp",
comp_id,
Buffer.from(compress(diff_local))
);
const updated = updateComponentMeta(p, doc, comp_id);
if (updated) {
p.comp.list[comp_id].meta = updated.meta;
p.comp.list[comp_id].tree = updated.tree;
}
p.render();
}
},
},
note: "load-comp",
},
{ item, ignore_first_component: true }
);
};
p.comp.list[id_comp] = {
comp: { id: id_comp, snapshot },
doc,
meta,
tree,
async on_update(bin, origin) {
if (origin === "sv_remote" || origin === "local") {
return;
}
const res = await p.sync.yjs.sv_local(
"comp",
id_comp,
Buffer.from(compress(bin))
);
if (res) {
const diff_local = Y.encodeStateAsUpdate(
doc as any,
decompress(res.sv)
);
Y.applyUpdate(doc as any, decompress(res.diff), "local");
await p.sync.yjs.diff_local(
"comp",
id_comp,
Buffer.from(compress(diff_local))
);
p.render();
}
},
};
doc.on("update", p.comp.list[id_comp].on_update);
doc.on("update", p.comp.list[comp_id].on_update);
}
}
}
};
export const updateComponentMeta = (p: PG, doc: DComp, comp_id: string) => {
const mitem = doc.getMap("map").get("root");
if (!mitem) return;
const meta: Record<string, IMeta> = {};
const tree: NodeModel<IMeta>[] = [];
const item = mitem.toJSON() as IItem;
p.comp.loaded[comp_id] = {
comp: item,
};
genMeta(
{
comps: p.comp.loaded,
meta,
on: {
visit(m) {
pushTreeNode(p, m, meta, tree);
if (m.parent) {
if (m.parent.id === "root") {
if (m.item.id === item.id) {
m.mitem = mitem;
}
} else {
const parent = meta[m.parent.id];
if (parent.mitem) {
parent.mitem.get("childs")?.forEach((child) => {
if (child.get("id") === m.item.id) {
m.mitem = child;
}
});
}
}
}
},
},
note: "load-comp",
},
{ item, ignore_first_component: true }
);
return { meta, tree };
};

View File

@ -8,6 +8,7 @@ import { EmptySite, PG } from "./ed-global";
import { treeRebuild } from "./tree/build";
import { reloadPage } from "./ed-route";
import { loadSite } from "./ed-site";
import { updateComponentMeta } from "./comp/load";
const decoder = new TextDecoder();
@ -172,9 +173,20 @@ export const edInitSync = (p: PG) => {
sv,
diff
);
if (res) {
Y.applyUpdate(doc, decompress(res.diff), "sv_remote");
await treeRebuild(p, { note: "sv_remote" });
if (data.type === "page") {
await treeRebuild(p, { note: "sv_remote" });
} else {
const updated = updateComponentMeta(p, doc, data.id);
if (updated) {
p.comp.list[data.id].meta = updated.meta;
p.comp.list[data.id].tree = updated.tree;
}
await treeRebuild(p, { note: "sv_remote" });
}
p.render();
}
}
},

View File

@ -0,0 +1,66 @@
import { MItem } from "../../../../../utils/types/item";
import { FNAdv } from "../../../../../utils/types/meta-fn";
import { PG } from "../../../logic/ed-global";
export const edMonacoDefaultVal = (p: PG, adv: FNAdv, mitem: MItem) => {
let val = "";
if (p.ui.popup.script.type === "item") {
const mode = p.ui.popup.script.mode;
val = (typeof adv[mode] === "string" ? adv[mode] : "") as any;
if (val === "") {
if (mode === "js") {
val = `<div {...props}>{children}</div>`;
} else if (mode === "css") {
val = `\
& {
display: flex;
// &.mobile {}
// &.desktop {}
// &:hover {}
}`;
}
}
} else if (
p.ui.popup.script.type === "prop-master" ||
p.ui.popup.script.type === "prop-instance"
) {
const mprops = mitem?.get("component")?.get("props");
if (mprops) {
const mprop = mprops.get(p.ui.popup.script.prop_name);
if (mprop) {
const kind = p.ui.popup.script.prop_kind;
if (kind === "value") {
val = mprop.get("value");
} else if (kind === "gen") {
val =
mprop.get("gen") ||
`\
async () => {
return \`""\`;
}`;
} else if (kind === "visible") {
val = mprop.get("visible") || "true";
} else if (kind === "option") {
val =
mprop.get("meta")?.get("options") ||
`\
[
{
label: "yes",
value: "y"
},
{
label: "no",
value: "n"
},
]`;
}
}
}
}
return val;
};

View File

@ -1,7 +1,7 @@
import type { Monaco, OnMount } from "@monaco-editor/react";
import { createStore } from "idb-keyval";
import trim from "lodash.trim";
import { useEffect } from "react";
import { FC, useEffect } from "react";
import { compress } from "wasm-gzip";
import { useGlobal, useLocal } from "web-utils";
import { jscript } from "../../../../../utils/script/jscript";
@ -10,6 +10,7 @@ import { monacoTypings } from "../../../../../utils/script/typings";
import { EDGlobal, IMeta, active } from "../../../logic/ed-global";
import { getMetaById } from "../../../logic/tree/build";
import { declareScope } from "./scope";
import { edMonacoDefaultVal } from "./default-val";
const scriptEdit = {
timeout: null as any,
@ -17,7 +18,7 @@ const scriptEdit = {
const encode = new TextEncoder();
export type MonacoEditor = Parameters<OnMount>[0];
export const ScriptMonaco = () => {
export const EdScriptMonaco: FC<{}> = () => {
const p = useGlobal(EDGlobal, "EDITOR");
const local = useLocal({
editor: null as null | MonacoEditor,
@ -26,6 +27,7 @@ export const ScriptMonaco = () => {
init: false,
value: "",
historyOpen: false,
mode: "",
idbstore: createStore(`prasi-page-${p.page.cur.id}`, "script-history"),
});
@ -53,6 +55,11 @@ export const ScriptMonaco = () => {
const monaco = local.monaco;
if (monaco && editor) {
if (local.mode !== p.ui.popup.script.mode) {
local.init = false;
local.mode = p.ui.popup.script.mode;
}
if (!local.init) {
if (p.ui.popup.script.mode === "js") {
monaco.editor.getModels().forEach((model) => {
@ -101,7 +108,7 @@ export const ScriptMonaco = () => {
}
}
})();
}, [active.item_id, local.monaco, local.editor]);
}, [active.item_id, local.monaco, local.editor, p.ui.popup.script.mode]);
if (!meta) return null;
@ -110,41 +117,45 @@ export const ScriptMonaco = () => {
item.adv = adv;
const doEdit = async (newval: string, all?: boolean) => {
if (local.editor && jscript.prettier.standalone) {
const text = trim(
await jscript.prettier.standalone.format(
all
? newval
: local.editor?.getValue().replace(/\{\s*children\s*\}/gi, newval)
),
"; \n"
);
if (local.editor) {
const prettier = jscript.prettier.standalone;
const prettier_ts = jscript.prettier.ts;
const prettier_estree = jscript.prettier.estree;
local.editor.executeEdits(null, [
{
range: {
startLineNumber: 0,
startColumn: 0,
endColumn: Number.MAX_SAFE_INTEGER,
endLineNumber: Number.MAX_SAFE_INTEGER,
if (prettier && prettier_estree && prettier_ts) {
const text = trim(
await prettier.format(
all
? newval
: local.editor
?.getValue()
.replace(/\{\s*children\s*\}/gi, newval),
{
parser: "typescript",
plugins: [prettier_ts, prettier_estree],
}
),
"; \n"
);
local.editor.executeEdits(null, [
{
range: {
startLineNumber: 0,
startColumn: 0,
endColumn: Number.MAX_SAFE_INTEGER,
endLineNumber: Number.MAX_SAFE_INTEGER,
},
text,
},
text,
},
]);
]);
}
}
};
p.script.do_edit = doEdit;
let mitem = meta.mitem;
if (p.ui.popup.script.type === "item") {
val = (
typeof adv[p.ui.popup.script.mode] === "string"
? adv[p.ui.popup.script.mode]
: ""
) as any;
}
if (!mitem) {
active.item_id = "";
return <div>no mitem</div>;
@ -155,44 +166,7 @@ export const ScriptMonaco = () => {
}
}
if (
p.ui.popup.script.type === "prop-master" ||
p.ui.popup.script.type === "prop-instance"
) {
const mprops = mitem?.get("component")?.get("props");
if (mprops) {
const mprop = mprops.get(p.ui.popup.script.prop_name);
if (mprop) {
const kind = p.ui.popup.script.prop_kind;
if (kind === "value") {
val = mprop.get("value");
} else if (kind === "gen") {
val =
mprop.get("gen") ||
`\
async () => {
return \`""\`;
}`;
} else if (kind === "visible") {
val = mprop.get("visible") || "true";
} else if (kind === "option") {
val =
mprop.get("meta")?.get("options") ||
`\
[
{
label: "yes",
value: "y"
},
{
label: "no",
value: "n"
},
]`;
}
}
}
}
val = edMonacoDefaultVal(p, adv, mitem);
return (
<Editor

View File

@ -4,7 +4,7 @@ import { Loading } from "../../../../../utils/ui/loading";
import { Modal } from "../../../../../utils/ui/modal";
import { EDGlobal } from "../../../logic/ed-global";
import { propPopover } from "../../side/prop-master/prop-form";
import { ScriptWorkbench } from "./workbench";
import { EdScriptWorkbench } from "./workbench";
export const EdPopScript = () => {
const p = useGlobal(EDGlobal, "EDITOR");
@ -80,7 +80,7 @@ export const EdPopScript = () => {
)}
>
{!jscript.editor && <Loading note={"js-editor"} backdrop={false} />}
{jscript.editor && <ScriptWorkbench />}
{jscript.editor && <EdScriptWorkbench />}
</div>
</div>
</Modal>

View File

@ -0,0 +1,46 @@
import { FC } from "react";
import { Button } from "../../../../../utils/ui/form/Button";
import { useGlobal } from "web-utils";
import { EDGlobal } from "../../../logic/ed-global";
export const EdScriptSnippet: FC<{}> = ({}) => {
const p = useGlobal(EDGlobal, "EDITOR");
return (
<div className="flex items-center space-x-1 pl-2 border-l">
<Button
className={cx(css`
width: auto !important;
padding-left: 5px;
padding-right: 5px;
font-size: 12px;
`)}
onClick={() => {
console.log(p.script.do_edit);
p.script.do_edit(
`\
<div {...props}>
<Local
name="local"
value={
{
//local object
}
}
effect={async (local) => {
//local effect
}}
>
{children}
</Local>
</div>
`,
true
);
}}
>
&lt;Local/&gt;
</Button>
</div>
);
};

View File

@ -1,53 +1,57 @@
import { useGlobal } from "web-utils";
import { ScriptMonaco } from "./monaco";
import { EdScriptMonaco } from "./monaco";
import { EDGlobal, active } from "../../../logic/ed-global";
import { IItem } from "../../../../../utils/types/item";
import { EdScriptSnippet } from "./snippet";
export const ScriptWorkbench = () => {
export const EdScriptWorkbench = () => {
const p = useGlobal(EDGlobal, "EDITOR");
return (
<div className="flex flex-1 items-stretch">
<div className="flex flex-1 flex-col ">
<div className="flex p-2 border-b space-x-2">
<div className="flex border-b">
{p.ui.popup.script.type === "prop-master" ? (
<CompTitle />
) : (
<>
{[
{ type: "js", color: "#e9522c" },
{ type: "css", color: "#188228" },
{ type: "html", color: "#2c3e83" },
].map((e) => {
return (
<div
key={e.type}
className={cx(
css`
color: ${e.color};
border: 1px solid ${e.color};
`,
"uppercase text-white text-[12px] cursor-pointer transition-all hover:opacity-100 w-[40px] text-center",
p.ui.popup.script.mode === e.type
? css`
background: ${e.color};
color: white;
`
: "opacity-30"
)}
onClick={() => {
p.ui.popup.script.mode = e.type as any;
p.render();
}}
>
{e.type}
</div>
);
})}
<div className="flex p-2 space-x-1">
{[
{ type: "js", color: "#e9522c" },
{ type: "css", color: "#188228" },
{ type: "html", color: "#2c3e83" },
].map((e) => {
return (
<div
key={e.type}
className={cx(
css`
color: ${e.color};
border: 1px solid ${e.color};
`,
"uppercase text-white text-[12px] cursor-pointer flex items-center justify-center transition-all hover:opacity-100 w-[40px] text-center",
p.ui.popup.script.mode === e.type
? css`
background: ${e.color};
color: white;
`
: "opacity-30"
)}
onClick={() => {
p.ui.popup.script.mode = e.type as any;
p.render();
}}
>
{e.type}
</div>
);
})}
</div>
{p.ui.popup.script.mode === "js" && <EdScriptSnippet />}
</>
)}
</div>
<div className="relative flex flex-1">
<ScriptMonaco />
<EdScriptMonaco />
</div>
</div>
</div>

View File

@ -26,7 +26,15 @@ export const EdSidePropComp: FC<{ meta: IMeta }> = ({ meta }) => {
const TypedTree = DNDTree<PropItem>;
let filtered = [] as NodeModel<PropItem>[];
const mprops = meta.mitem?.get("component")?.get("props");
let mprops = meta.mitem?.get("component")?.get("props");
if (!mprops) {
const mcomp = meta.mitem?.get("component");
if (mcomp) {
mcomp.set("props", new Y.Map() as any);
mprops = mcomp.get("props");
}
}
if (mprops && meta.mitem) {
mprops.forEach((m, key) => {
filtered.push({
@ -139,13 +147,13 @@ export const EdSidePropComp: FC<{ meta: IMeta }> = ({ meta }) => {
/>
</DndProvider>
<div
className="m-1 border border-blue-200 px-2 self-start text-[13px] hover:bg-blue-100 cursor-pointer"
className="m-1 border border-blue-200 px-2 self-start text-[13px] hover:bg-blue-100 cursor-pointer select-none"
onClick={() => {
if (mprops) {
const indexes: (number | undefined)[] = [];
mprops.forEach((e) => indexes.push(e.get("idx")));
let idx: any = (indexes.sort().pop() || 0) + 1;
const name = `prop_${idx + 1}`;
const name = `prop_${indexes.length === 0 ? 1 : idx + 1}`;
const map = new Y.Map() as FMCompDef;
syncronize(map, {
idx: idx,

View File

@ -13,10 +13,11 @@ export const propPopover = {
name: "",
};
export const EdPropPopoverForm: FC<{ mprop: FMCompDef; name: string }> = ({
mprop,
name,
}) => {
export const EdPropPopoverForm: FC<{
mprop: FMCompDef;
name: string;
closing: boolean;
}> = ({ mprop, name, closing }) => {
const p = useGlobal(EDGlobal, "EDITOR");
const mmeta = mprop.get("meta");
const local = useLocal({
@ -28,7 +29,8 @@ export const EdPropPopoverForm: FC<{ mprop: FMCompDef; name: string }> = ({
return (
<div
className={cx(
"flex text-sm flex-col items-stretch space-y-1 py-1 w-[300px]"
"flex text-sm flex-col items-stretch space-y-1 py-1 w-[300px]",
closing && "hidden"
)}
>
<div className="px-2 py-1 flex space-x-1">

View File

@ -5,6 +5,7 @@ import { FMCompDef, FNCompDef } from "../../../../../utils/types/meta-fn";
import { Popover } from "../../../../../utils/ui/popover";
import { EdPropPopoverForm, propPopover } from "./prop-form";
import { TypedMap } from "yjs-types";
import { useLocal } from "web-utils";
export type PropItem = {
name: string;
@ -18,6 +19,7 @@ export const EdPropCompTreeItem: FC<{
params: Parameters<NodeRender<PropItem>>[1];
render: () => void;
}> = ({ node, params, render }) => {
const local = useLocal({ closing: false });
if (node.id === "root") {
return <></>;
}
@ -51,14 +53,24 @@ export const EdPropCompTreeItem: FC<{
popoverClassName="bg-white shadow-lg border border-slate-300"
onOpenChange={(open) => {
if (!open) {
propPopover.name = "";
local.closing = true;
local.render();
setTimeout(() => {
propPopover.name = "";
render();
});
} else {
local.closing = false;
propPopover.name = node.text;
render();
}
render();
}}
content={
<EdPropPopoverForm mprop={node.data.mprop} name={node.text} />
<EdPropPopoverForm
closing={local.closing}
mprop={node.data.mprop}
name={node.text}
/>
}
className="flex-1 pl-1 hover:bg-blue-100 cursor-pointer items-center flex"
>

View File

@ -15,6 +15,24 @@ type CompilerOptions = Parameters<
export const jsMount = async (editor: MonacoEditor, monaco: Monaco, p?: PG) => {
const m = monaco as any;
if (editor.getModel()) {
const jsxHgController = new MonacoJsxSyntaxHighlight(getWorker(), monaco);
const { highlighter } = jsxHgController.highlighterBuilder({
editor: editor,
});
if (typeof editor.getModel === "function") {
highlighter();
}
editor.onDidChangeModelContent(() => {
if (typeof editor.getModel === "function") {
try {
highlighter();
} catch (e) {}
}
});
}
if (!m.customJSMounted) {
m.customJSMounted = true;
} else {
@ -267,24 +285,6 @@ export const jsMount = async (editor: MonacoEditor, monaco: Monaco, p?: PG) => {
);
setTimeout(() => {
if (editor.getModel()) {
const jsxHgController = new MonacoJsxSyntaxHighlight(getWorker(), monaco);
const { highlighter } = jsxHgController.highlighterBuilder({
editor: editor,
});
if (typeof editor.getModel === "function") {
highlighter();
}
editor.onDidChangeModelContent(() => {
if (typeof editor.getModel === "function") {
try {
highlighter();
} catch (e) {}
}
});
}
editor.getAction("editor.action.formatDocument")?.run();
}, 100);
};